Custom post type permalink endpoint

A couple things. First, your function names need to be prefixed with something unique. WordPress is a big ecosystem, and someone else has probably used all the generic function names you can think of.

Second, add_rewrite_endpoint takes care of adding query variables for you. So you don’t need this:

add_filter( 'query_vars', 'add_query_vars');
function add_query_vars($vars){
    $vars[] = "tours";
    $vars[] = "activities";
    return $vars;
}

Flushing rewrite rules on every load is not a good idea. This only needs to be done once after your rules have been added. Like on plugin activation. So you add_endpoints function could be shorted to this (with a better function name per point one above).

<?php
add_action('init', 'wpse42279_add_endpoints');
function wpse42279_add_endpoints()
{
    add_rewrite_endpoint('tours', EP_PERMALINK);
    add_rewrite_endpoint('activities', EP_PERMALINK);
}

Which works fine for posts. If you want it to work on pages or any other hierarchical post type, you’ll have to use the EP_PAGES endpoint mask.

<?php
add_action('init', 'wpse42279_add_endpoints');
function wpse42279_add_endpoints()
{
    add_rewrite_endpoint('tours', EP_PAGES);
    add_rewrite_endpoint('activities', EP_PAGES);
}

But that’s still not going to work as expected for you. Endpoints set their query variable equal to whatever comes after it. So if your URL is…

yoursite.com/some-country/some-city/activities/asdf

the query variable activities will be asdf. If nothing follows activities, your query var will be empty (but set), so it will always evaluate as false when you try to catch it…

<?php
add_action( 'template_redirect', 'wpse42279_catch_vars' );
function wpse42279_catch_vars()
{
    if( get_query_var( 'tours' ) )
    {
        // do stuff!
        exit();
    }
}

You can get around this by filtering request and changing the value of your tours and activities variables to true if they are set.

<?php
add_filter( 'request', 'wpse42279_filter_request' );
function wpse42279_filter_request( $vars )
{
    if( isset( $vars['tours'] ) ) $vars['tours'] = true;
    if( isset( $vars['activities'] ) ) $vars['activities'] = true;
    return $vars;
}

You should have a look at this guide to the Rewrite API I wrote. The relevant parts for your question are summed up above, however.

Leave a Comment