10

(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)

1
  • 2
    Nice question and really appreciated your editing the title and question content it for clarity; it'll help others who have a similar question in the future. Commented Aug 25, 2010 at 21:04

3 Answers 3

14

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:

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="..">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="..">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/

8
  • 1
    Very nice. How would you set it up so that the tech specs, etc. information is dynamic (rather than hard coded, as in your example)? Commented Aug 25, 2010 at 1:55
  • 1
    That's a tricky question so I need to understand your use-case or if it's just an abstract hypothetical? I can do this because I know the finite list of potential matches. If it were "match anything" it would override WordPress' other match patterns. Give me a concrete example and I'll give a solution otherwise it's a can of worms. Commented Aug 25, 2010 at 4:11
  • Thanks for your wonderful answer. I had never dug into Custom Post Types before, and they seem like an ideal solution. I've updated my question with a few more specifics, mainly to do with sidebars/widgets
    – cannyboy
    Commented Aug 25, 2010 at 11:07
  • @mike Just a hypothetical. To elaborate - I'm wondering how you could set it up so the information on the (for instance) tech specs page is entered in the admin dashboard somewhere (a custom post type, maybe, using a taxonomy to set the car?), as opposed to in the template file. Commented Aug 25, 2010 at 13:29
  • @tnorthcutt - I assume when you say "information on the tech specs page" you mean "the list of sub-pages?" Or do you mean custom fields? If the latter I assumed that the information would be stored in custom fields. My example didn't show that; maybe it should have? Commented Aug 25, 2010 at 20:52
1

I think someone might have already kind of answered this on the other question you posted (about parent pages / intermediate pages), but here's what I think the best way to structure your data is, based on what you've described:

 - Home
 - Volvo 850 (overview)
   - Volvo 850 tech spec
   - Volvo 850 pictures
 - Porsche 911 (overview)
   - Porsche 911 tech spec
   - Porsche 911 pictures

That way you only have to enter the meta fields once - on the parent page - and on the children pages you can pull that meta data from the parent:

<?php echo 'Top speed: '.get_post_meta($post->post_parent,'Top Speed',true); ?>

Of course, an even better way to organize this would be to have one single custom post type for each model of car which stores all of the car's information, and display the various subpages based on a GET request that's passed to the page and used in the page template as a switch to determine which template to display. That way you can completely avoid duplicating data, and make it easier to add more information to template later on...

More details...

I've done it a couple different ways. In one site where I had agents (company reps) as a custom post type, I used their posts to store all the data related to that person, but never actually displayed that page. Instead, I had an "Agent Listing" page, a "Agent Performance Record" page, and a "Contact This Agent" page, which were always called with a GET variable and displayed information out of the appropriate post. So the permalink would look something like site.com/agent-listing/?agent=john-smith.

In another site , I set up all the information on one page and built all three views for that page into the page template. In your case, that would look something like site.com/cars/volvo-850/?pictures.

And in the page template you would include a check for that variable near the top of the content:

if ($_GET['pictures']) {

 // template for pictures page

} else if ($_GET['tech-spec']) {

 // template for tech specs page 

} else {

 // overview template

}
3
  • Thanks a lot! For your last suggestion, do you mean I create a blank page (called perhaps 'Volvo 850 Widget Data') which has all these Custom Fields, and the other Volvo 850 pages automatically grab this data (er, somehow)? (this means I have to construct menus manually in Appearance>Menus, which I'm doing anyway) ... Or perhaps the data can be grabbed from the Overview page's Custom Fields...
    – cannyboy
    Commented Aug 24, 2010 at 22:52
  • I've done it both ways. I edited my answer above to explain. What you end up doing depends a lot on how automated you want your menu creation to be, like you said. Commented Aug 25, 2010 at 1:28
  • Oops. I just read down further and realized Mike already answered exactly what I was saying. Commented Aug 25, 2010 at 1:29
0

If you don't want to create custom post types, and you simply want to include a custom sidebar for each page or post, you could use the Graceful Sidebar Plugin. This lets create custom sidebar content right from within the post or page edit screen using additional fields called graceful title and graceful content. These are then displayed in the sidebar area as a widget when this post or page is being displayed on your blog. More information on this plugin is available at http://www.mlynn.org/graceful-sidebar-plugin

Your Answer

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

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