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

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

<?php
/*
Template Name: Demos and Downloads
*/

/* helper:  does regex */
function get_content_match($regex,$content) {
	preg_match($regex,$content,$matches);
	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(); ?>
<?php 
	$content = get_the_content();
	if(strstr(strtolower($content),'href="https://davidwalsh.name/demo/')):
?>
	<h1><a href="<?php the_permalink(); ?>"><?php the_title(''); ?></a></h1>
	<p style="padding-bottom:3px;padding-left:5px;">
	<?php
		$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:\/\/davidwalsh.name\/demo\/(.*)">/isU',$content));
		if($image) { echo '<img src="'.$image.'" class="image" alt="Tutorial Demo" />'; }
		echo $intro;
	?>
	</p>
	<div class="demo-actions">
		<a href="<?php the_permalink(); ?>" class="conred">Continue Reading »</a>
		<a href="https://davidwalsh.name/demo/<?php echo $link; ?>" class="demo">View Demo</a>
	</div>
<?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>
	</div>
	<?php if($paged != 1): ?>
	<div class="nav-right">
		<a href="/demos/page/<?php echo $paged - 1; ?>">Newer posts »</a>
	</div>
	<?php endif; ?>
	<div class="clear"></div>
</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

  • By
    5 HTML5 APIs You Didn&#8217;t Know Existed

    When you say or read "HTML5", you half expect exotic dancers and unicorns to walk into the room to the tune of "I'm Sexy and I Know It."  Can you blame us though?  We watched the fundamental APIs stagnate for so long that a basic feature...

  • By
    How I Stopped WordPress Comment Spam

    I love almost every part of being a tech blogger:  learning, preaching, bantering, researching.  The one part about blogging that I absolutely loathe:  dealing with SPAM comments.  For the past two years, my blog has registered 8,000+ SPAM comments per day.  PER DAY.  Bloating my database...

Incredible Demos

  • By
    DWRequest: MooTools 1.2 AJAX Listener &#038; Message Display

    Though MooTools 1.2 is in its second beta stage, its basic syntax and theory changes have been hashed out. The JavaScript library continues to improve and become more flexible. Fellow DZone Zone Leader Boyan Kostadinov wrote a very useful article detailing how you can add a...

  • By
    Jack Rugile&#8217;s Favorite CodePen Demos

    CodePen is an amazing source of inspiration for code and design. I am blown away every day by the demos users create. As you'll see below, I have an affinity toward things that move. It was difficult to narrow down my favorites, but here they are!

Discussion

  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: http://codex.wordpress.org/Plugin_API/Filter_Reference/request

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