Hay all, I'm playing around with WordPress 3.0 and two (2) of the new features, Custom Post Types and the Menu Editor.

I've started off by creating a new post type called "products", as you've guessed, this list products.

I'm using the bog standard template and I'm creating a new menu to replace the top nav. As far as I can see I can only add certain "products" to it, I cannot add a "archive" of products. What I'm trying to do is add a link to the menu to go to a page which lists ALL products.

Any idea how to do this?

4 Answers 4


@dotty As you can see by this trac ticket: There should be index pages for custom post types so obviously the need has not yet been addressed in WordPress core.

Both @John P Bloch and @Chris_O give you good alternatives; I'm going to give you a 3rd.

A "Products" Page

First Create a Page for your Custom Post Type and call it "Products". That will give it the following URL:


A "Products List" Shortcode

Next create a Shortcode that you can embedded into your "Products" page. In my example I called it [product-list]. Here's a screenshot of what using it would look like:

A Product's Page that uses a Shortcode to display a list of Products in WordPress
(source: mikeschinkel.com)

Note that such a shortcode would be a great candidate for adding lots of optional functionality and enabling it to work for many different post types but in the interest of clarity I pretty much hardcoded everything. You can of course use it as a starting point for your own shortcode:

add_shortcode('product-list', 'my_product_list');
function my_product_list($args) {
  $save_post = $GLOBALS['post'];  // Save state so you can restore later
  $post_type = 'product';
  $template_file = get_stylesheet_directory() . "/post-{$post_type}.php";
  if (!file_exists($template_file)) {
    return "<p>Missing template [$template_file].</p>";
  } else {
    global $post;
    $q = new WP_Query("showposts=10&post_type={$post_type}&orderby=title&order=ASC");
    $rows = array();
    $rows[] = '<div class="post-list ' . $post_type . '-post-list">';
    global $post_list_data;
    $post_list_data = array();
    $post_list_data['post_count'] = $post_count = count($q->posts);
    foreach ($q->posts as $post) {
      $rows[] = ob_get_clean();
    $rows[] = '</div>';
    $GLOBALS['post'] = $save_post;
    return implode("\n",$rows);

A post-product.php Theme Template File

Next you'll need to create a theme template file that only displays one product. The function that implements the shortcode names the template file post-product.php and here's a good starting point:

 * post-product.php - File to display only one product within a list of products.
<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
  <h2 class="entry-title"><?php the_title(); ?></h2>
  <div class="entry-content">
    <?php the_content(); ?>

Add the Menu Option

Last you'll want to add the menu option. This is very straightforward as you can see from this screenshot (the following assumes you've done nothing with WordPress 3.0 menus before and that you are using a theme that supports WordPress 3.0 menus such as Twenty Ten):

  1. Select the menu option in the admin menu.
  2. Click the "+" to add a new menu.
  3. Type in your menu name, whatever you like.
  4. Click the "Create Menu" button (the screen shot shows "Save Menu" but it will be "Create Menu" when adding.)
  5. Select your new Menu as your "Primary Navigation".
  6. Select your "Products" page.
  7. Click "Add to Menu"
  8. Click "Save Menu"

Adding a Products Page Menu Option to a WordPress Site
(source: mikeschinkel.com)

Finally, the Output

And here's what a basic product listing might look like:

A List of Products using a Custom Post Type in WordPress
(source: mikeschinkel.com)

  • The question left out is how to modify the products menu entry so it provides a submenu with all products.
    – hakre
    Aug 24, 2010 at 0:16
  • @harke Updated. Aug 24, 2010 at 2:55
  • well that was not a request :). I just wondered how the drop-down becomes automatically created and I think that's still not avail. But as written, that's not an request.
    – hakre
    Aug 24, 2010 at 9:41
  • Hi, I have a problem with this and hope you could help. The problem is current-menu-item class is not applied on products' li Jun 10, 2011 at 2:12
  • Missing images. :/
    – fuxia
    Jul 21, 2012 at 20:41

This is not natively supported by WordPress. However, you could add this to your functions.php file and it would work:

function give_me_a_list_of_products(){
  add_rewrite_rule( 'products/?$', 'index.php?post_type=products', 'top' );

add_action( 'init', 'give_me_a_list_of_products' );

That will give you example.com/products/ as a list of products. From there, you just add a custom link to your menu.

However, if you want true archiving (by month, year, etc.) with feeds, you need more detailed code. If your 'products' are a non-hierarchical post type (seems like they should be), you can use my plugin:


That gives you extra fields to customize your permalinks (like you can with blog posts), and will give you the ability to customize permalinks based on category, author, month, year, post type, etc.

  • Thanks for some great info here. I am looking for the same thing but although everything is working fine with the rewrite I am stuck because when I add the custom link to the menu the public website does not seem to change the css indicating a visitor is on that page. Could you please let me know how this is done so I can show the menu item in the "on" state if your within the "products" archive? Oct 14, 2010 at 1:48
As far as i can see i can only add certain "products" to it, i cannot add a "archive" of products. What I'm trying to do is add a link to the menu to go to a page which lists ALL products. Any idea how to do this?

You would need to assign a taxonomy to the "products" post type then add the taxonomy term to one of your custom menus which would then take the user to an archive page of all products under the taxonomy used.

Example I have a custom post type called "Jobs" with a taxonomy labeled "positions" alt text

If I wanted all jobs with the "Current Openings" taxonomy term I would select it and add it to the menu. alt text

If you need to have all your "products" post types on the archive page you could assign a parent taxonomy to all of them so they could all be listed on the archive page.

  • @Chris_O: This is one way, but not the only way and also requires a fair amount of effort to maintain the categorization by the user. JMTCW anyway. Aug 23, 2010 at 19:44
  • Makes sense. Hopefully the custom post type index page will be addressed in core.
    – Chris_O
    Aug 24, 2010 at 0:53

I think, it is an better solution to create via custom post type an post type Archive and move the archived posts in this archive. Also add the current post_type to the postmeta of this new post_type for undo this. I have write a plugin for this and current you can see this, without stylesheets, images and language file, on gist.github/978690.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.