Custom Post Type Data in Sidebar widgets?

(note: this question was originally about Custom Fields, but @MikeSchinkel had a better solution involving Custom Post Types)

On my site I have several pages which I want to show the same data in the sidebar.
For instance, in a structure like this:

-Home
-Cars 
 -Volvo 850 overview 
 -Volvo 850 tech spec 
 -Volvo 850 pictures
 -Porsche 911 overview
 -Porsche 911 tech spec
 -Porsche 911 pictures
-Roads 
 -Route 66 overview 
 -Route 66 history 
 -Route 66 pictures
 -Pan-American Highway overview
 -Pan-American Highway history
 -Pan-American Highway pictures

I would like all the Volvo 850 pages to show the same data in the sidebar, all the Porsche pages to show a different set of data (for instance Speed, Maker, etc).

The Road pages would have their own set of data for each road. Cars and Roads would also have there own page template, and the way I figure it would get the right sidebar is something like this within sidebar.php:

if ( is_page_template('car-profile-template.php') ) :
// show car widgets

Here’s an example page, the Volvo 850 Pictures page. The same (left) sidebar should appear on the other Volvo 850 pages, while the stuff on the right is just page content.

|  Home   •Cars   Roads                                |
--------------------------------------------------------
|   Overview     |     Volvo 840 Pictures              |
|   Tech Spec    |    (some pics)                      |
|  •Pictures     |                                     |
------------------                                     |
| -Specs-        |                                     |
| Volvo 850      |                                     |
| Speed:150mph   |                                     |
| Maker:Volvo    |                                     |  
| Download PDF   |                                     |
------------------                                     |
| -Rating-       |                                     |
| Style:3        |                                     |
| Safety:5       |                                     |
| Reliablity:4   |                                     |
------------------                                     |

In this example, the two sidebar widgets, Specs and Rating should be getting their info from a Custom Post Type. Is there a method, which would be easy for the end-user to edit, which means that they would have to enter this custom data only once? It may not be necessary for each of the fields to be separate (ie all of Spec could be entered within an Editor field, and all of Rating could be put in Excerpt field.. maybe)

3 s
3

UPDATE:

Based upon the update of the question I think I need to explicitly state that what is asked in the question can be done with the answer below, just used custom fields in the “Car” custom post type for each of the items you want displayed on all pages for a given car.

If you want to do it simply just hardcode the sidebar into the single-car.php template file I included below and then use your if statement to determine which content to display for the different URLs. You could go to the effort to widgetize your sidebar and develop a custom widget where the widget would pull the information for the current post ID, but why both unless you are building this as a theme for other people to use?

There are actually a bunch of subtly different ways to accomplish this but the one I am suggesting should wonder wonderfully for your needs.


Hi @cannyboy:

I actually don’t know what the best way would be to share custom fields across posts. But that might just be the red flag you need. If something seems too hard maybe…

An Alternate Approach?

…you could shonsider architecting it differently? I think you’ll be much better off creating a Custom Post Type of “Car” and then you can store everything for each “page” into the one Car post type. Here are some sample URLs:

http://example.com/cars/volvo850/  <-- overview
http://example.com/cars/volvo850/tech-specs/
http://example.com/cars/volvo850/pictures/

Learning about Custom Post Types

You can learn more about Custom Post Types at the answers to these questions:

  • Tips for using WordPress as a CMS?
  • Can a CrunchBase.com clone be implemented using WordPress?

A Custom Post Type and A Rewrite Rule

To implement Custom Post Types and the multiple pages you’d use code like the following which registers your “Car” Custom Post Type and then sets a rewrite rule for your car pages. Put this code in your theme’s functions.php file or in a plugin, whichever you prefer:

<?php
add_action('init','car_init');
function car_init() {
  register_post_type('car',
    array(
      'label'           => 'Cars',
      'public'          => true,
      'show_ui'         => true,
      'query_var'       => 'car',
      'rewrite'         => array('slug' => 'cars'),
      'hierarchical'    => true,
      //'supports'        => array('title','editor','custom-fields'),
    )
  );
  global $wp,$wp_rewrite;
  $wp->add_query_var('car-page');
  $wp_rewrite->add_rule('cars/([^/]+)/(tech-specs|pictures)','index.php?car=$matches[1]&car-page=$matches[2]', 'top');
  $wp_rewrite->flush_rules(false);  // This should really be done in a plugin activation
}

A Car-specific Theme Template File

Then you’ll need a Car-specific template file in your theme; the default name for this would be single-car.php. I’ve coded a starter template for you that renders all three of the URLs (the (overview), ‘tech-specs’ and ‘pictures’) in one template by using an if statement to determine which content to render:

<?php get_header(); ?>
<div id="container">
  <div id="content">
  <?php if ( have_posts() ): the_post(); ?>
    <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
    <h1 class="entry-title"><?php the_title(); ?></h1>
    <div class="entry-content">
<?php if(is_car_techspecs()): ?>
  <a href="https://wordpress.stackexchange.com/questions/858/..">Back</a>
  <h1>Tech Specs</h1>
  The tech specs go here!
  <?php get_post_meta($post->ID,'_car_tech_specs'); ?>
<?php elseif (is_car_pictures()): ?>
  <a href="https://wordpress.stackexchange.com/questions/858/..">Back</a>
  <h1>Pictures</h1>
  Car Pictures go here!
  <?php get_post_meta($post->ID,'_car_pictures'); ?>
<?php else: ?>
  <ul>
    <h1>Overview</h1>
    <li><a href="tech-specs/">Tech Specs</a></li>
    <li><a href="pictures/">Pictures</a></li>
  </ul>
  <?php the_content(); ?>
<?php endif; ?>
      <?php the_content(); ?>
    </div>
  <?php endif; ?>
  </div>
</div>
<?php get_sidebar(); ?>
<?php get_footer(); ?>

Note in the example above I’m being very simplistic with the use of get_post_meta(); real site would need to have a lot more complexity there.

Template Tags a.k.a. Helper Functions

Of course I used some template tags a.k.a. helper functions to minimize complexity in the template file in the if statement conditions. Here they are and you can put these in your theme’s functions.php file too:

function is_car_techspecs() {
  global $wp_query;
  return is_car_page('tech-specs');
}
function is_car_pictures() {
  global $wp_query;
  return is_car_page('pictures');
}

function is_car_page($page) {
  global $wp_query;
  return (isset($wp_query->query['car-page']) && $wp_query->query['car-page']==$page);
}

Screenshots filled with Custom Post Type Love

Once you have all that code in place and you’ve added a Car post like Volvo 850 you can get it to work like the following screenshots:

Overview Page

http://example.com/cars/volvo850/
(source: mikeschinkel.com)

Tech Specs Page

http://example.com/cars/volvo850/tech-specs/

Pictures Page

http://example.com/cars/volvo850/pictures/

Leave a Comment