Spring Sale! Save 30% on all books w/ code: PLANET24
Web Dev + WordPress + Security

WP Custom Fields, Part II: Tips and Tricks

[ Magnetic Fields ] As we have seen in our previous post, WordPress Custom Fields Part I, custom fields provide an excellent way to add flexible content to your posts and pages. By assigning various types of content to different custom fields, you gain complete control over when, where, and how to display the associated information. For example, sub-headings may be displayed in the sidebar, footnotes may be consolidated into a single region, post images may be displayed before the post title, and so on. In this follow-up article, we will review the basics of custom fields and then jump into a few custom-field tips and tricks.

Quick review of custom fields

Custom fields may be added when you create or edit any post, page, or custom post type. Each custom field consists of two variables, the key and its associated value. An example key would be “current mood”, and an example value would be “happy”. Each custom field remains associated with its corresponding post, but may of course be called outside of the loop and displayed anywhere via the theme template (e.g., sidebar, footer, et al).

There are several ways to retrieve and display custom field information on your pages. The first and easiest way uses the the_meta(); template tag, which always echoes an unordered list containing the attributes/values seen in the following example.

By default, <?php the_meta(); ?> gives us this:

<ul class='post-meta'>
<li><span class='post-meta-key'>Key 1:</span> Value for Key 1</li>
<li><span class='post-meta-key'>Key 2:</span> Value for Key 2</li>
<li><span class='post-meta-key'>Key 3:</span> Value for Key 3</li>
</ul>

Although this method is useful for general purposes, anything involving greater degrees of customization will require something a little more flexible. Fortunately, the get_post_meta() template tag provides the flexibility needed for advanced configurations. There are many ways to use this template tag, so let’s break away from the basics and explore some advanced tips and tricks.

Display values of a specific key

To loop through and display the values of a specific key, place the following within the loop of your choice, and change the “mood” value to that of your desired key value:

<?php echo get_post_meta($post->ID, 'mood', true); ?>

Display multiple values of a specific key

Each custom-field key may include multiple values. For example, if you listen to multiple songs during a given post, you may want to list them all with a key of “songs”. Then to loop through and display the multiple values for the songs key, we place the following code into the loop of choice:

<?php $songs = get_post_meta($post->ID, 'songs', false); ?>
	<h3>This post inspired by:</h3>
	<ul>
		<?php foreach($songs as $song) {
			echo '<li>'.$song.'</li>';
			} ?>
	</ul>

Notice the trick here: by changing the third parameter to “false”, we tell the function to return an array of the values for the specified key. A very handy trick for displaying multiple key values.

Display content only if a custom field exists

For cases when not all posts contain some specific custom-field key, use the following code to prevent unwanted, empty or incomplete markup from destroying the validity of your page:

// display an image based on custom-field value, if it exists

<?php $image = get_post_meta($post->ID, 'url', true);
	
	if($image) : ?>

	<img src="<?php echo $image; ?>" alt="" />

	<?php endif; ?>

Conditional display of custom-field data

Continuing with the previous technique, here is a basic code template for displaying a list of key values only if they exist:

<?php if(get_post_meta($post->ID, 'books', true) || 
	 get_post_meta($post->ID, 'music', true) || 
	 get_post_meta($post->ID, 'sites', true)
	 ): ?>

	<ul>
		<?php if(get_post_meta($post->ID, 'books', true)): ?>
		<li><?php echo get_post_meta($post->ID, 'books', true); ?></li>
		<?php endif; ?>

		<?php if(get_post_meta($post->ID, 'music', true)): ?>
		<li><?php echo get_post_meta($post->ID, 'music', true); ?></li>
		<?php endif; ?>

		<?php if(get_post_meta($post->ID, 'sites', true)): ?>
		<li><?php echo get_post_meta($post->ID, 'sites', true); ?></li>
		<?php endif; ?>
	</ul>

<?php endif; ?>

More conditional content based on custom-field values

Here’s another neat trick whereby custom-field values are used to determine which type of content appears on a page. In this example, we are checking the value of of a custom-field key called “hobbies”. Depending on the value of the hobbies key, different links are output on the page. Check it out:

