How to get the clean permalink in a draft?

When I use the_permalink or get_the_permalink in a draft or scheduled post, the URL provided is not the “final” permalink—it is the unpretty ?p=xxxxx version.

How can I get the final, “clean” permalink to show up in a draft or scheduled post?

Read More

I could do something involving $post->post_name, but I’d need the path as well, and that varies from post type to post type and depends on permalink structure. Is there a “universal” way to do this?

Related posts

Leave a Reply

2 comments

  1. This is a little “hacky”, but when you call get_permalink and you need the permalink for a draft, provide a clone of your post object with the details filled in:

    global $post;
    if ( in_array( $post->post_status, array( 'draft', 'pending', 'auto-draft' ) ) ) {
        $my_post = clone $post;
        $my_post->post_status = 'publish';
        $my_post->post_name = sanitize_title(
            $my_post->post_name ? $my_post->post_name : $my_post->post_title,
            $my_post->ID
        );
        $permalink = get_permalink( $my_post );
    } else {
        $permalink = get_permalink();
    }
    
  2. Since editor displays projected permalink for slug editor, it must have some way to figure it out. From looking at source that is handled by get_sample_permalink_html() and get_sample_permalink().

    Since we only need link without form cruft, we can rework it into something like:

    function get_draft_permalink( $post_id ) {
    
        require_once ABSPATH . '/wp-admin/includes/post.php';
        list( $permalink, $postname ) = get_sample_permalink( $post_id );
    
        return str_replace( '%postname%', $postname, $permalink );
    }
    

    No confidence it is foolproof, but works fine from quick test. 🙂