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
    How to Create a Twitter Card

    One of my favorite social APIs was the Open Graph API adopted by Facebook.  Adding just a few META tags to each page allowed links to my article to be styled and presented the way I wanted them to, giving me a bit of control...

  • By
    Send Text Messages with PHP

    Kids these days, I tell ya.  All they care about is the technology.  The video games.  The bottled water.  Oh, and the texting, always the texting.  Back in my day, all we had was...OK, I had all of these things too.  But I still don't get...

Incredible Demos

  • By
    jQuery Link Nudging

    A few weeks back I wrote an article about MooTools Link Nudging, which is essentially a classy, subtle link animation achieved by adding left padding on mouseover and removing it on mouseout. Here's how to do it using jQuery: The jQuery JavaScript It's important to keep...

  • By
    Animated AJAX Record Deletion Using jQuery

    I'm a huge fan of WordPress' method of individual article deletion. You click the delete link, the menu item animates red, and the item disappears. Here's how to achieve that functionality with jQuery JavaScript. The PHP - Content & Header The following snippet goes at the...

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!