The Science of Web Art, Design and Development

Tutorial: A category based archive on Wordpress

I followed Lorelle’s advice advice and added a category based archive on Zo’C’s archive page, and now I’m going to tell you how to create yours.

At the end of this post, you’ll find the complete code in a single piece.

Step 1: Create the template file and find the content area

The first thing to do is create a new template page for your theme. The easiest way to do it is by duplicating your default page template which is the file “page.php”. Login via FTP, SSH or your favorite method an copy that file to “category_archive.php” and start editing.

Edit your file so at the very beginning it has the following lines, they are responsible for telling Wordpress this is a template page and its name.

<?php
/*
Template Name: CategoryArchive
*/
?>

The reason why we copied the default page instead of starting from the scratch is that any theme has is peculiarities (footer, sidebar, header, this and that) and we want to preserve them all, we just want to change the content. So, now, you must find the content.

It is probably different on your theme, but in mine, I find content starts after this

<div id="main">
<div id="container">
<?php include("menu-sec.php"); ?>
	<div id="content">

And ends just before this

	</div><!-- content -->
</div><!-- container -->

<?php get_sidebar(); ?>
<div class="clearer"></div>
</div><!-- main -->

<?php get_footer(); ?>

Step 2: Find the categories and loop through them

Once you have located the content area let’s get to the PHP code to make the magic happen.

First you have to inquiry Wordpress for the categories

<?php $cats = get_categories("hierarchical=0"); ?>

Then loop through them and display them. Don’t forget to check for NULL entries: a sanity check. In case something goes wrong and no categories are returned the script will do nothing instead of crashing.

