The Science of Web Art, Design and Development

It is not difficult to comprehend Payday loans Ownership of a bank account

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

Trackback URI

70 Comments

  • 1
    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
  • 2

    @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
  • 3
    Chuck says:

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

    Sunday, 30 March 2008, 9:31
  • 4

    @Chuck – You are welcome.

    Sunday, 30 March 2008, 10:19
  • 5

    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
  • 6
    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
  • 7

    @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
  • 8
    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
  • 9

    @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
  • Brendan says:

    Greetings!

    First of all, thanks for this code. It’s a great solution to the archive format.

    I’m working on integrating it into my site, and I noticed that hierarchical was set to 0. When I set it to 1 to include my sub-categories, I found that they were styled the same way as the parents.

    Is there a way to change the style of sub-categories so that they can be seen as children of other categories!

    Cheers,
    Brendan

    Sunday, 25 May 2008, 18:26
  • Allan says:

    Thanks for making that tutorial. It works great.
    Is there any way that I can add content in the regular wordpress fashion to the archive page besides hard coding it in to the template like it did with this page http://www.uscollectacoin.com/review-provo-index ?

    Saturday, 21 June 2008, 22:22
  • Searched for something like this a while ago, but could only find plugins, not plain, helpful code. Glad I looked again! Just what I needed at just the right time.

    I’ll try to remember to let you know when it’s up and running.

    Friday, 4 July 2008, 21:22
  • Elpie says:

    Hi Guilherme,
    I posted with my thanks back in April and thought I would let you know where I am using your code. You can see it in action here:
    http://mambo-tutorials.com/free-tutorials

    This page is accessed more frequently than the site map and analytics is proving that its a popular page for visitors. Thanks again for saving me a lot of time.

    Wednesday, 9 July 2008, 15:03
  • Using a variation of your code at haiku.kristarella.com/archive Got the Books list, which are categories themselves, then the chapter/post list after them and then the topics are categorised below that. Hard to get a good feel for it since there’s only a few posts there so far.

    Cheers!

    Tuesday, 15 July 2008, 19:16
  • Sarah says:

    Thank you for this useful piece of code! I was wondering whether or now it is possible to display the title of each post in alphabetical order under each category. Right now, it displays my post titles by Date, which is not what I was hoping for. If there is a solution, please inform me about it! Once again, thank you so much for coding this.

    Sunday, 10 August 2008, 7:22
  • Sarah says:

    Hey, I am back again. For the past few hours, I was searching for a solution to my problem of displaying my archive post in alphabetical order under each category instead of ordering the post titles by date.

    After a simple tweaking of the code, I edited the following line:
    get_posts(”numberposts=-1&category=$cat->cat_ID”)

    and replaced it with this code:
    get_posts(“orderby=post_name&order=ASC&numberposts=-1&category=$cat->cat_ID”)

    I am not an expert on PHP coding, so discovering this feels like a revelation for me. I am so dependable upon using other people’s code tutorials or plugins, so I feel good to have solved this problem myself. Thank you Guilherme Zühlke O’Connor for this lovely hack and I hope my contribution with this little tweak will be of some help to your visitors. Keep up the great work!

    Sunday, 10 August 2008, 8:49
  • Hi people, Sorry the blog was a bit abandoned in the last couple of months, I’ve been mostly offline for personal reasons.

    @Brendan –

    Is there a way to change the style of sub-categories so that they can be seen as children of other categories!

    There sure is. If there are, just go to your CSS and style it as you please. You have to target the LI elements of inside the LI for each parent category.

    Maybe the easiest way to go is to tweak the code so you insert a class to the parent element.

    Sunday, 10 August 2008, 9:47
  • @Allan –

    Is there any way that I can add content in the regular wordpress fashion to the archive page besides hard coding it in to the template like(…)

    I don’t think it is because we are adding some logic to the theme to automatically generate, not adding content properly. You need to handle some PHP to create a template, AFAIK.

    @kristarella –

    Just what I needed at just the right time.

    I’m glad it was useful ;)

    @Elpie –

    You can see it in action here:
    http://mambo-tutorials.com/free-tutorials (…) Thanks again for saving me a lot of time.

    Lovely!
    You are welcome.

    @Sarah –

    I am not an expert on PHP coding (…) so I feel good to have solved this problem myself.

    And you should!

    Thank you Guilherme Zühlke O’Connor for this lovely hack and I hope my contribution with this little tweak will be of some help to your visitors. Keep up the great work!

    Thanks for posting back your solution, it will surely be useful.

    Sunday, 10 August 2008, 9:54
  • Fuzzy says:

    I know this is an older post. But THANK YOU! I’ve been trying to find a walk-through to help me build an archive page for several days. This is the first one that I completely understood and that actually worked!!! Thank you so much

    Monday, 20 October 2008, 5:10
  • @Fuzzy – You are welcome.

    Monday, 20 October 2008, 11:46
  • Elpie says:

    Hi Guilherme,
    Just a suggestion for a small tweak to your code for XHTML validation compliance.

    // Show category description
    if ($cat->category_description != NULL) { /PHP
    category_description /PHP>
    PHP } /PHP

    Adding the brackets will prevent empty tags appearing in the output.

    Thursday, 30 October 2008, 22:16
  • Elpie says:

    Ugh – the editor messed with what I was trying to display, but essentially its an open { after NULL) and closing this after the closing paragraph tag /p
    I’m sure you get the picture ;)

    Thursday, 30 October 2008, 22:19
  • @Elpie –

    Hi Guilherme,
    Just a suggestion for a small tweak to your code for XHTML validation compliance.

    Thanks for pointing that out.

    Sunday, 2 November 2008, 15:24
  • mrlive says:

    I have followed the guide and make a category archive:

    http://mrlive.org/en/p-archives/

    The problem is that I used two language (qTranslate Plugin) so the title does not appear properly.

    I wonder if there is a way to fix it :-?

    Thanks so much.

    Tuesday, 11 November 2008, 2:56
  • Puanthanh says:

    Thanks alot

    What will be the code for- If I want to show it only for a category with some description of the psot

    Sunday, 16 November 2008, 20:41
  • @mrlive – I wonder if there is a way to fix it :-?

    I don’t know the plugin you are using for trasnlating, but apparently the information on square brackets is some form of meta-tagging not to be published. My guess is that you have to find out if this is a configuration you can switch of, if you are confident to do it, remove it from the code directly.

    @Puanthanh –

    What will be the code for- If I want to show it only for a category with some description of the psot

    Then stick for this bit and ignore the other properties other than the name

    if ($cat->category_description != NULL) ?>
    					

    < ?php echo $cat->category_description ?>

    Sunday, 23 November 2008, 3:01
  • You might also want to check out my plugns, collapsing categories and collapsing archives, which have some similar functionality
    http://wordpress.org/extend/plugins/profile/robfelty

    Friday, 13 February 2009, 22:37
  • IcedNyior says:

    hi there :) I hope you still reply to comments here. Im trying to use your code but I came across some problems.

    The categories show but the posts only shows the recent 5 posts, and it repeats under each category. Could I be doing something wrong?

    Thursday, 16 April 2009, 5:18
  • IcedNyior says:

    opps i forgot to add, You can see the example here http://voize.my/archives

    Thursday, 16 April 2009, 5:18
  • @IcedNyior –

    hi there :) I hope you still reply to comments here.

    Hi IcedNyiod, yes I do. I realised that there was a plugin causing conflict in this page and so it is likely that the code you copied doesn’t really make sense, if you can try now that it’s fixed, it should work. Let me know if the problem persists.

    Monday, 20 April 2009, 21:01
  • Drozdov says:

    It worked!!!! Really thanks!

    Monday, 20 April 2009, 22:57
  • Kate says:

    Hi Gui,
    First of all, thanks for the code! It was just what I was looking for. I’m thinking, though, (and I could be wrong)… but I believe the if statement may need to be fixed. Currently, as the code is, if there are no category descriptions it still outputs the paragraph. (Obviously not ideal. :) So, I changed it to this:

    if ($cat->category_description != NULL) {?>
    category_description ?>

    Anyways, thanks again! Take care.

    Friday, 24 April 2009, 15:18
  • Kate says:

    Hmmm…. let me try that again:

    if ($cat->category_description != NULL) {?>
    category_description ?>

    Friday, 24 April 2009, 15:21
  • Kate says:

    Nevermind! :) I keep messing it up! Plus I just saw Elpie’s comment from 30 October 2008, 22:16, which was in fact what I was suggesting too. Feel free to delete the extra comment(s). Take care. :)

    Friday, 24 April 2009, 15:24
  • @Kate – Hi Kate, thanks for your comments, I’m glad it worked for you. There are things that could be improved here, I’m glad when they are pointed out.

    Monday, 27 April 2009, 9:38
  • IcedNyior says:

    Thanks so much for fixing the code :) it works now.

    How do i display the total number of posts in the category though?

    Monday, 27 April 2009, 10:03
  • Awesome – just what I needed. Thanks for sharing a simple code snippet instead of making a bloated plugin with 100 unneeded features!

    Look for it soon at nudelrestaurant.com

    Thursday, 30 April 2009, 2:51
  • Good idea.

    Thursday, 30 April 2009, 3:23
  • Thank you SO much for this clear, simple code example! May the wind from my geek beanie propellor always cool your brow.

    Peace!

    http://www.coloradanmagazine.org/2009/03/

    Wednesday, 6 May 2009, 19:22
  • Batt-Girl says:

    10k u!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Wednesday, 17 June 2009, 13:07
  • Marksten says:

    Dude thank you very much for your code!
    I was searching for this to build a sitemap at the bottom of a website.

    Cheers!

    Monday, 6 July 2009, 19:20
  • gslondon says:

    Is it possible to use the plugin to display the archives exactly as the default wp archives, only difference is the categories are filtered to only the category you require? I have got this plugin running thanks to your tutorial but it isnt quite what I’m looking for.

    example of what I need…

    Page Category1

    (sidebar cat1)
    Jan 2009 (links through to show all posts under category1 for Jan2009)
    Feb 2009 (links through to show all posts under category1 for Feb2009)

    Page Category2

    (sidebar cat2)
    Jan 2009 (links through to show all posts under category2 for Jan2009)
    Feb 2009 (links through to show all posts under category2 for Feb2009)

    At the moment without the plugin I cannnot filter by category, so the sidebar links display ALL posts.

    With the plugin I can list by category/ date etc and link to a post but need to list by year /month and only display links for the selected category

    Reading thsi back I’ts confusing so I hope you get what I’m trying to do

    Thanks

    Thursday, 13 August 2009, 8:57
  • Thanks so much for this! It really got me back on the right track with a site that was feeling vaguely stubborn. Thanks so much for sharing your knowledge in such a clear and articulate way, and judging by the comments, I’m not the only one :D

    Friday, 5 February 2010, 0:57
  • Aaron says:

    Great tutorial!! With some tweaking and using the comments above I made it do exactly what I wanted! Thanks again!

    Thursday, 11 February 2010, 14:03
  • Thank for this, I don’t have yet a archive page for my blog this will help me a lot. keep it up.

    Friday, 12 February 2010, 7:51

Trackbacks

  1. The Blog Herald
  2. : News aggregator
  3. : News aggregator
  4. Morpho Designs » Blog Archive » Do You Remember the Ambient Orb Blog Index?
  5. Round WordPress: Summer of Code, Kubrick Retired, How Tos, WebWare 100, and WordPress Fan Blogs « Lorelle on WordPress
  6. HealthMatters | Round WordPress: Summer of Code, Kubrick Retired, How Tos, WebWare 100, and WordPress Fan Blogs
  7. » Round WordPress: Summer of Code, Kubrick Retired, How Tos, WebWare 100, and WordPress Fan Blogs
  8. Morpho Designs » Blog Archive » WordPress Site Maps – Three Ideas

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.
  • You are encouraged to link to your blog or personal site, but if you link to a commercial site, the link will be removed
  • If your comment is merely to promote a link to your site (AKA, spam), it will be removed altogether