<?php $value = get_post_meta($post->ID, 'hobbies', true);

	if($value == 'gaming') {
		echo '<a href="http://domain.tld/gaming/">Gaming Stuff</a>';
	} elseif($value == 'sleeping') {
		echo '<a href="http://domain.tld/sleeping/">Nap Supplies</a>';
	} elseif($value == 'eating') {
		echo '<a href="http://domain.tld/eating/">Dieting Advice</a>';
	} else {
		echo '<a href="http://domain.tld/">Home Page</a>';
	}

?>

Simplification and externalization

To clean up our source code a little, we can relocate the get_post_meta() function to the theme’s functions.php file. The immediate benefit here is one less parameter to include in the template tag. To do this, first place the following code into your theme’s functions.php file:

<?php function get_custom_field_data($key, $echo = false) {
	global $post;
	$value = get_post_meta($post->ID, $key, true);
	if($echo == false) {
		return $value;
	} else { 
		echo $value;
	}
}
?>

..and then call the function by placing this code in the desired location within your page template:

<?php if(function_exists('get_custom_field_data')) {
	get_custom_field_data('key', true);
} ?>

The only thing you need to edit here is the value of the “key” parameter, which should be the same as the key for which you would like to display value data. The second parameter is currently set as “true” so that the key value is echoed to the browser. To save the key value as a variable for further processing, change this parameter to “false”.

Streamlining attribute values

Using the same principle as described in the previous example, we can create a function that will streamline the display of custom-field images while providing localized control over their associated (X)HTML attributes. Given the typical example of a custom-field value containing a URL to a specific image, we create function whereby the image URL is retrieved and displayed along with a set of attribute values passed from the function call. We place this function in our theme’s functions.php file:

function get_attribute_data($key, $alt, $title, $width, $height) {
	global $post;
	$value = get_post_meta($post->ID, $key, true);
	if($value) {
		echo '<img src="'.$value.'" alt="'.$alt.'" title="'.$title.'" width="'.$width.'" height="'.$height.'" />';
	} else {
		return;
	}
}

We then place the following function call into the desired location within our page template file:

<?php get_attribute_data('image', 'Alt text for the image', 'Title text for the image', 150, 150); ?>

Once in place, this function first checks for the value of a custom-field key named “image”. If such a value exists, it is echoed to the browser within the requisite image ( <img> ) markup, which is also populated with the attribute values specified in the function call. The usefulness of this technique may also be applied to other types of custom-field values, such as links, lists, and so on.

Additional internal custom-field functions

In addition to the get_post_meta() function, there are three additional PostMeta functions that return arrays when used inside of the loop:

  • get_post_custom() — Returns array of key/value data for current post
  • get_post_custom_keys() — Returns array of key data for current post
  • get_post_custom_values($key) — Returns all values for a specific key for current post

Closing Thoughts

Hopefully at this point you have a clear understanding of how to implement custom fields. By generalizing the techniques described in this article and the previous tutorial, we may integrate virtually any type of content, associate it with any array of posts, and display the related content in segregated fashion according to the purposes of our design. Even better, using custom fields for particular types of content — featured images, footnotes, thumbnails, and other extra information — makes it easy to change the layout of your content on a sitewide basis.

References

About the Author
Jeff Starr = Web Developer. Book Author. Secretly Important.
SAC Pro: Unlimited chats.