<?php if($cats != NULL) { ?>
		<ul>
		<?php foreach ($cats as $cat) { ?>
			<li>

			<?php if($cat != NULL) {
				$base_url = get_bloginfo('home') . "/category/" . $cat->slug; ?>
				<h3><a href="<?php echo $base_url?>"><?php echo $cat->cat_name?></a></h3>
			<?php } ?>

			<?php // Show category description
				if ($cat->category_description != NULL) ?>
					<p><?php echo $cat->category_description ?></p>

For each category, we are presenting the title and the description. Additionally, the category name is a link to the regular category listing page, so people can dig further on a category, if they want to.

Step 3: Find the posts filed under each category and display them

On each iteration of the loop above, besides presenting the category info, we need to query the posts filed under that particular category and display them. Start by querying Wordpress about the posts of the category you are in.

<?php $myposts = get_posts("numberposts=-1&category=$cat->cat_ID"); ?>

(UPDATE: get_posts parameters updated to avoid the default limit of 5 posts, thanks Chuck for pointing out the problem.)

And then, loop through them displaying its name and permalink. And, once we have our hands on it, lets add it a touch of class and display the date in which it was published.

<ul>
<?php foreach($myposts as $post) : ?>
	<li><?php the_time('M d') ?>. <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endforeach; ?>
</ul>

Don’t forget to close the outer loop:

<?php } ?>

Step 4: Create a page using the layout you just made

Selecting The TemplateNow that you have created a page template for your category based archive, you must create a page using it.

Go to the admin panel on your blog, to the write page interface and create your page normally, except that on the right panel, under “Page Template” you’ll chose “CategoryArchive”. Chose a nice Post Slug for it if you want and a descriptive title but you don’t need to put any content because it won’t show anyway.

The complete code to copy and paste

If you find it difficult to copy and paste all the pieces of this tutorial, here is the complete code that you can just copy and paste inside the content of your page template.

Just remember that this is NOT the complete template, as it changes from theme to theme, this is only the juicy part of it, enjoy.

<?php $cats = get_categories("hierarchical=0"); ?>

<?php if($cats != NULL) { ?>
		<ul>
		<?php foreach ($cats as $cat) { ?>
			<li>

			<?php if($cat != NULL) {
				$base_url = get_bloginfo('home') . "/category/" . $cat->slug; ?>
				<h3><a href="<?php echo $base_url?>"><?php echo $cat->cat_name?></a></h3>
			<?php } ?>

			<?php // Show category description
				if ($cat->category_description != NULL) ?>
					<p><?php echo $cat->category_description ?></p>

				<?php $myposts = get_posts("category=$cat->cat_ID"); ?>
				<ul>
				<?php foreach($myposts as $post) : ?>
					<li><?php the_time('M d') ?>. <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
				<?php endforeach; ?>
				</ul>
			</li>
	<?php } ?>
		</ul>
<?php } ?>

Who is using it

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Netvouz
  • DZone
  • ThisNext
  • MisterWong
  • Wists
  • Technorati
  • BlogMemes
  • Ma.gnolia
  • YahooMyWeb
  • Netscape
  • Slashdot
  • StumbleUpon

Related Posts

Trackback URI

28 Comments

  • Chuck says:

    Thanks for sharing the code snippet. It works well, but the only issue I’m having is the maximum number of posts retrieved for each category. Looks like get_posts only returns a max of 5 posts, which is the default. Any thoughts on how to list all posts (> 5) for a category?

    Saturday, 29 March 2008, 21:44
  • @Chuck - Oops, you are right, you should use this instead:

    get_posts(”numberposts=-1&category=$cat->cat_ID”)

    I’ve updated the post with this solution, thanks for pointing the problem out.

    Saturday, 29 March 2008, 22:59
  • Chuck says:

    That was simple… I should have known that. It works great now. Thanks again!

    Sunday, 30 March 2008, 9:31
  • @Chuck - You are welcome.

    Sunday, 30 March 2008, 10:19
  • I definitely have to create an Archive page myself. Your script will help me save some time. Thanks!

    P.S. I think you could add the Top Posts section to your Archive too. That way, more people will find their way to your best posts.

    Monday, 31 March 2008, 3:04
  • HERO says:

    I have to say THANKS A MILLION for this script. I’ve been searching for this exact functionality for weeks and have posted numerous requests on the wordpress forum to no avail. So thank you so very much.

    I’m wondering if there’s a way to display categories by category ID rather than alphabetically? Or even better, to display categories by ID in a predescribed order?

    Thanks again!

    Monday, 31 March 2008, 14:55
  • @Adrian | Rubiqube - You are welcome

    P.S. I think you could add the Top Posts section to your Archive too. That way, more people will find their way to your best posts.

    That is a nice idea, thanks for that.

    @HERO - You are welcome, I’m glad is useful.

    I’m wondering if there’s a way to display categories by category ID rather than alphabetically? Or even better, to display categories by ID in a predescribed order?

    Well, you can sort categories by id. You have two routes to do that. You can either make a direct request to the database and ask it to sort it by id, or you can sort it within the PHP code.

    The former is faster, but you might find yourself having to adapt it every time the database changes in newer versions, the second one is more general and more scalable.

    You can also use PHP to order based on a pre-stablished order of category names, instead of alphabetical.

    Monday, 31 March 2008, 16:08
  • HERO says:

    I know my way around PHP pretty well and do a decent job adapting existing code to my needs, but I’m useless when it comes to writing it. Is there any way I could talk you into showing us how you’d use PHP to order based on a pre-stablished order of category names as you mentioned?

    Thanks again so much. Even without the modifications this is working great. I’m using a set of custom fields to assign thumbnail images to each of my tutorials, and when I release my redesign and switch to wp 2.5 I’ll be including a gallery page using your script. I’ll drop you a line with the link later in the week.

    Monday, 31 March 2008, 20:13
  • @HERO -

    Is there any way I could talk you into showing us how you’d use PHP to order based on a pre-stablished order of category names as you mentioned?

    I might write a post about this in the future, why not?

    In the meantime, if you have a fixed list of categories, why not simply make separate calls to retrieve posts, one for each category?

    Monday, 31 March 2008, 21:29
  • Hi GUI,

    Thanks for sharing this wonderful tutorial.
    I fooling around with page templates and had just created my first one.

    Flush with the success :) of that experiment, I feel ready to try yours.

    Cheers,

    Mitch

    Wednesday, 2 April 2008, 6:49
  • @Mitchell Allen - I’m delighted to know. Good luck with your further experiments!

    Wednesday, 2 April 2008, 7:22
  • Whee! It worked!
    Thanks, GUI!

    Cheers,

    Mitch

    Thursday, 3 April 2008, 19:23
  • @Mitchell Allen -

    Whee! It worked!
    Thanks, GUI!

    Great! You’re welcome.

    Friday, 4 April 2008, 0:10
  • Drew says:

    Great Tutorial! Thanks!
    I agree with Hero (Comment #8). I’d love to see a tutorial on how to call only designated categories. OR, as you suggested in your follow up (Comment #9) how to call each category with it’s associated posts individually one after the other.

    Thanks again for this Tutorial, it works perfectly!

    Tuesday, 8 April 2008, 21:38
  • @Drew - You are welcome!

    I’d love to see a tutorial on how to call only designated categories. OR, as you suggested in your follow up (Comment #9)

    I’ll try to come up with this tutorial for one of my next posts.

    Wednesday, 9 April 2008, 2:25
  • UtahGuy says:

    i’m on board with the last two comments about the tutorial for loading only certain categories in the archive page. that would be awesome.

    thanks for all the hard work you do to make these tutorials. sometimes i think i should have become a programmer instead of a designer. so much to know, so little time.

    thanks again for sharing Guilherme.

    Monday, 14 April 2008, 12:30
  • @UtahGuy - You are welcome, UtahGuy, that tutorial will be made ;)

    sometimes i think i should have become a programmer instead of a designer. so much to know, so little time.

    You can be both, it’s never too late ;)

    Monday, 14 April 2008, 23:36
  • HERO says:

    I couldn’t wait any longer, so I read the wp codex for about 4 hours, and with a little trial and error managed to write a solution to exclude categories from the results.

    Replace this line:
    PHP $cats = get_categories(”hierarchical=0″);

    with this:
    $cats = get_categories(’orderby=name&exclude=13′);

    If you want to exclude more categories simply separate them with a coma.

    -HERO

    Saturday, 26 April 2008, 13:03
  • HERO says:

    Ahh, I recall in an earlier post I promised to include a link to the page where I used your brilliant script. You can find it here: http://pshero.com/gallery/

    Thanks again!

    Saturday, 26 April 2008, 13:15
  • @HERO - Thanks for your contibution, and consider yourself linked. I’ve just created a “who is using it” session on this post.

    Sunday, 27 April 2008, 4:14
  • Hi GUI!
    Adding the who’s using it is a nice touch. I discovered PSHero.com as a result. It is a beautiful site, even as it undergoes upgrading.

    I use your plugin, too. I’ve opted to use the dropdown menu approach, in order to declutter my sidebar.

    Cheers,

    Mitch

    Sunday, 27 April 2008, 11:45
  • HERO says:

    Hey G! Thanks for the mention in the Who’s Using It section!

    I discovered something cool about the script and modifications I posted above… if you use the term “include” instead of “exclude” you can make the page only include the categories you choose and none of the others. This way if you add more categories to your blog in the future, you won’t have to go back and modify the archive to exclude them!

    Thanks again man! This script is awesome!

    Monday, 28 April 2008, 5:33
  • Elpie says:

    Guilherme, thanks so much for posting this. You have just saved me a lot of time and angst writing my own (time is a rare commodity for me ;))
    It’s brilliant, works exactly as expected and is just what I was looking for. Thanks so much!

    Tuesday, 29 April 2008, 5:47
  • @Mitchell Allen - Hi Mitch, I think you are talking about the SubCats plugin, which you also use, but I’ve put you in the list of users of this template, since you are using it.

    PS Hero is great, I like it very much myself.

    @HERO - No Problem, I’m glad to show good work around. Thanks for your nice additions to the discussion.

    @Elpie - You are welcome, I’m Glad it’s being helpful.

    Thursday, 1 May 2008, 0:35
  • This was JUST what I needed! Thank you. By using the category descriptions, this makes a nice archive-by-category page. The only thing is, I try to keep my categories to a few core minimums, which means some of them are incredibly long.

    If you are so inclined, it would be great to see a way to view the most recent 20 or the top 20 in any category with a link to “read all” in this category.

    I’m a PHP idiot, so it’s not something I can do for myself — but I’m loving the stuff that I’m figuring out by following your tutorials!

    Tuesday, 13 May 2008, 16:26
  • @Angela Parker -

    If you are so inclined, it would be great to see a way to view the most recent 20 or the top 20 in any category with a link to “read all” in this category.

    That seems like a very good idea. I’ll give it a thought and see if I come up with such post in a near future.

    Wednesday, 14 May 2008, 6:47

Trackbacks

  1. The Blog Herald
  2. : News aggregator

Share your thoughts

(Comments are dofollow, but also moderated. Don't forget to check the box stating that you are human before you submit your comment.)

Reply New