What you want is a rewrite endpoint.
You're already familiar with these. WordPress' urls that end with
feed are simple a rewrite endpoint, and you can add your own!
add_rewrite_endpoint takes two arguments: the endpoint you want, and the "mask" of where you want it to go. "mask" is just a number that you can do some bitwise math with to specify where you want the endpoint to go. As of WP 3.4 you can specify a custom
ep_mask when registering a post type.
The basic gist: hook into
add_rewrite_endpoint, specify the custom EP mask of your post type. Here's a really quick example (as a plugin here):
const EP = 262144;
private static $ins = null;
public static function instance()
is_null(self::$ins) && self::$ins = new self;
public static function init()
add_action('plugins_loaded', array(self::instance(), '_setup'));
register_activation_hook(__FILE__, array(__CLASS__, 'activate'));
register_deactivation_hook(__FILE__, array(__CLASS__, 'deactivate'));
public static function activate()
public static function deactivate()
public function _setup()
add_action('init', array($this, 'register'));
add_action('init', array($this, 'endpoints'), 15);
add_filter('request', array($this, 'filter_request'));
public function register()
'label' => __('Products', 'wpse'),
'public' => true,
'rewrite' => array(
'ep_mask' => self::EP,
public function endpoints()
public function filter_request($vars)
$vars['detailed'] = true;
The only downside to this is that endpoints are meant to be used as
/<endpoint_name>/<some_value>. So without
<some_value> present the endpoint technically wouldn't work -- hence the filter hooked into
request. Check if the endpoint is set, and set it to true if it is.
That also means that
/detailed/asdf would work just as well as
/detailed/. Not a huge issue to but something to be aware of.
On the front end side of things, you can check to see if the endpoint exists by using
// we're on /product/some-product/detailed/
// do stuff!
add_rewrite_endpoint adds query variables with the same name as you specified for the endpoint.
detailed in this case.