Support » Developing with WordPress » Custom Post Types – Published Posts – Preview Changes URL’s – Page not Found

  • Since this issue is related only to previewing an edit to a published custom post type, I cannot provide a site URL, but I can note that in testing, reviewing this issue across multiple sites, it is occurring consistently regardless of theme.

    I have:

    -there are no health check items to report
    -deactivated all plugins – same results
    -switched themes – same results
    -reset permalinks
    -clear local browse cache
    -insured no server caching was in use
    -issue is not occurring on standard published posts or published pages, on any drafts or any pending posts/pages – just the Published CPT’s
    -researched this exhaustively
    -issue is new(er) to these sites

    Seems this is an issue with core when I add CPT’s in a child theme. Note, all sites tested that have the issue are running either 2016 or 2017 as the parent theme and use a proper child theme. All works except this issue.

    Each creates the CPT’s based on the following in child theme functions.php:

    function faq_post_type() {
        $labels = array(
            'name'                => _x( 'Faqs', 'Post Type General Name', 'text_domain' ),
            'singular_name'       => _x( 'Faq', 'Post Type Singular Name', 'text_domain' ),
            'menu_name'           => __( 'Faqs', 'text_domain' ),
            'parent_item_colon'   => __( 'Parent Faq:', 'text_domain' ),
            'all_items'           => __( 'All Faqs', 'text_domain' ),
            'view_item'           => __( 'View Faq', 'text_domain' ),
            'add_new_item'        => __( 'Add New Faq', 'text_domain' ),
            'add_new'             => __( 'New Faq', 'text_domain' ),
            'edit_item'           => __( 'Edit Faq', 'text_domain' ),
            'update_item'         => __( 'Update Faq', 'text_domain' ),
            'search_items'        => __( 'Search Faqs', 'text_domain' ),
            'not_found'           => __( 'No Faqs Found', 'text_domain' ),
            'not_found_in_trash'  => __( 'No Faqs Found in Trash', 'text_domain' ),
        );
    
        $args = array(
            'label'               => __( 'Faqs', 'text_domain' ),
            'description'         => __( 'Faqs', 'text_domain' ),
            'labels'              => $labels,
            'hierarchical'        => false,
            'public'              => true,
    		'publicly_queryable'  => true,
            'show_ui'             => true,
            'show_in_menu'        => true,
            'show_in_nav_menus'   => true,
            'show_in_admin_bar'   => true,
    		'supports' => array(
    		'title',
    		'editor',
    		'author',
    		'thumbnail',
    		'excerpt',
    		'trackbacks',
    		'custom-fields',
    		'comments',
    		'revisions',
    		'page-attributes',
    		'post-formats',
    		),
    		'taxonomies' => array('faq_category','post_tag'),
    		'update_count_callback' => '_update_post_term_count',		
            'menu_position'       => 5,
            'menu_icon'           => null,
            'can_export'          => true,
            'has_archive'         => true,
            'exclude_from_search' => false,
            'publicly_queryable'  => true,
            'capability_type'     => 'post',
    		'query_var'          => 'qa_faqs',
            'rewrite'             => array('slug' => 'faqs'),
        );
    
        register_post_type( 'qa_faqs', $args );
    
    // Hook into the 'init' action
    
    }
    add_action( 'init', 'faq_post_type', 0 );
    
    // Register Custom Taxonomy
    function faq_taxonomy()  {
        $labels = array(
            'name'                       => _x( 'Faq Categories', 'Taxonomy General Name', 'text_domain' ),
            'singular_name'              => _x( 'Faq Category', 'Taxonomy Singular Name', 'text_domain' ),
            'menu_name'                  => __( 'Faq Categories', 'text_domain' ),
            'all_items'                  => __( 'All Faq Categories', 'text_domain' ),
            'parent_item'                => __( 'Parent Faq Category', 'text_domain' ),
            'parent_item_colon'          => __( 'Parent Faq Category:', 'text_domain' ),
            'new_item_name'              => __( 'New Faq Category Name', 'text_domain' ),
            'add_new_item'               => __( 'Add New Faq Category', 'text_domain' ),
            'edit_item'                  => __( 'Edit Faq Category', 'text_domain' ),
            'update_item'                => __( 'Update Faq Category', 'text_domain' ),
            'separate_items_with_commas' => __( 'Separate Faq Categories with commas', 'text_domain' ),
            'search_items'               => __( 'Search Faq Categories', 'text_domain' ),
            'add_or_remove_items'        => __( 'Add or Remove Faq Categories', 'text_domain' ),
            'choose_from_most_used'      => __( 'Choose from Most Used Faq Categories', 'text_domain' ),
        );
    
        $args = array(
            'labels'                     => $labels,
            'hierarchical'               => true,
            'public'                     => true,
            'show_ui'                    => true,
            'show_admin_column'          => true,
            'show_in_nav_menus'          => true,
            'show_tagcloud'              => false,
            'rewrite'                    => array('slug' => 'faq-category'),
        );
    
        register_taxonomy( 'faq_category', 'qa_faqs', $args );
    }
    
    // Hook into the 'init' action
    add_action( 'init', 'faq_taxonomy', 0 );
    /*
    add_filter('pre_get_posts', 'query_post_type');
    function query_post_type($query) {
     if(is_category() || is_tag()) {
     $post_type = get_query_var('post_type');
     if($post_type)
     $post_type = $post_type;
     else
     $post_type = array('nav_menu_item','post','faqs');
     $query->set('post_type',$post_type);
     return $query;
     }
    }
    */
    
    function coolio_tag_add_custom_types( $query ) {
        if( is_tag() && $query->is_main_query() ) {
            $post_types = array( 'post', 'qa_faqs' );
            $query->set( 'post_type', $post_types );
        }
    }
    add_filter( 'pre_get_posts', 'coolio_tag_add_custom_types' );

    I do not recall this happening in the past.

    Has something in core changed?

    Note:

    The “Preview Changes” Button in the post editor’s Publish metabox has a consistent URL attached to it in the form of:

    /cpt_rewrite_slug/cpt_single_post_slug/?preview=true&post_type=cpt_name

    that URL, when clicked on, is then redirected to a URL of the form:

    /cpt_rewrite_slug/cpt_single_post_slug/?preview_id=post_id&preview_nonce=random&post_format=standard&_thumbnail_id=-1&post_type=cpt_name

    So, what are we doing wrong in that we cannot preview changes on a published custom post type?

