Create Custom WordPress Category/Archive Pages

When using WordPress as a content management system, you may find yourself in a situation where you want a parent page to show snippets from each of its child pages. There are a few ways you can go about this.

To begin with, obviously, you need to create the page that will show the list. This should be a standard WordPress page. For purposes of this article, let’s say this page has a title of “Parent.” Once you’ve created the “Parent” page, you can create each of the child pages. Make sure that you indicate each of those pages has “Parent” set as its parent.

Next, you will need to create some custom template files. I would recommend creating one template page called something like “children.php” that you can include where necessary. I would recommend copying the contents of your index.php template file (or whichever file you use to show normal archive/category pages). The top of “children.php” will look something like:

<?php
/* Store the ID of the current page as a separate variable */
$current_page_id = $post->ID;
/* Pull in the header template */
get_header();
?>

Then, just before the area where the loop usually goes within the template file, include the following code:

<?php 
/* Store our normal query in a temporary variable, since we will be temporarily overriding it */
$tmpquery = $wp_query;
?>

From here, you have three options as to how to proceed:

  1. Show the content above the <!--more--> quicktag in each page
  2. Show the full content of each page
  3. Show the “excerpt” from each page

To show only the content that appears above the <!--more--> quicktag, you will need to override the global settings for the current page. To do that, you should include the following code just below the code I showed above:

<?php
/* Override the fact that standard pages are set to show all content, rather than just the content above the "more" quicktag */
global $more; $more = 0;
?>

Next, you will need to run the query that will retrieve the child pages. The query shown in the code snippet below will only show direct descendants of the current page; it will not show content from deeper descendants. More information on the query_posts() function can be found in the WordPress codex.

<?php 
query_posts('orderby=title&order=ASC&post_type=page&post_parent='.$current_page_id); 
?>

Moving on, if you want to use either the first or second option I mentioned above, you’ll proceed with a standard loop, which might look something like:

<?php
if (have_posts()) : while (have_posts()) : the_post();
?>
<div class="post" id="post-<?php the_ID(); ?>">
<h2><a href="<?php the_permalink(); ?>">
<?php the_title(); ?></a></h2> <div class="entry">
<?php the_content('<p class="serif">Read more &raquo;</p>'); ?>
<?php wp_link_pages(array( 'before' => '<p><strong>Pages:</strong> ', 'after' => '</p>', 'next_or_number' => 'number' )); ?>
</div>
</div>
<?php endwhile; endif; ?>

If you would prefer to show the “excerpt” from each page rather than the content, you should replace the line that looks like:

<?php the_content('<p class="serif">Read more &raquo;</p>'); ?>

with:

<?php the_excerpt(); ?>

Once you’ve finished the loop, you probably want to restore the original query to make sure any other functions in your sidebar, footer, etc. run properly based on the real information for the current page. To restore the original query, simply use the following code after you close the loop:

<?php $wp_query = $tmpquery; ?>

Finally, what you’ll want to do is create a template file for each page that will act this way. For instance, in the example for this post, we created a page called “Parent” (which, presumably, would have a slug of “parent”). Therefore, we’ll create a PHP file called page-parent.php and upload it to our template directory (as described in the WordPress Template Hierarchy). The contents of this new template file are simply:

<?php require_once( TEMPLATEPATH . '/children.php' ); ?>

I believe there are plug-ins available that let you use specific templates for groups of pages, in which case you don’t need to create individual template files for each parent page. However, if you’ve only got a few parent pages with which you want to do this, it might just be simpler to create the individual template files the way I just showed.

Put it all together, and you’ve got a static WordPress page that will act like an archive or category page, showing the content or excerpt from each child page.

One Response

  • walter

    Hey this was VERY helpful for setting up a kind of product-site. One option would still improve the case: the possibility to control the depth. Is there still no way to do this with the query of wordpress?? Any idea?