I have a custom post type called “destinations” and I have set the EP mask for the post type to default EP_PERMALINK. I have added a couple of endpoints as follows :
add_filter( 'query_vars', 'add_query_vars');
function add_query_vars($vars){
$vars[] = "tours";
$vars[] = "activities";
return $vars;
}
add_action('init', 'add_endpoints');
function add_endpoints(){
global $wp_rewrite;
add_rewrite_endpoint('tours', EP_PERMALINK);
add_rewrite_endpoint('activities', EP_PERMALINK);
$wp_rewrite->flush_rules();
}
Now if I test this on a normal post it redirects to the template that I need it to (I have a template redirect for the single template hook)
ie. somesite.com/test-category/test/activities/
But for the post type (which is hierarchical) it just removes the endpoint from the url and stays on the single-destination.php template
ie. somesite.com/destination/south-africa/kruger-national-park/activities/
becomes
somesite.com/destination/south-africa/kruger-national-park/
Any help or guidance will be greatly appreciated. I have been struggling with this for hours and no results 🙁
Thanks
1
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.