Viewing 5 replies - 1 through 5 (of 5 total)
  • Moderator bcworkz

    (@bcworkz)

    Hiya PWD,

    You get the award for most complete topic post. You’ve been around here a few times 🙂

    I tried your code in my own twentyseventeen child theme and could not replicate your problem. The rewritten preview URL is something the block editor does in order to utilize the REST API. It’s normal. I actually had to add 'show_in_rest' => true, to your arguments array to get the block editor to show up. Without it I got the classic editor, whose previews also work.

    I’m left with the impression that there must be something about your server configuration or WP installation that is outside the usual, otherwise no one’s CPT previews would be working. That’s not to say there are not issues, but as you know, every situation is different and one’s preview issue may not be related to any other preview issue.

    Unfortunately, from the information you provided, all I can contribute is that it works for me.

    @bcworkz

    First, thanks so much for looking into this and providing your feedback. I did actually just realize I had left the Classic Editor Plugin on while testing…which for now I need running on the sites. Please read on…

    And, just to be clear, you wrote:

    Without it I got the classic editor, whose previews also work.

    You did Publish the FAQ, then return to the editor later, make an edit, then click the ‘Preview Changes’ button??

    I did go ahead and add 'show_in_rest' => true, and have the following notes:

    First,

    Since day one of the official release on these sites of the Block Editor, I had installed the Classic Editor Plugin. I set the option ‘Allow users to switch editors‘ to ‘no‘ and the option ‘Default editor for all users‘ to ‘Classic Editor‘… We would need to provide some training on the new editor when we all have the time…

    Next, I went ahead on my test site (default theme, only plugin is Classic Editor) and changed the ‘Allow users to switch editors‘ to ‘yes‘, and now we see we can choose which editor we want to use.

    If I edit the FAQ CPT with the Block Editor, I can preview the changes and note that the button changes it’s URL to the form:
    /cpt_rewrite_slug/cpt_single_post_slug/
    and now simply reads ‘Preview’ (not ‘Preview Changes’),
    and does as you have noted, which is rewrite the URL to the _nonce URL and we can preview the changes.

    If I select the ‘Classic Editor’, the problem returns.

    Also, it’s not a server config issue as the Host is one of WP’s recommended ones, is quite widely used, and if it was an issue with them, they would have fixed that long ago.

    So, now the question is actually:

    How do we preview a published CPT when we want to continue to use the Classic Editor, but do so when the CPT was originally created either before the Block Editor came out, or when it was created and was always edited with it turned off?

    If someone could please test that scenario and provide additional feedback, that would be awesome.

    Moderator bcworkz

    (@bcworkz)

    Ah! Found the issue. It’s related to the allowing users to select editor option of the classic editor plugin. Even when you remove the setting, the problem persists until the plugin is deactivated. Activating without the option does not cause any issues. This in combination with a CPT makes this a rather unusual situation, explaining why it’s an unreported bug AFAIK.

    The root cause (well, not quite, but close to) of the problem is the preview URL’s CPT permalink base (/faqs/) is not parsed for some reason so the query is trying to only match post post_type. The work around would be to compile an array of all of your post types and set the post_type query var with the list in “pre_get_posts” action when there is a preview parameter in $_GET. For example:

    if( $query->is_main_query() && array_key_exists('preview_id', $_GET) ) {
    	$post_types = array( {list all post types here} );
            $query->set( 'post_type', $post_types );
    }

    Would you please compose a bug report in the Trac system please? I’m not quite sure that is the correct place, but the plugin is tightly integrated into WP and the real root cause is possibly in core.

    @bcworkz

    Great work! I can confirm that when I added this (after my code above):

    function coolio_query_var_gut_fix_it ($query) {	
    	if( $query->is_main_query() && array_key_exists('preview_id', $_GET) ) {
    		$post_types = array( 'post', 'qa_faqs' );
    			$query->set( 'post_type', $post_types );
    	}	
    }
    add_filter( 'pre_get_posts', 'coolio_query_var_gut_fix_it' );

    I can preview the changes!

    I will follow up soon on trac as suggested.

    Thanks!

    Important note:

    When I have that code running, and I try to Preview the Changes on a Page, I got these wonderful errors:

    Notice: wpdb::prepare was called incorrectly. The query only expected one placeholder, but an array of multiple placeholders was sent. Please see Debugging in WordPress for more information. (This message was added in version 4.9.0.) in /path/devcool19/wp-includes/functions.php on line 4773

    Notice: wpdb::prepare was called incorrectly. The query only expected one placeholder, but an array of multiple placeholders was sent. Please see Debugging in WordPress for more information. (This message was added in version 4.9.0.) in /path/wp-includes/functions.php on line 4773

    Warning: Cannot modify header information – headers already sent by (output started at /path/wp-includes/functions.php:4773) in /path/wp-includes/pluggable.php on line 1251

    Warning: Cannot modify header information – headers already sent by (output started at /path/wp-includes/functions.php:4773) in /path/wp-includes/pluggable.php on line 1254

    (any insight on that?)

    So, I modified above to:

    function coolio_query_var_gut_fix_it ($query) {
    /* Let's not do this for pages for now */	
    	if ( !is_page() ) {
    		if( $query->is_main_query() && array_key_exists('preview_id', $_GET) ) {
    			$post_types = array( 'post', 'qa_faqs' );
    				$query->set( 'post_type', $post_types );
    		}
    	}	
    }
    add_filter( 'pre_get_posts', 'coolio_query_var_gut_fix_it' );

    And all seems well (Preview Changes on Pages works), but I will definitely need more testing before I can roll this out to live sites…

    Again, thanks!

    Moderator bcworkz

    (@bcworkz)

    It’s probably because there is no “page” post type in the passed array of types. Your fix would be a legitimate way to fix that.

    Yes, thorough testing is mandatory! I only checked that the CPT query worked OK.

Viewing 5 replies - 1 through 5 (of 5 total)
  • You must be logged in to reply to this topic.