Have you ever wanted to be able to serve up an alternative version of your posts, perhaps tweaking the layout or even the content of the posts? Not all the time, just in certain circumstances?

I’ve had two cases recently where I’ve needed to do this. My solution: to change the post template when a certain URL parameter is added to the URL.

When this technique is implemented, a user going to:

http://domain.com/postname/

will get the normal post in the normal template. A user going to

http://domain.com/postname/?template=basic

will be presented the post in an alternative layout or even with altered content.

To make what we’re trying to achieve clear, let me first outline my two use cases. After that, I’ll show you how to achieve this by a) serving up a different post template based on a URL parameter and b) creating the custom post template.

Use Case 1: Removing Headers, Footers And Sidebars

For one project I’m working on, I needed to serve up the post content only. Everything else, including the header, footer and the sidebars needed to be stripped out. I needed this ‘post content only’ version to be always available, for every post, but for the original fully styled posts to be available as well.

Here are some screenshots from my local development environment to demonstrate what I want to achieve. The full post lives at http://localhost/wprs-support/mark-webber/ and displays normally:

When ?template=basic is appended to the URL (ie http://localhost/wprs-support/mark-webber/?template=basic), the custom post template is triggered and just the content is displayed:

Why do I want to do this? I’ll be pulling in the content into another page, probably via an Ajax call (or possibly through an iFrame). I don’t need the headers, sidebars etc as they will already be displayed on the page I’m pulling the content into. It’s not possible to only pull in a section of a page in an iFrame or via Ajax, so I need to strip that stuff out.

Okay, it’s possible to get the whole page and then strip out the stuff I don’t want via JavaScript, but that means that it’s downloading the whole page unecessarily, making it slower, etc. It’s much better to be able to download just the content itself without the rest of the presentation layer.

Use Case 2: Changing Content

I’m the lead developer (but not the owner) of the WP Review Site plugin. I recently had a customer asking to get the average rating for a particular post, so they could display it in a banner on another site via an iFrame. There are other ways to achieve this, but the simplest is to use the URL Parameter and post template combination to serve up just the average rating, as follows:

The URL used here is the same as the one for the ‘post content only’ version shown above, but I’ve swapped out the custom post template. Rather than just stripping out the header, sidebar and footer, it’s actually serving up different content: the average rating for the post, instead of the post content.

How To Serve Up A Different Template

It’s reasonably easy to use a custom post template when a certain URL parameter is detected.

First we need to let WordPress know about the URL parameter so we can detect it later. We do this by adding the following code to your theme’s functions.php file:

We use the query_vars filter (line 4) to call a function (line 1) that returns the existing array of query vars with our new one added on the front (line 2). I’ve used ‘template’ as the URL parameter and have continued to use that below, but you can use what ever you want (as long as it’s not one that’s commonly used already).

Note: We could just use $_GET[‘template’] rather than adding it to the query_vars array, but it’s not best practice. Using the query_vars method future proofs us in case we later decide to rewrite the URL structure to make fancy permalinks for this URL parameter, eg: http://domain.com/postname/template/basic/ instead of http://domain.com/postname/?template=basic

Next, we check for the existence of the URL parameter / query_var, by adding the following code to your theme’s functions.php file (below the code given above):

We use the single_template filter (line 10) to call a function called sjc_template (line 1). This function checks if the URL parameter is set (line 3) and, if so, returns the path to the single-basic.php template file (line 4). If the URL parameter doesn’t exist, the default template is returned unchanged (line 7).

Once again, I’ve used single-basic.php, but you can call this file whatever you want – as long as you are consistent with the name when creating the template file below.

Disclaimer: The above code will fail if the single-basic.php file(or whatever you’ve called it) doesn’t exist. We should probably use file_exists to check it’s there and error out nicely if not. I’d do that if I was publically releasing a theme or plugin or doing client work, but haven’t bothered in this case.

There is an increasing trend to put code such as this into a ‘custom functionality’ plugin rather than functions.php, so that it is still available if you switch themes. That’s a great idea in general, but not particularly useful in this case, because the code is calling a custom template in your theme directory. Switch themes and this will break anyway, unless you recreate the template in the new theme.

How To Create The Custom Post Template

Once we’ve told WordPress to use a custom post template instead of single.php, we need to create that custom post template.

In your theme folder you need to create a file called single-basic.php (you can call this whatever you want, as long as it matches the file name requested in the previous step).

What’s in this file? Whatever you want to tweak the post. For my ‘post content only’ format shown above, I used the following:

Note: this just creates part of the page. It doesn’t have html, head or body tags. That’s probably no good if you want people to actually visit this page in the browser, but in my case it’s primarily for me to pull the content in to be displayed in a page that already has a html, head and body tags. It’s better for me to have it ready to go.

If you need to have a full HTML page, simply add the tags to single-basic.php. You can probably get the basic code from your header.php file, leaving out the extra lines that aren’t necessary. You could even link to a custom CSS file if you just want to make style changes, although there is a better way to do that (without using custom post templates).

This technique could cause duplicate content in the eyes of the search engines. It may be best to add <meta name="robots" content="noindex"> to the head of the page (if you have that section) or to exclude pages with this paramters in robots.txt.

For my ratings only example from above, my single-basic.php file contains the following:

I don’t need the post content. I just need the average rating, which I’m getting through the WP Review Site API. This will return a plain number, not wrapped in any HTML. Once again, if a full HTML page is required, you need to add the appropriate tags to the template file.

Critically, WordPress is still serving up the same post, even if we’re not choosing to display it. The post ID and everything else associated with the post is still present and available to us.

Final Thoughts

This technique has served me well on a number of occasions. It provides the flexibility to serve up altered content / layout for your posts, through the power of custom post templates.

Hi, I just wanted to say that I commissioned nearly identical functionality from a developer for exactly the same reason! My implementation uses pages, so it was easier as pages already have a fully supported template system, but we had to ensure any page viewed in a popin had the correct template, and that meant a dynamic switching system for the page templates.

I wanted to add that this also addresses a functionality issue when using popins to display WP content, as if the header file loads again, WP can pitch a fit over duplicate headers and possibly even whitescreen the page on you depending on what plugins are doing in wp_header. So this little trick is more important than it may seem

Hi, thanks for this great post, I was looking for this!
So if I understand correctly: you could add this parameter to the post permalink in your page-template to get a different single-post template something like this:

href="/?template=basic"

If I wanted to rewrite the url with parameter to a different domain, would my .htaccess file look something like this?

I had the same problem as others here: I wanted to implement this at a page level (not posts). Ended up being incredibly easy to fix, but posting the solution here just in case someone is still trying to find an answer. Simply replace the ‘single_template’ bit on the last line of code (add_filter) with ‘page_template’.