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

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.

Read More

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?

Related posts

Leave a Reply

4 comments

  1. @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)

  2. 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.

  3. 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.

  4. 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.