Saturday, January 10, 2009

Using Custom Fields to create a dynamic sidebar

WordPress has the ability to allow post authors to assign custom fields to a post. This arbitrary extra information is known as meta-data. This meta-data can include bits of information such as:

  • Mood: Happy
  • Currently Reading: Cinderella
  • Listening To: Rock Around the Clock
  • Weather: Hot and humid

With some extra coding, it is possible to achieve more complex actions, such as using the metadata to store an expiration date for a post.

Meta-data is handled with key/value pairs. The key is the name of the meta-data element. The value is the information that will appear in the meta-data list on each individual post that the information is associated with.

Getting Custom Fields

To fetch meta values use the get_post_meta() function:

 get_post_meta($post_id, $key, $single);<br />
  • $post_id is the ID of the post you want the meta values for. Use $post->ID to get a post's ID.
  • $key is a string containing the name of the meta value you want.
  • $single can either be true or false. If set to true then the function will return a single result, as a string. If false, or not set, then the function returns an array of the custom fields.

Highly Customized Sidebar using Custom Fields and Categories Per-Post


I've used WordPress for a few years now, but currently I am in need of help of building custom sidebars on a per-post basis using information stored in custom fields and categories. I'm a web designer by trade, not a programmer, and have some experience with PHP but not enough to do what I need.

Setup
I'm currently designing a website that uses WordPress as a CMS and will be used by location scouts for potential movie and commercial shooting locations. Posts act in two ways: 1. as News (much like a blog) and 2. as an individual location.

Each individual location is categorized using the WordPress category system, however there are over 75 categories including children. Some locations may have up to 3 different categories. On top of that, each location also has a series of custom fields.

Intention
When an individual location is being viewed, the purpose of the sidebar is to feature two sets of 3+ locations: 1. via a category based on the posts categories and 2. locations nearby using a custom field stored in the post.

Since some posts may have up to 3 categories in all, I don't know how to narrow down the category to just one. For instance, the post may have the main category of House with children of Historic & Period 1950s. All I would want is to pull the House category when someone is viewing a home location and list other locations categorized under Houses in the sidebar.

The same is for the Custom Fields application. Here the intention is to pull the zoning area for the location and list other locations in the same zone.

So if I'm looking at a post for a particular location that is categorized under Gas Station and is located in Zone 1, I should see in the sidebar at least 3 other gas stations and 3 different locations in the zone 1.

Since each post is unique concerning a location, the sidebar must spit out specific information. I've tried to figure out the code, but can't make anything work correctly.

Try something like:

<?php $thumb = get_post_meta($post->ID, "post_thumb", true); if (!empty($thumb)) { ?><img class="alignright size-thumbnail" src="<? echo $thumb;?>" width="120" alt="Thumbnail image for '<?php the_title();?>'" /><? } ?>

Another way to handle this issue

I recently finished the redesign of my blog, The Humanaught, and as these things tend to - it came with a few forehead slapping mind scratchers.

The key one being that the design utilized the post’s footer to store comments. On many posts you wouldn’t even know there was a problem, however when I - on occasion - veer from my usual rambling and only write a tiny little blurb, the issue is evident.

Take, for example, a standard page layout. On one side (in my case, the left) you have your content, on the other you have your sidebar, and hanging out at the bottom you’ve your footer (fig. 1). If your content and your sidebar have a roughly equal amount of doodats in them, you’re golden - but when you short change your comment box, your sidebar extends its full length and makes everything look goofy

Digging into my WordPress template, I needed a dynamic way of determining the size of the content box. For this I threw the following code just above The Loop of my single.php and page.php pages.

<?php
$post = get_post(the_ID(), ARRAY_A);
$contlen = strlen($post[‘post_content’]);
?>

I come out of that with a variable ($contlen) that gives me the character count of my content. Now all I needed to do was pass that variable to my sidebar and use some conditionals (IF bla bla bla) to decide what should be displayed and what should be cut.

The problem with the standard WordPress template is that the <?php get_sidebar(); ?> that WordPress uses by default to load all the goodies in sidebar.php doesn’t pass variables defined in other areas of the template.

To fix this we change:

<?php get_sidebar(); ?>

to

<?php include (TEMPLATEPATH . ‘/sidebar.php’); ?>

Now any variables you set in single.php/page.php will carry over to sidebar.php.

Next up, we need to attribute some values to that prioritized list we made a bit earlier. We need to decide after what character count certain sidebar elements will be displayed. As this is all very much a “give or take” solution, figures will vary depending on things like font-size, the size of elements in the sidebar, etc. However, let’s use my numbers for the sake of … well… just because.

  • All - Search Box, Recent Posts
  • >1,000 - Badges
  • >3,500 - Recent Comments
  • >5,000 - Blogroll

To implement this, we just wrap the sidebar elements in IF statements:

<?php if (is_home() || $contlen > 3500) { ?>
<h2>Recent Comments</h2>
<ul>
<?php get_recent_comments(); ?>
</ul>
<?php } ?>

The IF statement simply says if it is the home/index.php (is_home()) or (||) our content’s length ($contlen) is greater than 3500, display this crap - otherwise, move along.

That about does it, but for the sake of re-illustration, here’s the conditional to display the blogroll:

<?php if (is_home() || $contlen > 5000) { ?>
<h2>Blogroll</h2>
<ul>
<?php wp_list_bookmarks(); ?>
</ul>
<?php } ?>

What this doesn’t take into account are pages that display things like search results, particularly if those results are few to none. But with some simple modifications, I’m sure you can adjust this method to suit your blog’s particular needs.

Technorati Tags: , , , , ,

blog comments powered by Disqus