WP Custom Fields, Part II: Tips and Tricks
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 postget_post_custom_keys()
— Returns array of key data for current postget_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.
55 responses to “WP Custom Fields, Part II: Tips and Tricks”
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…
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!
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?
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”
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.
@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!!
Sorry there is an error with above code, third line should be:
<?php if($images != "") { // if we have images ?>
Used
'
instead of"
Sorry!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!
@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.
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.
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!
@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.