WordPress Custom Fields, Part II: Tips and Tricks

Posted on December 22, 2008 in WordPress by

[ Diagram: Electric Field ] 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 page or post. 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 or page, but may of course be called apart from the loop and displayed anywhere on the page.

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 this 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 an array of all key/value data for current post
  • get_post_custom_keys() — Returns an array of all 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

Related articles

55 Responses

  1. [ Gravatar Icon ] Erika says:

    This is awesome! Printing it out and sticking it in my WP binder. :)

  2. [ Gravatar Icon ] dekora says:

    It’s a good and complete guide. I always use custom fields for SEO-purposes in order to change meta-values (title, desc, kw’s etc..) in the header accompanied by a default fall back if no value is entered.

    I think people would ask less questions on the Wordpress forums if there we’re a more simple and to the point guide like this. So much can be done with custom values. :)

  3. [ Gravatar Icon ] Hedley says:

    Thanks for the tips! I am just experimenting with custom fields for the first time, and I wonder if I can ask you a question:

    I am rebuilding a site for someone in which a small number of editors post articles from a number of different writers. Most of those writers are NOT registered users, but a few are. As I want the real author of the article to show up on he post, not the creator of the post, I use custom fields to specify the writer (name=”author”, value=author’s actual name). Then, in my theme files, I replaced:

    <?php the_author_posts_link(); ?>

    with

    <?php if ( get_post_meta($post->ID, 'author', true) ) { ?><?php echo get_post_meta($post->ID, "author", $single = true); ?><?php } ?>

    So far so good. In any post that has a custom “author” field specified, the pseudo author is displayed instead of the post creator. However, in posts in which a pseudo author has not been specified, no author shows up on the post at all. This is understandable, since there is no code to call it. I could just populate the custom field n every post, but I want posts created by writers who are registered users to show up normally, for the hyperlink. Is there a method of testing the condition using an “else” after the “if” so that I can tell it to use the old code if there is no custom field?

    Thanks!

    HB

  4. [ Gravatar Icon ] Stephen R says:

    Three words:

    More Fields plugin.

    Two more words:

    Nice article ;-)

  5. [ Gravatar Icon ] Jeff Starr says:

    Thank you all for the great feedback! Sorry it took so long to reply — we have been extremely busy moving into our new home (our first!), so things have been a little chaotic around here recently and it is taking ahwile to get caught up again with everything. Thanks so much for the comments — they are greatly appreciated! Cheers and Happy New Year to everyone! :)

  6. [ Gravatar Icon ] Randa Clay says:

    You rock! Thanks so much for posting such helpful solutions. I found exactly the help I was looking for here.

  7. [ Gravatar Icon ] Jeff Starr says:

    My pleasure, Randa - glad to be of service! :)

  8. [ Gravatar Icon ] 4500 says:

    ID, 'mood', true); ?>

    Thanks! That’s exactly what i was looking for :)

  9. [ Gravatar Icon ] Leon Poole says:

    Thank you - With the help from your post I’ve finally been able to set up post thumbnails on my blog. :)

  10. [ Gravatar Icon ] Jeff Starr says:

    @Leon Poole: Thanks, man — you just made my day! :)

  11. [ Gravatar Icon ] Dave says:

    This post is really useful. I knew custom fields were powerful, but never quite knew how to use them. I currently use custom fields to pull three images from a page, and display them on every page. Could I set up a custom loop to do the following:

    1. look to see if a custom field image_$i exists, and insert the data for it (where $i initially == 1)
    2. $i++ to increase the value to 2
    3. Look for a second custom field image_$i, and insert the data for that.
    4. keep looping through the custom fields until there is no image_$i (For example if it reaches image_5, but there is no custom field image_5)

    This is a great post, I will be subscribing to your blog immediately!!

    Good work!

  12. [ Gravatar Icon ] Jeff Starr says:

    @Dave: Yes, I would certainly think that such a configuration is possible, and if not, there are always a million ways to make it happen with WordPress. In fact, I usually find that there is always an easier, more efficient way of doing things. Thanks for subscribing, and for the positive feedback, btw — much appreciated! :)

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

  14. 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?

  15. [ Gravatar Icon ] Jeff Starr says:

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

  16. [ Gravatar Icon ] Toby says:

    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. :)

  17. [ Gravatar Icon ] Jeff Starr says:

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

  18. [ Gravatar Icon ] Chad says:

    Great article! Thanks

  19. [ Gravatar Icon ] Scott Weber says:

    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">itunes (Mp3)</a>';
              }
              elseif($value == 'purchase-amazon') {
                   echo '<a href="#" rel="nofollow">Amazon (Mp3)</a>';
              }
              elseif($value == 'purchase-emusic') {
                   echo '<a href="#" rel="nofollow">emusic (Mp3)</a>';
              }
              else {
                   echo '';
              }
    } ?>

  20. [ Gravatar Icon ] Jeff Starr says:

    @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?

  21. [ Gravatar Icon ] David Rivers says:

    @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!

  22. [ Gravatar Icon ] Maor says:

    Great tips!
    Thanks you very much, very helpful.

  23. [ Gravatar Icon ] Kappaluppa says:

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

    ;)

  24. [ Gravatar Icon ] Jeff Starr says:

    @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! :)

  25. [ Gravatar Icon ] Kathy says:

    I am having problems with the foreach.
    I am using the example for displaying multiple values of a key and I get this error:
    Warning: Invalid argument supplied for foreach()

    for the life of me, i can’t figure it out! Please help…

  26. [ Gravatar Icon ] Kathy says:

    well, i found a solution for the invalid argument error. But I don’t know why its necessary. I just know it works. I had to add (array) in front of the get_post_meta:

    $affiliates = (array)get_post_meta($post->ID, 'affiliates', $single=false);

    Now I have a different problem! the custom field values are being pulled from ALL posts, not just the values from the current post. Any ideas on that?

    THanks!

  27. [ Gravatar Icon ] Kathy says:

    PS
    well, i do know why, actually. I was told that without that (array) in front of the get_post_meta the foreach did not know it was an array. I’m using WP2.7 could that be the problem?

  28. [ Gravatar Icon ] Toure says:

    Hi, I am looking for a way to display many images based on custom fields.
    I am working on a type of Image gallery where a post will have multiple images and I just don’t wanna have to insert them withing the post directly.
    Any help will be appreciated.
    By the way, I am modifying the theme “No-frills 2.1.7 by Jess Kim”

  29. [ Gravatar Icon ] toure says:

    Hello,
    Is there a way to have multiple custom field images of a post?
    Could anyone guide me on that please. I just don’t wanna use the gallery tag of wordpress.
    I am looking to be able to continually add images to a post based on custom field.

  30. [ Gravatar Icon ] David says:

    @toure: To insert multiple images using custom fields, add a new custom field name ‘image’ and URL of image as value. Do this for all images needed in the post (add another custom field called ‘image’ for each image). You can upload the images using the add image part of WordPress, then copy the link URL and paste it into the value of custom field.

    To add the images to your post template file, open ’single.php’ and add the following code where you want the images to appear:

    <?php $images = get_post_meta($post->ID, 'image', false); //get each custom field 'image' and store as array $images ?>
    <?php if($images != '") { // if we have images ?>
    <?php foreach($images as $image) { // start looping through images ?>
    <img src="<?php echo $image; ?>" alt="" /><?php // display the image
    <?php } // stop looping here ?>

    Hope this helps!!

  31. [ Gravatar Icon ] David says:

    Sorry there is an error with above code, third line should be:

    <?php if($images != "") { // if we have images ?>

    Used ' instead of " Sorry!

  32. I have been experimenting with using custom fields but I had a co-worker insist to me that using them is a huge server problem because each one is a totally new sql call. Have you experienced any slowing after implementing custom fields?

    Thanks!

  33. [ Gravatar Icon ] Jeff Starr says:

    @Bryan Markham: As with many WordPress designers, I have been using custom fields on many sites with absolutely stunning performance. It all depends on how they are used, server configuration, software, plugins, etc. I don’t think a few custom fields are going to destroy the performance of any site that isn’t already slow to begin with. I would like to see the actual data supporting such a claim.

  34. [ Gravatar Icon ] Lori says:

    What a great tutorial! Thank so much for taking the time to put this together, as I can see that it has helped a number of people, including us beginners!

    I wonder if you could take just a bit more time to answer a question for me regarding using custom fields with NextGen Gallery. I’ve included various slideshows on different pages of my site using the key ‘gallery’ with value slideshow on each page. I had to edit both the gallery.php and my page template file to create this custom field.

    My slideshow shows up in a div on the left side of the page (http://tomasi-design.com/?page_id=7). I would like to somehow automatically pull in the gallery title and gallery description into the div on the right side based on the slideshow that shows up on that page.

    I’m hoping this can be achieved with a custom field, but try as I may, I can’t figure out the correct code to place in that right div!

    Any guidance is appreciated.

  35. [ Gravatar Icon ] Maddy says:

    Hi,

    I use custom field in my site to get certain pictures and videos and such themes are available in abundance. However, I would like to use the mail feature to update my posts regularly. Now, I am failing to understand how should I be sending across the custom field name/value pair via mail and get the picture/video published right?

    I actually follow up your blog very regularly … and wondering if you have a solution?

    Cheers!

  36. [ Gravatar Icon ] Jeff Starr says:

    @Maddy: Not possible with WordPress at this point, but there may a plugin hiding out there somewhere that might do it. Haven’t heard of anything specific though. Good luck.

  37. [ Gravatar Icon ] Cole says:

    This has been incredibly helpful - you have no idea! I truly appreciate it

  38. [ Gravatar Icon ] Garrett says:

    I’m just starting to understand the power of custom fields and your post is really helping. Thanks!

  39. [ Gravatar Icon ] Richard says:

    Thanks for very much for this tutorial. It’s excellent.

    I wonder if I could ask you a perhaps arcane question please.

    What’s the difference between:

    <?php echo get_post_meta($post->ID, 'myImage', $single=true) ?>

    and

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

    In other words, what difference does adding the “$single” make to the calling of the custom field? I ask because I’m comparing your really helpful tutorial with the Doc4 tutorial for Flutter (http://www.doc4design.com/articles/flutter-basic-usage) and notice this difference. I’m not sure of the distinction.

    Any help much appreciated.

    Kind regards
    Richard

  40. [ Gravatar Icon ] Jeff Starr says:

    @Richard: great question. All I know is that the two statements are functionally identical, however you should refrain from restating the variable name when passing a value in the argument (as in your first example). Stick with just the value instead, especially with WordPress functions ;)

  41. [ Gravatar Icon ] Ranadeep says:

    I have a query about the multiple custom field values. How can I combine 2 multiple values? As in, if I need to insert 5 photos with the custom field “photo” and 5 links with the custom field “link” - each photo to be linked in order e.g. photo1 should link to link1, photo2 should link to link2 and so on… I tried but couldn’t figure out. Can someone help please?

  42. [ Gravatar Icon ] TheN2S says:

    I have:

    ID, 'audio', true) || get_post_meta($post->ID, 'musicvideoo', true)): ?>

    display this if either musicvideoo or audio exists..

    But NOW how do we tell the system to NOT display that if either audio or musicvideoo exists..

  43. [ Gravatar Icon ] Jeff Starr says:

    Remember to wrap your code with <code> tags, folks — nobody can help you with half-eaten snippets..

  44. [ Gravatar Icon ] TheN2S says:

    <?php if(get_post_meta($post->ID, 'audio', true) || get_post_meta($post->ID, 'musicvideo', true)): ?>

    show if musicvideo or audio exists

    <?php endif; ?>

    I want to know how to reverse the conditional statement with a !

  45. [ Gravatar Icon ] Jennifer says:

    A less verbose way to display the custom field only if the field exists:

    <?php if(get('CustomField')) { ?>
           <? echo get('CustomField') ?>
    <?php } ?>

  46. [ Gravatar Icon ] Jennifer says:

    Okay - I now realize we’re talking about WP Custom Fields here, not Flutter. Sorry!

  47. [ Gravatar Icon ] Lee Peterson says:

    I’m trying to give my client an easy way to:

    • Use the key of ‘image’ multiple times for multiple images
    • Use timthumb script to resize proportionately
    • Create an image slide effect using Malsup Cycle script

    How would I combine multiple values and attribute types into one script?

    Seems I just can’t get it right:

    <?php $image = get_post_meta($post->ID, 'image', false); ?>
           <?php foreach($image as $the_image); {
                  echo '<img src="<?php bloginfo('template_url'); ?>/scripts/timthumb.php?src=<?php echo $the_image; ?>&h=170&w=220&zc=1&q=60" alt="<?php the_title(); ?>" />';
    } ?>

    This could be an excellent addition to your post above.

    Thank you!

  48. [ Gravatar Icon ] Daniel says:

    Hi perishable community,
    First of all I’m a new here and this site is very nice , very helpful.
    Could anyone help me pls. with displaying list of pages with at least 3-5 custom fields ? I’m almost for 14 days searching on internet, I have only found this article but there is only one custom field:
    http://www.wprecipes.com/how-to-use-a-custom-blurb-when-listing-pages
    , I asked there for the help to add more fields but no answer , Is it hard to add and display more fields ?
    I have changed my wp-pages into girl’s portfolios so i need list of girls with the girl’s names

    eg.:
    (page title-the name of the girl ),
    country,
    province,
    city,
    age and one thumbnail image (custom field)on the right.

    I am browsing internet 3 days 24/7 and i see only examples with one value & key , not with more , any help would be very appreciate.
    Thanks a lot Daniel

  49. [ Gravatar Icon ] TheN2S says:

    @Daniel contact me. (click my name “TheN2S” to go to my site and fill out the contact form)

  50. [ Gravatar Icon ] Daniel says:

    The code from that site i would like to use with more fields:

    ID, 'custom_blurb', true);
                  echo "<a>ID)."\">$page->post_title</a>";
                  echo $custom_blurb;
           }
    ?>

  51. [ Gravatar Icon ] Daniel says:

    @THEN2S just did it

  52. [ Gravatar Icon ] David says:

    Hi - I am combining the use of custom field metaboxes and custom taxonomies inside a Wordpress 3.0 custom post. When I output the taxonomies using get_the_term_list, the outputted value automtically has a link to other posts with the same taxonomy. Can this be achieved with get_post_meta?
    I would like to output say a price range value from a radio selection, so the user cn click on the price range and go to a page listing ‘all products within XXX price range’. I could do this with another custom taxonomy but I will shortly end up with a long right hand column in my edit custom post screen! Any help much appreciated.

  53. [ Gravatar Icon ] Pariuri says:

    Thanks you very much for this post :)

  54. Really nice info! Thank you so much :-)

  55. [ Gravatar Icon ] prazetyo says:

    Thank you…very useful