55 responses to “WP Custom Fields, Part II: Tips and Tricks”

  1. SystemTraderFX 2009/03/12 7:33 pm

    Hi Jeff,

    I keep coming back to your blog because you just happen to have all the answers! ;)

    I have a question about your “Display multiple values of a specific key” section.

    In your example you have $songs, well what if I want to display “$songs” and another multiple value of a specific key called “$albums”?

    How would I put this loop together so that it would look something like:

    Song: Song 1
    Album: Album 1

    Song: Song 2
    Album: Album 2

    Your wisdom here would be greatly appreciated!

    Thanks for reading,
    -Ray

  2. SystemTraderFX 2009/03/12 8:03 pm

    Okay I figured out one way of displaying multiple values of multiple keys.
    I used a “for” loop with an array count to display each key value.

    Where I went wrong was using the example code in the article, which used a “foreach” loop.

    Just wondering if there is a more elegant solution though?

  3. @SystemTraderFX: Glad to hear you found a solution! Also thanks for following up with your second comment – much appreciated. Not sure if there is a more “elegant” solution.. as you know, with WordPress and code in general, there is almost always a “better” way of doing things. I can’t think of a better way of doing it off the top of my head (which unfortunately is all I have time for these days), but I will keep it in memory and report back if I find or think of something that could improve upon it.

  4. Thank you for both of these tutorials! I am just getting my feet wet with custom fields and found your writing to be quite easy to follow and very understandable for a noob like me. :)

  5. Jeff Starr 2009/03/29 8:03 am

    Absolutely my pleasure, Toby — thanks for the positive feedback! :)

  6. Great article! Thanks

  7. Scott Weber 2009/06/20 9:31 am

    I have a bunch of values for the same custom field name.
    I would like to display the custom fields in ascending alphabetical order.
    Right now they are showing in the order I entered them. Any ideas?

    Custom fields
    name – purchase, value – purchase-itunes
    name – purchase, value – purchase-amazon
    name – purchase, value – purchase-emusic

    here is the code I am using:

    ID, 'purchase', false); ?>
    <?php foreach($value as $value) {
              if($value == 'purchase-itunes') {
                   echo '<a href="#" rel="nofollow ugc">itunes (Mp3)</a>';
              }
              elseif($value == 'purchase-amazon') {
                   echo '<a href="#" rel="nofollow ugc">Amazon (Mp3)</a>';
              }
              elseif($value == 'purchase-emusic') {
                   echo '<a href="#" rel="nofollow ugc">emusic (Mp3)</a>';
              }
              else {
                   echo '';
              }
    } ?>

  8. Jeff Starr 2009/06/23 3:06 pm

    @Scott Weber: Are you referring to how the custom fields appear in the Admin area, or the order in which the values are output to the browser?

  9. David Rivers 2009/06/24 5:01 am

    @Scott Webber: Before your foreach statement add the following line:

    $value = array_unique($value);
    sort($value );

    First line will remove any duplicate entries (usually a good idea), second line will sort the array alphabetically. You can also sort in various other ways, just google ‘php sort’ and read about it at php.net.

    Hope this helps!

  10. Great tips!
    Thanks you very much, very helpful.

  11. Kappaluppa 2009/08/05 5:10 pm

    Thanks for the wonderful tutorial. Very easy to understand. Tho, I got a little bit lost at the streamlining attribute section… wasn’t sure why the function called into the page template didn’t use variables. Using your example will every image come up with the same alt & title tag. I know I’m missing something there. Hopefully by the time I need to use it, I’ll figure it out! LOL

    Thanks again for a very well written set of articles. I will check here first the next time I need to learn something… which happens to be get_option()

    ;)

  12. Jeff Starr 2009/08/09 5:48 pm

    @Kappaluppa: You can get unique alt and title attributes for each image by either including additional custom fields or placing all of your markup in the current post’s custom field. That’s the beauty of WordPress! :)

Comments are closed for this post. Something to add? Let me know.
Welcome
Perishable Press is operated by Jeff Starr, a professional web developer and book author with two decades of experience. Here you will find posts about web development, WordPress, security, and more »
.htaccess made easy: Improve site performance and security.
Thoughts
I live right next door to the absolute loudest car in town. And the owner loves to drive it.
8G Firewall now out of beta testing, ready for use on production sites.
It's all about that ad revenue baby.
Note to self: encrypting 500 GB of data on my iMac takes around 8 hours.
Getting back into things after a bit of a break. Currently 7° F outside. Chillz.
2024 is going to make 2020 look like a vacation. Prepare accordingly.
First snow of the year :)
Newsletter
Get news, updates, deals & tips via email.
Email kept private. Easy unsubscribe anytime.