Multiple templates for a custom post type

As new user to wordpress I’m finding that the preset templates structure a little restricting coming from the flexibility of other template routed CMS I’ve worked with.

Saying this, I know there are plenty of workarounds and I’m now currently in the process of trying to establish them.

One of the main hurdles I’m finding is wrangling content into multiple locations. Currently I’m trying to output the same post type content into two sections or templates.

For example I have a custom post type “ballons” with ballon related posts. I’d like to output these posts into two different templates / sections (for this example, a normal version and a mobile version)

The url structure would ideally represent this:

/{post_type}/{post_slug}

/ballons/my_red_ballon_post
/mobile/ballons/my_red_ballon_post

The only way I know how to route this url structure to a specific template, is by using pages. If possible though, I’d like avoid having a entry in pages as there is no page specific content.

Once this has been setup I’d like to create a listing page of all my ballons. I’d like to know if this setup is the same or different to just outputting specific posts like above.

The url structure would be:

/ballons/
/mobile/ballons/

Thanks for your time 😀

— paul

2 Answers
2

Mobile might not be a great example — responsive design would take care of that.

Were this my project I would take a slightly different approach. Instead of prefixing the URL, I would stick the mobile on the end with an rewrite endpoint. An endpoint combined with using the template_include filter would work.

So you end up with a permalink structure like this

/{post_type}/{post_slug}

/{post_type}/{post_slug}/mobile

There are many answers that explain this elsewhere. For the mobile endpoint.

<?php
add_action('init', 'wpse74553_add_endpoints');
function wpse74553_add_endpoints()
{
    // EP_ALL adds the endpoint to everything.
    add_rewrite_endpoint('mobile', EP_ALL);
}

// this makes the naked `mobile` endpoint work vs. having to
// use something `mobile/works`.
add_filter('request', 'wpse74553_filter_request');
function wpse74553_filter_request( $vars )
{
    if(isset($vars['mobile']))
        $vars['mobile'] = true;

    return $vars;
}

From there you can hook into template_include filter and change the template if the mobile query variable is set.

<?php
add_filter('template_include', 'wpse74553_include');
function wpse74553_include($t)
{
    if(get_query_var('mobile'))
    {
         // you have a request with the mobile endpoint
         $t="mobile-template.php";
    }

    return $t;
}

The only thing to watch out for is that template_include fires on every request. It’s not specific — so if you want to use it, you’ll probably need to do more checking than above. There’s also a bunch of more specific filters; take a look in wp-includes/template.php to get an idea, specifically the function get_query_template.

For single posts you could use the single_template filter, for instance.

In short, you’re not at all limited by the template hierarchy, you can change it at will with the template_include or any of the {{type}}_template filters.

Leave a Comment