Title: WP-DraftsForFriends
Author: Lester Chan
Published: <strong>Январь 16, 2014-ж.</strong>
Last modified: Август 10, 2026-ж.

---

Плагиндерди издөө

![](https://ps.w.org/wp-draftsforfriends/assets/banner-772x250.png?rev=3639528)

![](https://ps.w.org/wp-draftsforfriends/assets/icon.svg?rev=978048)

# WP-DraftsForFriends

 Автору [Lester Chan](https://profiles.wordpress.org/gamerz/)

[Жүктөө](https://downloads.wordpress.org/plugin/wp-draftsforfriends.2.0.0.zip)

 * [Кенен маалымат](https://ky.wordpress.org/plugins/wp-draftsforfriends/#description)
 * [Сын-пикирлер](https://ky.wordpress.org/plugins/wp-draftsforfriends/#reviews)
 *  [Орнотуу](https://ky.wordpress.org/plugins/wp-draftsforfriends/#installation)
 * [Development](https://ky.wordpress.org/plugins/wp-draftsforfriends/#developers)

 [Колдоо](https://wordpress.org/support/plugin/wp-draftsforfriends/)

## Сүрөттөө

This plugin generates a unique link you can send to a friend so they can read a 
post before you publish it. The link works for someone who is not logged in and 
has no account, it only ever opens the one post it was issued for, and it stops 
working by itself when the time you set runs out.

Everything happens under `Posts -> WP-DraftsForFriends`: pick an unpublished post,
say how long the link should last, and copy the link it gives you. The list below
shows every link you have out, how long each has left, and lets you extend or revoke
them. The settings are the second tab of that same page.

Sharing takes the `publish_posts` capability rather than `manage_options`: a plugin
for sharing your own drafts has no business asking for the capability that lets 
somebody reconfigure the site.

Modified from Drafts for Friends, originally by Neville Longbottom. The plugin icon
is by [Freepik](https://www.freepik.com) from [Flaticon](https://www.flaticon.com).

### Features

 * A unique 32-character link per share, valid only for the post it was issued for
 * An expiry you choose in seconds, minutes, hours or days, with a default you set
   once
 * Works for a logged-out visitor with no account
 * Scheduled and pending posts can be shared as well as drafts
 * A sortable, paginated list of every link you have out, with the time each has
   left
 * Extend or revoke links in bulk
 * Comments are forced closed on a shared draft
 * Moving a post to the trash revokes its links; restoring the post brings them 
   back
 * Multisite-safe, including network activation

### Donations

I spent most of my free time creating, updating, maintaining and supporting these
plugins, if you really love my plugins and could spare me a couple of bucks, I will
really appreciate it. If not feel free to use it without any obligations.

### Usage

Go to `Posts -> WP-DraftsForFriends`. The page has two tabs, **Shared Drafts** and**
Settings**.

Under **Share a Draft**, choose an unpublished post, set how long the link should
last, and press **Share Draft**. The link appears in the list below; press **Copy
link** to put it on your clipboard and send it to whoever needs it.

The list shows every link you have out. **Expires After** counts down and then reads`
Expired`. Twenty rows are shown at a time, every column except the link is sortable,
and _Screen Options_ changes how many rows you see.

To extend links, set **Extend by** to the duration you want to add, tick the rows,
choose **Extend selected** and press **Apply**. To revoke them, tick the rows and
choose **Revoke selected**. Both are bulk actions rather than links on each row,
and deliberately so: a link is a `GET`, and a browser or link checker that quietly
prefetches one would have revoked every share on the page before you knew about 
it.

The **Settings** tab sets the duration a new share starts on. It is only a starting
value — both the share form and **Extend by** can be changed for one share without
changing the setting. That tab takes `manage_options`, so an author sees the Shared
Drafts tab and not the Settings one.

Anyone with the `edit_others_posts` capability — administrators and editors — sees
every shared draft on the site and can share any unpublished post. Authors and contributors
see only their own, and can only share posts they are allowed to edit.

### WP-CLI

    ```
    wp draftsforfriends list --user=admin
    wp draftsforfriends create 42 --user=admin
    wp draftsforfriends create 42 --expires=14 --measure=d --user=admin
    wp draftsforfriends extend 3 4 5 --expires=1 --measure=d --user=admin
    wp draftsforfriends revoke 3 --yes --user=admin
    ```

    ```
    create prints the share link on a line of its own before its success message, and `list` prints one per row. **A share link is the credential** — whoever holds it reads the unpublished post until the link expires, with no account and no login — so treat the output of both as you would the drafts themselves. Shell history, a CI log and a captured `stdout` are all places those links now live.
    ```

**Pass `--user`.** WP-CLI runs as nobody unless told otherwise, and every one of
these is scoped exactly as the screen is: a share belongs to whoever created it,
anyone with `edit_others_posts` sees them all, and creating, extending or revoking
one checks that you may edit the post it points at. Run as nobody, `list` reports
nothing and the rest are refused.

    ```
    --expires and `--measure` default to the duration on the **Settings** tab, the same value the share form and **Extend by** start on. `extend` and `revoke` take as many ids as you like, exactly as the bulk actions do. `revoke` asks before it acts, because the link stops working immediately and cannot be restored; `--yes` answers for a script.
    ```

There is no subcommand for the settings — that is one option row, which `wp option
get wp_draftsforfriends_options` already reads.

### Filters

    ```
    wp_draftsforfriends_capability decides who may reach each tab. The context is `shares` for the Shared Drafts tab or `settings` for the Settings tab:
    ```

    ```
    add_filter( 'wp_draftsforfriends_capability', function ( $capability, $context ) {
        return 'settings' === $context ? 'manage_options' : 'edit_posts';
    }, 10, 2 );
    ```

    ```
    wp_draftsforfriends_share_url filters the link a friend is given, and
    wp_draftsforfriends_requested_hash reads the hash back off the request. **They
    ```

are one contract.** Change the shape of the link without teaching the plugin to

recognise it and every share link 404s, with nothing on the admin screens looking
wrong:

    ```
    add_filter( 'wp_draftsforfriends_share_url', function ( $url, $share ) {
        return home_url( '/secret/' . $share->hash . '/' );
    }, 10, 2 );

    add_filter( 'wp_draftsforfriends_requested_hash', function ( $hash ) {
        if ( '' !== $hash ) {
            return $hash;
        }

        $path = isset( $_SERVER['REQUEST_URI'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';

        return preg_match( '#/secret/([A-Za-z0-9]+)/#', $path, $m ) ? $m[1] : '';
    } );
    ```

The default link is `?p=<id>` rather than the post’s permalink, and that is not

an oversight: the preview works by catching the row WordPress fetches for a bare
post id and puts back before rendering. A permalink looks the post up by slug among
the _public_ statuses, so an unpublished post is never found at all.

### Actions

Three fire as a share moves through its life, each after the write has
 succeeded:

 * `wp_draftsforfriends_share_created` — the stored share, and the post it shares.
 * `wp_draftsforfriends_share_extended` — the share as it now stands, and the
    expiry
   it carried before.
 * `wp_draftsforfriends_share_revoked` — the share as it was; the link has
    already
   stopped working.

    ```
    add_action( 'wp_draftsforfriends_share_created', function ( $share, $post ) {
        error_log( sprintf( 'Shared "%s" until %s', $post->post_title, $share->date_expired ) );
    }, 10, 2 );
    ```

## Скриншоттор

[⌊Posts -> WP-DraftsForFriends: the share form, and every share with its countdown⌉⌊
Posts -> WP-DraftsForFriends: the share form, and every share with its countdown⌉[

Posts -> WP-DraftsForFriends: the share form, and every share with its countdown

[⌊The Settings tab, which sets how long a new share lasts unless you say otherwise⌉⌊
The Settings tab, which sets how long a new share lasts unless you say otherwise⌉[

The Settings tab, which sets how long a new share lasts unless you say otherwise

[⌊What the friend sees: an unpublished post, with no account and no login⌉⌊What 
the friend sees: an unpublished post, with no account and no login⌉[

What the friend sees: an unpublished post, with no account and no login

## Орнотуу

 1. Install and activate the plugin.
 2. Go to `WP-Admin -> Posts -> WP-DraftsForFriends` and share your first draft.

There is nothing to configure before you start. Sharing takes the `publish_posts`
capability rather than `manage_options`, so any author can share their own drafts
without being made an administrator.

## FAQ.KG

### Where did the Drafts for Friends page go?

It is still under _Posts_, and it is now one page with two tabs — **Shared Drafts**
and **Settings** — rather than a screen with no settings of its own.

The address changed, from `edit.php?page=wp-draftsforfriends/wp-draftsforfriends.
php` to `edit.php?page=wp-draftsforfriends`, so an old bookmark needs replacing.
The old address had the plugin’s own folder name in it, which meant the page moved
if you ever renamed the folder.

Links you have already given to friends are unaffected. Those point at the post 
itself and never went through the admin screen.

### Where have Extend and Delete gone from each row?

They are bulk actions now, above and below the list. Tick the rows you want, choose**
Extend selected** or **Revoke selected**, and press **Apply**. Extend uses the **
Extend by** duration next to the dropdown.

A row action is a plain link, and a plain link is one browser prefetch or one link
checker away from being followed without anybody meaning to. Revoking cannot be 
undone, and extending silently prolongs public access to something you have not 
published, so neither should be reachable that way.

### A friend says the link shows “Page not found”

The link has expired, it has been revoked, or the post has been moved to the trash.
Open _Posts -> WP-DraftsForFriends_ and look at the **Expires After** column: an
expired share reads `Expired`. Tick that row, set **Extend by**, and choose **Extend
selected** — the same link starts working again. Restoring the post from the trash
also makes its links work again.

Once the post is published the link stops previewing and simply shows the published
post, which is public by then anyway.

### Who can see which shared drafts?

Anyone with the `edit_others_posts` capability — administrators and editors — sees
every shared draft on the site and can share any unpublished post. Authors and contributors
see only their own, and can only share posts they are allowed to edit.

### Can my friend leave a comment on the draft?

No. Comments are forced closed on a shared draft.

### Does the friend need an account?

No. That is the point of the plugin: the link works for a logged-out visitor, and
only for the post it was issued for, and only until it expires.

### Does the screen need JavaScript?

No. Sharing, extending and revoking are ordinary form submissions handled on the
server, so all three work with JavaScript turned off. The script only adds the **
Copy link** button, a warning before you revoke, and catching a missing draft or
a nonsense duration before the page reloads.

## Сын-пикирлер

![](https://secure.gravatar.com/avatar/40d7759c6d9ffed2e216b052cd3e31097ac4829fddf2049654b0ea0755111c14?
s=60&d=retro&r=g)

### 󠀁[Extremely usefull!](https://wordpress.org/support/topic/extremely-usefull-2/)󠁿

 [Lu Is](https://profiles.wordpress.org/kalimanmx/) Май 3, 2019-ж.

Very easy to use, and gives you the peace of mind of keeping users out of the dashboard

![](https://secure.gravatar.com/avatar/47e9d156ac53e9769862aa031c5d0f85945ac205b25e81d70b5d423b09f4afe5?
s=60&d=retro&r=g)

### 󠀁[Ideal for service providers](https://wordpress.org/support/topic/ideal-for-service-providers/)󠁿

 [deargeek](https://profiles.wordpress.org/deargeek/) Май 9, 2017-ж.

If you offer a publishing service for your clients who don’t want to / need to know
how to write their own posts, this is perfect. Well done!

![](https://secure.gravatar.com/avatar/1fe0862ea4dd920bfa928e8633440e218c4e45fdb8dd75cfcdfeed11c282b3dc?
s=60&d=retro&r=g)

### 󠀁[Love this!](https://wordpress.org/support/topic/love-this-75/)󠁿

 [Anita C](https://profiles.wordpress.org/mymothersdaughter/) Сентябрь 3, 2016-ж.

Great plugin! Love all of Lester’s plugins actually.

![](https://secure.gravatar.com/avatar/b2c20cde0e2520351cd749678c5c197e6c1bb1bf8f983963010ded4fef429f34?
s=60&d=retro&r=g)

### 󠀁[Easy to install, works well](https://wordpress.org/support/topic/easy-to-install-works-well/)󠁿

 [davblayn](https://profiles.wordpress.org/davblayn/) Сентябрь 3, 2016-ж.

The plugin is well made and works as designed. It’s easy to install too.

 [ Read all 7 reviews ](https://wordpress.org/support/plugin/wp-draftsforfriends/reviews/)

## Contributors & Developers

“WP-DraftsForFriends” is open source software. The following people have contributed
to this plugin.

Мүчөлөрү

 *   [ Lester Chan ](https://profiles.wordpress.org/gamerz/)

“WP-DraftsForFriends” has been translated into 3 locales. Thank you to [the translators](https://translate.wordpress.org/projects/wp-plugins/wp-draftsforfriends/contributors)
for their contributions.

[Translate “WP-DraftsForFriends” into your language.](https://translate.wordpress.org/projects/wp-plugins/wp-draftsforfriends)

### Interested in development?

[Browse the code](https://plugins.trac.wordpress.org/browser/wp-draftsforfriends/),
check out the [SVN repository](https://plugins.svn.wordpress.org/wp-draftsforfriends/),
or subscribe to the [development log](https://plugins.trac.wordpress.org/log/wp-draftsforfriends/)
by [RSS](https://plugins.trac.wordpress.org/log/wp-draftsforfriends/?limit=100&mode=stop_on_copy&format=rss).

## Өзгөртүүлөр

### 2.0.0

 * BREAKING: Requires WordPress 6.8 and PHP 8.2, up from 6.0 and 7.4.
 * BREAKING: The screen has moved from `edit.php?page=wp-draftsforfriends/wp-draftsforfriends.
   php` to `edit.php?page=wp-draftsforfriends`, still under `Posts -> WP-DraftsForFriends`,
   and is now one page with two tabs, `Shared Drafts` and `Settings`. Links already
   sent to friends are not affected.
 * BREAKING: Extend and Delete are no longer links on each row. They are bulk actions
   named Extend selected and Revoke selected, applied to the rows you tick. A row
   action is a `GET` and one prefetch away from revoking every share on the page.
 * BREAKING: Removed the `WPDraftsForFriends` class. The plugin is now `WP_DraftsForFriends`
   plus `WP_DraftsForFriends_Admin`, `_Install`, `_List_Table`, `_Options`, `_Preview`,`
   _Settings` and `_Shares` under `includes/`.
 * BREAKING: Removed the `wp_ajax_draftsforfriends_admin` endpoint. Every write 
   is now an ordinary nonced form post to the screen.
 * BREAKING: Dropped the `dff_page`, `dff_sortby` and `dff_sortorder` query arguments
   in favour of core’s `paged`, `orderby` and `order`. A bookmarked sorted URL no
   longer sorts.
 * NEW: Added a `Settings` tab for the default share duration, which was hardcoded
   to two hours.
 * NEW: Settings are stored in a single `wp_draftsforfriends_options` row and the
   upgrade markers in `wp_draftsforfriends_version`. Both are removed on uninstall,
   on a single site and across a network, along with the pre-2.0.0 `draftsforfriends_db_version`
   row.
 * NEW: Added the `wp_draftsforfriends_capability` filter, so either tab can be 
   handed to another capability. It is answered by `option_page_capability_wp_draftsforfriends_options`
   too, so a filtered settings capability governs the save as well as the screen.
 * NEW: Added the `wp_draftsforfriends_share_created`, `wp_draftsforfriends_share_extended`
   and `wp_draftsforfriends_share_revoked` actions, each firing after the write 
   has succeeded.
 * NEW: Added the `wp_draftsforfriends_share_url` filter and its companion `wp_draftsforfriends_requested_hash`.
   The link a friend is given and the check that lets them read it now go through
   one contract, so a site can move share links to a shape of its own. Filtering
   only the first leaves every link 404ing.
 * NEW: Added a Copy link button to each row.
 * NEW: Added a _Shared drafts per page_ screen option.
 * NEW: A `wp draftsforfriends` WP-CLI command — `list`, `create`, `extend` and `
   revoke`, the four things the screen does. It prints share links, which are credentials,
   and needs `--user` because everything it does is scoped to who is asking.
 * NEW: Added a PHPUnit test suite, vitest coverage for the script, and GitHub Actions
   CI.
 * CHANGED: The shared drafts list is a standard WordPress list table, with sortable
   columns, standard pagination at twenty rows and bulk actions, replacing roughly
   250 lines of hand-rolled pagination links and column headers.
 * CHANGED: Messages are core admin notices raised through `add_settings_error()`
   rather than a hand-built banner the script unhid.
 * CHANGED: The plugin now works when installed under a directory name other than`
   wp-draftsforfriends`.
 * CHANGED: Dropped the jQuery dependency; the script is plain JavaScript, and nothing
   on the screen depends on it running.
 * CHANGED: Moving a shared post to the trash now revokes its links instead of leaving
   them working. Restoring the post from the trash makes them work again.
 * CHANGED: Restructured the plugin into `includes/` with one class per file.
 * CHANGED: Removed `img/receipt_share.png`, which was only ever used by the `icon32`
   admin markup WordPress dropped in 3.8.
 * FIXED: Fixed a bug where a shared draft could appear in places it was not shared
   to. Once one valid preview link had been opened, the post was re-used for every
   later query in that same request that returned nothing of its own, including 
   requests carrying a wrong, expired or deleted link.
 * FIXED: Fixed the post title being output unescaped on the admin screen.
 * FIXED: Fixed extending and deleting checking permissions against a post supplied
   with the request rather than the one the shared draft actually points at.
 * FIXED: Fixed activation and uninstall fatally erroring on multisite, which called
   a function removed in WordPress 5.1.
 * FIXED: Fixed multisite activation and uninstall skipping every site past the 
   hundredth.
 * FIXED: Fixed the shared drafts table not being registered with `$wpdb->tables`,
   so its name was wrong inside `switch_to_blog()`.
 * FIXED: Fixed the duration unit dropdowns having no label, which left screen readers
   announcing them as unlabelled combo boxes.
 * FIXED: Fixed the item count above the list counting shares whose post had been
   deleted and which were never listed. Deleting a post permanently now deletes 
   its shared drafts.
 * FIXED: Fixed eleven strings never being translated because of a typo in the text
   domain.
 * FIXED: Fixed several PHP 8 warnings.
 * FIXED: Fixed the _Shared drafts per page_ screen option being thrown away when
   applied, so the list always paged at twenty whatever you set it to.
 * NOTE: Every database query is now a single prepared statement with every value
   bound, including the sort column, which goes through the `%i` identifier placeholder.

## Мета

 *  Нуска **2.0.0**
 *  Акыркы жаңыртуу **2 күн мурун**
 *  Активдүү орнотуулар **1,000+**
 *  WordPress нускасы ** 6.8 же андан жогору **
 *  Tested up to **7.0.3**
 *  PHP нускасы ** 8.2 же андан жогору **
 *  Тилдер
 * [Czech](https://cs.wordpress.org/plugins/wp-draftsforfriends/), [English (US)](https://wordpress.org/plugins/wp-draftsforfriends/),
   [Russian](https://ru.wordpress.org/plugins/wp-draftsforfriends/) жана [Swedish](https://sv.wordpress.org/plugins/wp-draftsforfriends/).
 *  [Translate into your language](https://translate.wordpress.org/projects/wp-plugins/wp-draftsforfriends)
 * Тег:
 * [drafts](https://ky.wordpress.org/plugins/tags/drafts/)[friends](https://ky.wordpress.org/plugins/tags/friends/)
   [preview](https://ky.wordpress.org/plugins/tags/preview/)[send](https://ky.wordpress.org/plugins/tags/send/)
   [share draft](https://ky.wordpress.org/plugins/tags/share-draft/)
 *  [Advanced View](https://ky.wordpress.org/plugins/wp-draftsforfriends/advanced/)

## Рейтинг

 5 out of 5 stars.

 *  [  6 5-star reviews     ](https://wordpress.org/support/plugin/wp-draftsforfriends/reviews/?filter=5)
 *  [  0 4-star reviews     ](https://wordpress.org/support/plugin/wp-draftsforfriends/reviews/?filter=4)
 *  [  0 3-star reviews     ](https://wordpress.org/support/plugin/wp-draftsforfriends/reviews/?filter=3)
 *  [  0 2-star reviews     ](https://wordpress.org/support/plugin/wp-draftsforfriends/reviews/?filter=2)
 *  [  0 1-star reviews     ](https://wordpress.org/support/plugin/wp-draftsforfriends/reviews/?filter=1)

[Your review](https://wordpress.org/support/plugin/wp-draftsforfriends/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/wp-draftsforfriends/reviews/)

## Мүчөлөрү

 *   [ Lester Chan ](https://profiles.wordpress.org/gamerz/)

## Колдоо

Issues resolved in last two months:

     0 out of 2

 [Колдоо форумун көрүү](https://wordpress.org/support/plugin/wp-draftsforfriends/)

## Кайрымдуулук

Would you like to support the advancement of this plugin?

 [ Кайрымдуулук кылуу ](https://lesterchan.net/site/donation/)