• I’ve defined a custom post type, ‘Review’, that I’d like to utilize with a custom permalink: /reviews/parentcat/childcat/postname. The below code correctly creates the CPT and the custom permalink appears correctly in the administrative panel when creating a new ‘Review’. However, the resulting ‘Review’ that is created returns a 404 when clicking the custom permalink. What is the modern wordpress way of solving this issue? Ideally I’d like not to use any external plugins. The below code is defined within a custom plugin. The permalinks have already been refreshed, that is not the issue.

    // Register 'Review' custom post type
    add_action( 'init', 'vidcreate_post_types' );
    
    // Register the permalink structure desired for 'Review' posts, with placeholders
    add_action( 'init', 'vidrewrite_rules' );
    
    // Replace permalink placeholders with actual content
    add_filter('post_type_link', 'update_review_link_placeholders', 10, 2);
    
    /**
     * Custom 'Review' post type
     */
    function vidcreate_post_types() {
    
    	register_post_type( 'review',
    		array(
    			'labels' => array(
    				'name' => __( 'Reviews' ),
    				'singular_name' => __( 'Review' )
    			),
    			'public' =>  true,
    			'has_archive' => true,
    			'taxonomies' => array('category', 'post_tag'),
    			'rewrite' => array(
    				'slug'=>'reviews',
    				'with_front'=> true,
    				'feed'=> true,
    				'pages'=> true
    			),
    			'hierarchical' => true,
    			'menu_icon' => 'dashicons-video-alt',
    			'supports' => array(
    				'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments', 'revisions', 'page-attributes'
    			)
    		)
    	);
    
    }
    
    /**
     * Create custom permalink structure for 'Review' pages
     */
    function vidrewrite_rules(){
    
    	add_rewrite_tag( '%review_slug%', '(reviews)','post_type=review&slug=' );
    	add_permastruct( 'review', '/reviews/%category%/%review%');
    
    }
    
    /**
     * Update permalinks placeholders with content
     */
    function update_review_link_placeholders($permalink, $post) {
    
    	if(('review' == $post->post_type) && '' != $permalink && !in_array($post->post_status, array('draft', 'pending', 'auto-draft')) ) {
    
    		// Get category for post
    		$post_categories = wp_get_post_categories( $post->ID );
    		$cateogryObject = get_category( $post_categories[0] ) ;
    
    		$category_link = $cateogryObject->slug;
    
    		// get full category slug, including parent cat
    		if ( $parent = $cateogryObject->parent ) {
    			$category_link = get_category_parents($parent, false, '/', true) . $category_link;
    		}
    
    		// replace placeholder with slud
    		$permalink = str_replace('%category%', $category_link, $permalink);
    
    		return $permalink;
    	}
    
    }
Viewing 6 replies - 1 through 6 (of 6 total)
  • Removing rewrite rules and then recreating it might solve your problem
    flush rewrite rules

    As a quick test, visit the Permalinks page under Settings in the WordPress admin. After I visited it, which does flush the rewrite rules, your code did load the page for me (instead of a 404).

    Thread Starter ph34r

    (@ph34r)

    Eggheads, as stated originally, the rewrite rules had already been flushed prior to submitting the request for assistance.

    Ryan, did you verbatim copy my code for your test? I am still unable to get the CPT permalinks to function as intended.

    Yes, here is what I did:

    * Setup brand new WordPress 4.1 site
    * Enabled permalinks
    * Pasted your code into functions.php of the Twenty Fourteen theme
    * Created category called “test”
    * Created new review called “hello” and checked “test” category
    * Published review and visited link

    First time I visited, I got a 404. Then I visited the Permalinks settings page, and tried to visit the review again, then it loaded. This was the URL: example.org/reviews/test/hello/

    Thread Starter ph34r

    (@ph34r)

    Hi Ryan,

    Thanks for quick reply back. What I noticed in recreating your steps is that it works fine if only a parent category is selected. However, if a sub category (e.g. test -> testsub) is created and only the sub category is selected, neither link works (reviews/test/post/ nor /reviews/test/sub/post). If the sub category and parent category are selected, then only the top level permalink will work (reviews/test/post, not reviews/test/sub/post).

    Any idea on how to address this? In order for everything to work as intended, I really need the subcategory permalink to work, that was the point of the following snippet in my code:

    // get full category slug, including parent cat
    		if ( $parent = $cateogryObject->parent ) {
    			$category_link = get_category_parents($parent, false, '/', true) . $category_link;
    		}

    I know this is doable, because I’m able to achieve it using the “Custom Post Type Permalinks” plugin by Toro_Unit, but I can’t rely on that plugin for this project.

    What about something like this?

    function vidrewrite_rules(){
    	add_rewrite_tag(
    		'%primary_category%',
    		'([^&]+)'
    	);
    
    	add_rewrite_rule(
    		'^reviews/([-a-z0-9]+)/([-a-z0-9]+)?$',
    		'index.php?post_type=review&primary_category=$matches[1]&review=$matches[2]',
    		'top'
    	);
    
    	add_rewrite_tag(
    		'%secondary_category%',
    		'([^&]+)'
    	);
    
    	add_rewrite_rule(
    		'^reviews/([-a-z0-9]+)/([-a-z0-9]+)/([-a-z0-9]+)?$',
    		'index.php?post_type=review&primary_category=$matches[1]&secondary_category=$matches[2]&review=$matches[3]',
    		'top'
    	);
    }
Viewing 6 replies - 1 through 6 (of 6 total)
  • The topic ‘Custom Post Type with modified permalink structure results in 404’ is closed to new replies.