Wordpress: Blog Posts on Pages
Posted on August 7, 2008
I spent about 3 days beating my head against a problem with this website. I’m using Wordpress as a CMS (Content Management System) and to power the Screaming Light blog, which means I have a combination of information arranged as pages and all of our blog posts.
Like so many people, I wanted to use pages to manage all the links and relatively-static info on my pages, I wanted Wordpress to handle the backend and hide most of the code (if possible), and I still wanted some of my static pages to include relevant blog posts. I finally beat the problem. I got pieces of the solution from a bunch of different places, so I’ve linked the ones I could re-locate here, but no one had the whole puzzle in one place.
The first step in the solution was to install a plugin that would allow the execution of PHP from within a page or post (I used Exec-PHP) and configure it properly. The website has ample documentation, so I’ll skip that explanation.
The second step was to write my own loop to pull and include the relevant posts, right in the text for each page. (With Exec-PHP, any code you put in a post or a page will execute – which of course plays hob with the Visual editor, so be sure to disable the dang thing. If you’re writing code, you don’t want to be using it anyway.) So what code do we put in there?
Well, we want to use “The Loop”, Wordpress-speak for any “while” loop that pulls posts from the database and displays them. The problem is, since we’re on a page instead of in a file which Wordpress expects to have posts on it, the default Wordpress loop isn’t available, so we’ll have to write our own.
Fortunetly, this is really easy, even if (like me) you don’t know much (any) PHP. (A good basic grounding in coding and algorithms helps though – at least you know what to look for, even if you don’t recognize it until you see it.) Here’s a tutorial and a link to the Wordpress Query Parameters:
Defining your own Wordpress Loop
Templeate Tags and Query Post Parameters
The Plugin Reveal IDs for WP Admin 2.5 makes creating custom queries a bit easier, by showing you the ID number for your categories, pages, and posts in the WP Admin pages.
So, here’s my method:
1. Create Page – obviously.
2. Create “static” content – the part of the page that’s always going to stay the same.
3. Create my loop, customizing the selection parameters to pull just the posts you want.
I wanted two things for this site: first, a listing of *only* the posts in the categories “Weddings” and “Portraits” to appear on those pages; and second, I want a third category, “Projects”, to appear on the Projects page, but *not* on the front page of the site.
Step two is the easiest. I open up my index.php template and search for the Loop.
<?php query_posts($query_string . "&showposts=3"); ?>
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<h1><a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a></h1>
The query_posts() is the bit we want to modify. Notice that the parameters used to pull the posts for this loop aren’t all in there (the $query_string bit is a call to an SQL variable set up somewhere else) – but the “&showposts=3″ seems to be added to that query_string by the period. So, simply modifying that line to read
<?php query_posts($query_string . "&cat=-14&showposts=3"); ?>
excludes category 14 (Projects) from our main page.
Step 2 done – now for step 1.
I’m going to skip over the process of creating a page and all the associated junk – that info’s widely available. What I want to do is add dynamic content – posts – to that page. So we’re going to assume you have some page, and that it currently looks like this:
[Some page content,]
[we don't care what,]
[ that won't change ]
[ very often ]
We want to add PHP for our custom loop right in the page, directly below this.
[Some page content,]
[we don't care what,]
[ that won't change ]
[ very often ]
------------------------
[ PHP for the loop ]
Notice I’ve used an <hr> tag to separate our blog posts from the page info – entirely optional, and depends on your design, obviously.
Here’s the code from that how-to I linked above:
<h3>Recent Articles</h3>
<ul>
<?php
$recentPosts = new WP_Query();
$recentPosts->query('showposts=5');
?>
<?php while ($recentPosts->have_posts()) : $recentPosts->the_post(); ?>
<li><a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a>
<?php endwhile; ?>
</ul>
And here are the important bits of the code, with explanatory comments interjected:
<?php
$recentPosts = new WP_Query();
$recentPosts->query('showposts=5'); ?>
This bit sets up a new query and defines it - here, it's showing the 5 most-recent posts.
?>
<?php while ($recentPosts->have_posts()) : $recentPosts->the_post(); ?>
<a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a></li>
<?php endwhile; ?>
This bit displays the posts we just got with our query - we won't be messing much with this bit.
The first bit is obviously the interesting one - especially the $recentPosts->query('showposts=5'); part. By changing showposts=5 to something else, we can define what gets shown. To display Weddings (category 12), I just change showposts=5 to cat=12, like this:
$recentPosts->query('cat=12');
The possibilities here are infinite; go read the Template Tags Codex site for more of them. You can pretty much pull any content you want, from a single post by ID to every post ever written.
I could stop here, but I want to show the line beneath each post too, so I reach into my index.php file again and crib heavily on the formatting. I wind up with:
[ Some page content, ]
[ we don't care what, ]
[ that won't change ]
[ very often ]
------------------------------------------------------
<?php $recentPosts = new WP_Query();
$recentPosts->query('cat=12');
while ($recentPosts->have_posts()) : $recentPosts->the_post(); ?>
<h1><a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a></h1>
<p>Posted on <?php the_time('F j, Y'); ?></p>
<?php the_content(__('Read more'));?>
<div id="meta"></div>
<?php endwhile; ?>
And that's it - how to add posts to otherwise-static pages. The formatting bits I've largely neglected to explain, but basically, anything you put between <?php $recentPosts->query('cat=12'); and
while ($recentPosts->have_posts()) : $recentPosts->the_post(); ?><?php endwhile; ?> will be repeated for every post pulled.
Technical Note: This (or in fact, *any* category sort) will not work if the Simply Exclude Plugin is enabled. Don't ask me why.


Nice helpful blog. but i still have an issue that i have not been able to resolve yet, how do i show different posts or categories in different pages, do not want the pages to be static, is this possible
if you’re not interested in showing static info above the posts, or don’t mind editing the code directly to change that static info, you can just use category templates, as described here:
http://codex.wordpress.org/Category_Templates
I like using static pages instead of category templates because, in addition to the reasons mentioned above, this method allows me to set up a category template that applies to category listings (and individual posts in that category, thanks to the Force Category plugin) without including the static info at the top of the page every time that template is called.
I am trying to create exactly this, but I get a better understanding from reverse engineering php than starting from scratch. Perhaps you can link a downloadable example?
Never mind, I managed to figure it out. Your tutorial is very nice. Thanks!
That´s a great thing! Now I can use posts on pages. Thank you for the tutorial. After a little bit of adapting, everything runs fine.
Thanks for the article! In conjuction with http://codex.wordpress.org/The_Loop I realize now that we can’t have a loop within a loop without calling WP_Query a 2nd time.
One note: I copied and pasted your code, and got an error. Then I realized the single quotes were the wrong character. You may want to make sure all the single quotes in the code examples are actually single quotes. Here’s an example: $recentPosts->query(’cat=12′);
Thanks again!
Thanks for the note Philip! I’ve run into this before; it’s the Wordpress smart quotes replacement filter. I think I got around it by replacing the single-quote charecter in the code with the ampersand shortcode for it, '
Thanks for solving that one for me. Fantastic.
Thanks for the tutorial. It puts my posts on my pages, but I wanna know if there’s a way for the page to include plain text from the page I’ve written in wordpress (not in the code) aswell. Any ideas?
@Lina – If you put the text above the loop code (where I have the [static content] in the tutorial) it should put the plain text above the posts on the page.