I have a custom post type called event. The URL structure looks like this.


Where "workshop" is the name of the event. Right now the template will show different data depending on the query string. For example this URL:


Will loop out some files. I'm adding the query string so i can do that in the same template.

$sub = isset( $_GET['sub'] ) ? $_GET['sub'] : null;
switch ( $sub ) {
    case "files":
        echo "TODO: Loop out files";
    case "participants":
        echo "TODO: Loop out participants";
    case "agenda":
        echo "TODO: Write out the agenda!";
        <!-- etc -->

But i don't like this URL structure! I'd like the URL to be:


So that i in the "Event" template (/workshop/) can look at the URL structure instead of the query string. The problem is that adding /filesto the URL will make wordpress look for a page that doesn't exist and give a 404.

Is it possible to do some URL wizardry so the template (and post data) of this url:


Also kicks in with this URL:


  • To clarify, you want URLs such as http://web.site/events/2016/08/16/hello-world?sub=files http://web.site/events/1999/12/31/new-years?sub=images to strip ?sub= and replace it with a / to be 2016/08/16/hello-world/files? – Ethan O'Sullivan Aug 26 '16 at 4:52
  • @EthanJinksO'Sullivan Nope, don't wanna use query strings at all. See "update 2" – Johan B Aug 27 '16 at 7:03
  • I'm confused by your question then. From what I understand: your website is having pages with .../events/2016/08/21/workshop?sub=files but you want the structure to be /events/2016/08/21/workshop/files instead. Where /files is another page template? You're gonna have to clarify your question more. Since I'm not the only one not understanding it entirely. – Ethan O'Sullivan Aug 28 '16 at 3:18
  • @EthanJinksO'Sullivan Sorry for the confusion. Your assumption is almost exactly what i mean. Except the last part. I want /files to use the same template (and post object) as the "Event" (/workshop/). I have rewritten the post to clarify more. – Johan B Aug 29 '16 at 12:32

Put this code in your functions.php-

function the_dramatist_url_rewrite() {
    global $wp_rewrite;
    add_rewrite_tag('%sub%', '([^&]+)');
add_action('init', 'the_dramatist_url_rewrite', 10, 0);

The go to the permalinks page in the settings menu at dashboard and hit Save Changes button. Hope this is gonna help.

  • ps: the add_rewrite_rule might need some fixing too – birgire Aug 21 '16 at 16:45
  • Sure. Go ahead. You can edit my answer or you can suggest me. :) – CodeMascot Aug 21 '16 at 16:55
  • Since I don't fully understand the question I don't want to do possible wrong edits ;-) like if files is a static word or if it's for any file attachment or something else or how the current rewrite rules are constructed? But hopefully OP can use your suggestions as a starting point and even explain it better for you. PS: I noticed a missing ? for index.php and then it's not clear what matches $matches[1]. – birgire Aug 21 '16 at 20:57
  • Sorry, i was a bit unclear. I updated my question. I don't to rewrite my query strings. I don't want to use them at all. Problem is; how do i make the template to be used when there is an extra step in the URL? – Johan B Aug 22 '16 at 8:26

I ended up using end points. This is my final (but simplified) code. In functions i added this.

add_action('init', 'jbenjaminsson_add_endpoints');
function jbenjaminsson_add_endpoints()
    add_rewrite_endpoint( 'files', EP_PERMALINK );
    add_rewrite_endpoint( 'participants', EP_PERMALINK );
    add_rewrite_endpoint( 'agenda', EP_PERMALINK );

add_filter( 'request', 'jbenjaminsson_filter_request' );
function jbenjaminsson_filter_request( $vars )
    if( isset( $vars['files'] ) ) $vars['files'] = true;
    if( isset( $vars['participants'] ) ) $vars['participants'] = true;
    if( isset( $vars['agenda'] ) ) $vars['agenda'] = true;
    return $vars;

And on the template i did this:

if ( get_query_var( 'files' ) ) {
    get_template_part( '/template-parts/event', 'files' );
} elseif ( get_query_var( 'participants' ) ) {
    get_template_part( '/template-parts/event', 'participants' );
} elseif ( get_query_var( 'agenda' ) ) {
    get_template_part( '/template-parts/event', 'agenda' );
  • Need to change EP_PERMALINK to EP_PERMALINK | EP_PAGES if you're on a page (and maybe other cases) and make sure to re-save permalink settings. – joshcanhelp Apr 17 '17 at 23:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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