Wordpress - Adding an Archive of Posts to the Navigation Menu in WordPress 3.0

@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:

http://example.php/products/

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:

<?php
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) {
      $q->the_post();
      ob_start();
      include($template_file);
      $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:

<?php
/**
 * 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(); ?>
  </div>
</div>

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)


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:

http://www.wordpress.org/extend/plugins/custom-post-permalinks/

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.