Create WordPress Page Templates with Custom Queries

By  on  

One of my main goals with the redesign was to make it easier for visitors to find the information that was most popular on my site. Not to my surprise, posts about MooTools, jQuery, and CSS were at the top of the list. What do those three topics have in common? The fact that I provide a sweet demo for each of them. Thus I set out to create an easy way to check out all of my demos -- the Demos & Downloads page.

I could address my Demos and Downloads link to "/index.php?s=view+demo" but that's ugly -- not SEO friendly nor is it an address anyone will remember. The solution was to create a new page template that would act similar to a search results page but afford me much more flexibility.

The Strategy

The first step was to identify posts that had a demo. If I were starting my blog today I would add a custom field called "demo" and give all posts containing a demo a value of "1". The issue is that I have 2 years worth of posts and no desire to add a custom field to all of those posts that contain demos. I do know, however, that the label of all of my demos is "View Demo" so any post containing that string would likely contain a demo. Problem solved: I will need a search parameter for my custom query that looks for the "view demo" string.


WP_Query is WordPress' awesome database interaction class. WP_Query accepts dozens of helpful parameters in the form of a request string or an array to grab the posts you need (writing raw MySQL statements sucks). With my strategy mapped out and WP_Query researched, it was GO time.

The Page Template PHP

Template Name: Demos and Downloads

/* helper:  does regex */
function get_content_match($regex,$content) {
	return $matches[1];

/* list of "view demo" posts */
$paged = (get_query_var('paged')) ? (int) get_query_var('paged') : 1;
$demoPosts = new WP_Query('s=view+demo&showposts=10&order=desc&post_status=publish&paged='.$paged);

<?php get_header(); ?>

<h1>Demos & Downloads</h1>

<?php while ($demoPosts->have_posts()) : $demoPosts->the_post(); ?>
	$content = get_the_content();
	<h1><a href="<?php the_permalink(); ?>"><?php the_title(''); ?></a></h1>
	<p style="padding-bottom:3px;padding-left:5px;">
		$intro = get_content_match('/<p>(.*)<\/p>/isU',$content);
		$image = get_content_match('/src="(.*)" class="image"/isU',$content);
		$link = strip_tags(get_content_match('/href="http:\/\/\/demo\/(.*)">/isU',$content));
		if($image) { echo '<img src="'.$image.'" class="image" alt="Tutorial Demo" />'; }
		echo $intro;
	<div class="demo-actions">
		<a href="<?php the_permalink(); ?>" class="conred">Continue Reading »</a>
		<a href="<?php echo $link; ?>" class="demo">View Demo</a>
<?php endif; ?>
<?php endwhile; ?>

<div class="next-prev-links no-print">
	<div class="nav-left">
		<a href="/demos/page/<?php echo $paged + 1; ?>">« Older Posts</a>
	<?php if($paged != 1): ?>
	<div class="nav-right">
		<a href="/demos/page/<?php echo $paged - 1; ?>">Newer posts »</a>
	<?php endif; ?>
	<div class="clear"></div>

<!-- <?php trackback_rdf(); ?> -->
<?php get_footer(); ?>

Notice that in order to use pagination within the demos section, I needed to set my own $paged variable and add it to the WP_Query parameters string. The other parameters should be self explanatory.

Once I had the posts for the page, I'd cycle throw each post and use some custom PHP (which you couldn't easily do on the search page) to parse the post content to and pull out a supporting image and link to the demo. The result is my Demos and Downloads page.

Beautiful! Don't be afraid to create custom page templates with content generated from your own custom queries. Have any other pages that you think would make the site better? Let me know!

Recent Features

Incredible Demos

  • By
    Ana Tudor&#8217;s Favorite CodePen Demos

    Cocoon I love canvas, I love interactive demos and I don't think I have ever been more impressed by somebody's work than when I discovered what Tiffany Rayside has created on CodePen. So I had to start off with one of her interactive canvas pens, even though...

  • By
    jQuery Chosen Plugin

    Without a doubt, my least favorite form element is the SELECT element.  The element is almost unstylable, looks different across platforms, has had inconsistent value access, and disaster that is the result of multiple=true is, well, a disaster.  Needless to say, whenever a developer goes...


  1. I’ve really liked the WordPress Database system ever since i started with WordPress. EZSQL is an awesome class I now use whenever I need to make something non-wp (very rare)

  2. really wordpress as cms with this plugin…

    something wrong with demo page.. see the first article demo..

    may be this problem occured coz word “view demo” in this page which is no demo.. actually..

    nice tricks again..

  3. Good idea Matt! I should check that out.

  4. This query is an awesome query and had no idea that was possible. You can use this one step further and make multiple queries on one page where clients can edit all the text on one page very easy! Just blew my mind.

  5. blog sites thanks for your shiarn g e

  6. Hey David, Thanks for this awesome post :) I have one doubt though, rather than using the built in function : next_posts_link(‘« Older Entries’) why are you using custom url like this? /demos/page/<?php echo $paged + 1;

    Oh and it ain't working for me I don't know why.. :| When I click on the older posts link, its changing the URL to page/2 but showing the same posts :|

  7. can anybody start with:

    .. to create another wp template – go there and there, do that and that…

    no – people love to start with exact code :(

    then, name the topic “code of a new WP Page Template”

  8. Nice article.

    But what did you save this custom php page template as? And how do you get WordPress to link to it? Or did you overwrite the default page.php?

  9. Great! I needed to do something similar, googled it before “inventing the warm water” (as we say in spanish) and found this. I’ll do something similar, but I’m combining your idea with this:

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!