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
    Being a Dev Dad

    I get asked loads of questions every day but I'm always surprised that they're rarely questions about code or even tech -- many of the questions I get are more about non-dev stuff like what my office is like, what software I use, and oftentimes...

  • By
    JavaScript Promise API

    While synchronous code is easier to follow and debug, async is generally better for performance and flexibility. Why "hold up the show" when you can trigger numerous requests at once and then handle them when each is ready?  Promises are becoming a big part of the JavaScript world...

Incredible Demos

  • By
    Web Notifications API

    Every UI framework has the same set of widgets which have become almost essential to modern sites: modals, tooltips, button varieties, and notifications.  One problem I find is each site having their own widget colors, styles, and more -- users don't get a consistent experience.  Apparently the...

  • By
    JavaScript Copy to Clipboard with Branding

    I published a post a year ago detailing how you can copy to the clipboard using JavaScript.  The post was very popular and why would it be?  Copying content from a webpage without needing to use the default browser functions is awesome.  One trend I've...

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!