Different permalink for CPT and regular Posts/Pages but why?

Permalink structure in Back-end: http://domain.com/%year%/%category%/%postname%

For “regular” Posts/Pages all is okay but as soon a CPT is shown %year% is gone?

Read More

Url shown for Posts/Pages looks some like: http://domain.com/2014/category01/regular-post001
Url shown for CPT looks some like: http://domain.com/category01/cpt-post002

Most weird (to me) is, when I give in (for that CPT) http://domain.com/2014/category01/cpt-post002 it shows the CPT BUT then leaves out/redirects to the url without 2014(year).

What am I missing/doing wrong?

Related posts

Leave a Reply

1 comment

  1. The permalink configuration in WordPress backend is only for standard posts and pages. For CPT the default URL structure is http://example.com/cpt-identifier/post-slug. If you want a different URL structure for you CPT you will have to define and register your own rewrite rules.

    For example:

    add_action( 'init', 'register_posttype' );
    function register_posttype() {
    register_post_type( 'my_cpt', //this will be in the URL as CPT identifier
        array(
            'labels' => array(
                'name' => __( 'My Custom Post Types' ),
                'singular_name' => __( 'Custom Post Type' )
            ),
            'public' => true,
            'has_archive' => true,
            'rewrite' => array('slug' => 'products'), //This will override the CPT identifier
        )
    );
    }
    

    If you want to include dinamic tag in the URL structure of your CPT, like year, you will have to define your own rewrite rules and permalink filter:

    add_action( 'init', 'register_posttype' );
    function register_posttype() {
    register_post_type( 'my_cpt', //this will be in the URL as CPT identifier
        array(
            'labels' => array(
                'name' => __( 'My Custom Post Types' ),
                'singular_name' => __( 'Custom Post Type' )
            ),
            'public' => true,
            'has_archive' => true,
            'rewrite' => array('slug' => '%year%/my_cpt'), //This will override the CPT identifier
        )
    );
    }
    
    add_filter('post_type_link', 'modify_permalink');
    function modify_permalink($url, $post = null) {
        // limit to certain post type. remove if not needed
        if (get_post_type($post) != 'my_cpt') {
            return $url;
        } elseif(!is_object($post)) {
            global $post;
        }
        $url = str_replace("%year%",  get_the_date('Y'), $url);
    
        return $url;
    }
    
    add_action('init','my_add_rewrite_rules');
    function my_add_rewrite_rules() {
        add_rewrite_rule('([0-9])/my_cpt/(.+)/?$', 'index.php?post_type=my_cpt&post=$matches[1]', 'top' );
    }