0

I have a custom post type mycpt and I'm trying to allow for a variable to be appended onto the end of the URL right after the post name slug, like this:

www.site.com/mycpt/the-name-of-my-post/var-value-here/

I've been searching around, and the only examples I can find don't use the post name/slug in the URL, but rather taxonomies, so I'm not sure what the correct way to do it is. Here is what I'm trying now, but it's treating the URL with the variable as a separate page type (it's loading a default template rather than the template my custom post type uses).

add_action( 'init', function() {
    add_rewrite_tag( '%my_var%', '([^/]*)' );
    add_rewrite_rule( '^mycpt/(.*)/([^/]*)/?', 'index.php?post_type=mycpt&my_var=$matches[1]', 'top' );
}, 10, 0 );

I also tried changing $matches[1] to $matches[2] since I thought maybe the wildcard for the post name/slug was the first match, but that didn't work either.

Can anybody see what I'm doing wrong here?

4
  • WordPress doesn't know which post you want, you only pass the value of my_var in your rewrite rule.
    – Milo
    Jul 4, 2018 at 19:50
  • @Milo do I need to manually add the &p=xxx url parameter? I figured WordPress automatically added that, since none of the examples I found added that parameter.
    – Gavin
    Jul 4, 2018 at 19:51
  • Yes, but not p, it's whatever your post type slug is, mycpt in your example. Rewrite rules need to set all the necessary query vars to result in a successful main query.
    – Milo
    Jul 4, 2018 at 19:54
  • I actually wasn't able to get this working. I ended up just using add_rewrite_endpoint and having a variable name in the permalink structure.
    – Gavin
    Jul 6, 2018 at 18:38

2 Answers 2

5

Here's a complete working example that adds a post type, with extra rule to capture an additional parameter:

function wpd_post_type_and_rule() {
    register_post_type( 'mycpt',
        array(
            'labels' => array(
                'name' => __( 'mycpt' ),
            ),
            'public' => true,
            'rewrite' => array( 'slug' => 'mycpt' ),
        )
    );
    add_rewrite_tag( '%mycpt_var%', '([^/]*)' );
    add_rewrite_rule(
        '^mycpt/([^/]*)/([^/]*)/?$',
        'index.php?mycpt=$matches[1]&mycpt_var=$matches[2]',
        'top'
    );
}
add_action( 'init', 'wpd_post_type_and_rule' );

After adding this and flushing rewrite rules, you'll have both

www.site.com/mycpt/the-name-of-my-post/

and

www.site.com/mycpt/the-name-of-my-post/var-value-here/

You can get the value of mycpt_var in the template with:

echo get_query_var( 'mycpt_var' );
1
  • Thanks, that worked perfectly! Not sure why it wasn't working before, since this is exactly what you described at first.
    – Gavin
    Jul 9, 2018 at 16:37
1

As a temporary solution you can try using free plugin : https://wordpress.org/plugins/custom-post-type-permalinks/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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