Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I've found this helpful snippet to make a delete post link on the front-end:

<?php if (current_user_can('edit_post', $post->ID)) 
    echo "<a href='" . wp_nonce_url("/wp-admin/post.php?action=delete&amp;post=$id", 'delete-post_' . $post->ID) . "'>Delete</a>" ?>

What I am wondering if there is a way to modify this code and create a complementary Publish link, which would publish a pending post, from the front end. I've tried the following with no luck...

<?php if (current_user_can('edit_post', $post->ID)) 
    echo "<a href='" . wp_nonce_url("/wp-admin/post.php?action=publish&amp;post=$id", 'publish-post_' . $post->ID) . "'>Publish</a>" ?>

If anyone knows if or how a front-end Publish post link would be possible, and if it could be derived from the delete post link, that would be awesomely helpful.

Thank you!

share|improve this question

1 Answer 1

up vote 3 down vote accepted

There isn't, by default, a 'publish' link because of the way WordPress handles publishing posts. 'publish' is not consider an action in the same way 'delete' is, instead you save the post, with all its data, including its post status.

To get round this you can create your own action handler. In order to avoid potential clashes with WP or other plug-ins, you should probably prefix your custom action, or at the very least your nonce.

The following code should work for this link (note prefixed action and nonce):

$url = add_query_arg(array('action'=>'mypublish', 'post'=>$post->ID),home_url());
echo  "<a href='" . wp_nonce_url($url, 'my-publish-post_' . $post->ID) . "'>Publish</a>"; 

The following function performs some checks, publishes the post and then re-directs you to the published post.

//Run the publish function only if the action variable is correct.
if(isset($_REQUEST['action']) && $_REQUEST['action']=='mypublish')
    add_action('init','my_publish_draft');

    function my_publish_draft(){
         //Get the post's ID.
         $post_id = (isset($_REQUEST['post']) ?  (int) $_REQUEST['post'] : 0);

        //No post? Oh well..
        if(empty($post_id))
            return;

        $nonce = $_REQUEST['_wpnonce'];

        //Check nonce
        if (! wp_verify_nonce($nonce,'my-publish-post_'.$post_id)) 
            wp_die('Are you sure?'); 

        //Check user permissions
        if (!current_user_can('publish_posts'))
            wp_die("You can't do that"); 

        //Any other checks you may wish to perform..

        //Publish post
        wp_publish_post( $post_id );

        //Redirect to published post
        $redirect = get_permalink($post_id);
        wp_redirect($redirect);
        exit;
    }

Edit

As mentioned in the comments, slugs are not set when using this method. WordPress does not automatically give draft posts a slug, but only when you click 'Publish'. The above does not update the slug, just the status. To get round this you can manually set the slug when you create the draft.

Alternatively, you can replace the wp_publish_post call with the following (slightly heavier and a bit uglier) code:

    $post = get_post($post_id,ARRAY_A);
    $post['post_status'] ='publish';
    wp_update_post($post);
share|improve this answer
    
This is really great! Thank you! I have one question, I've noticed that posts I publish with this, their slug is not appearing or being set. Because of this I can't seem to view or link to the posts. If by any chance do you know a way around this problem? –  Bennett Feb 27 '12 at 2:35
    
See, updated answer :D –  Stephen Harris Feb 27 '12 at 12:13

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.