Nick Van der Vrekens blog & portfolio

Using Custom fields in WordPress to attach images or files to your posts.

February 14th, 2009

Noteworthy, PHP, Themes, Wordpress

This article has been posted on the official WordPress Codex

WordPress has introduced Custom Fields for some time now, but not many people seem to know how to use them. Today I’ll try to give you some enlightenment about this, and explain how they work or what they can be used for.

I’ve been using Custom Fields in my themes too, and have created a function which enables an unlimited amount of images, files, links, flying cows or *whatever* to be attached to your posts and pages.  There are probably alot more people that can benefit from this method, so feel free to use it. I’ll explain how to do this in this post.

What are these mistery fields?

Well, Custom Fields are variables which you can attach to posts or pages. These variables can hold whatever you want, for example a demo version of something you’ve blogged about or a picture of the candybar you just ate.

How do I use them?

Custom Fields can be added through the “Custom Fields” panel in the WordPress editor, as shown in the image below. All a field requires is a key and a value. The key will be used to identify the variable in your theme, the value itself will be used where you want it. In this example we’ll add a Custom Field called “link1″, which will hold the URL of the WordPress Codex documentation about Custom Fields.
Fill in your key/value set and press “Add Custom Field”.

In this form we'll add the Custom Field. Our key will be "link1" and it'll hold the value "http://codex.wordpress.org/Using_Custom_Fields".

In this form we'll add the Custom Field. Our key will be "link1" and it'll hold the value "http://codex.wordpress.org/Using_Custom_Fields".

Ok, thats that. If you did everything right you should get something like this:

If you see this you did a good job.

If you see this you did a good job.

You’ll see that WordPress makes it easy for us, and will display all keys you’ve used before in a selection box. Next time you want to insert a Custom Field with this key, you can easily select it.

Our keys have not been saved however, to save them permanently we’ll need to save the current post or page first. You can do this using the button in the top right corner. In the next step I’ll explain how to use the inserted variables in your theme.

Retrieving the posts Custom Fields in your theme.

A WordPress theme cycles through its posts in something what we call “The Loop“. This is the preferred way of fetching your content from the WordPress database. In order to understand what happens next, you should have basic knowledge of what this thing really does ( click here to be enlightened ).

Every time “The Loop” runs over one of our posts, we can ask WordPress if it has one of our Custom Fields on that particular post. The function we’ll use to do that is called “get_post_meta“. If WordPress holds a key named “link1″ for that post, it’ll put its value (the URL we entered) in the variable we define for it. In this example the variable “$our_custom_field_variable” will be the lucky one. When WordPress doesn’t find the key we asked for however, the variable will have a “null”-value.

You can see a basic implementation of how to get our key below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 
 <!-- Start the Loop. -->
 <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); 
// here we get the Custom Field with key "link1". 
// the PHP variable "$our_custom_field_variable" will hold the link 
// to the WordPress Codex documentation. 
$our_custom_field_variable = get_post_meta($post->ID, 'link1', true);?>
 
 <!-- Display the Post's Content in a div box. -->
 <div class="entry">
   <?php the_content(); ?>
 </div>
 
 
<!-- Display our Custom Field -->
<div class="link">
   link1: "<?php echo $our_custom_field_variable; ?>"
 </div>
 
 <!-- Stop The Loop (but note the "else:" - see next line). -->
 <?php endwhile; else: ?>
 
 <!-- The very first "if" tested to see if there were any Posts to -->
 <!-- display.  This "else" part tells what do if there weren't any. -->
 <p>Sorry, no posts matched your criteria.</p>
 
 <!-- REALLY stop The Loop. -->
 <?php endif; ?>

There you go, thats all !
From now on you can use Custom Fields in all your WordPress themes.
If you’re still interested in my own method, keep reading for a few more minutes.

Automatically fetching all Custom Fields

What’s the point?

If you have alot of Custom Fields defined, it may be a good idea to automate the fetching part.
I wrote a small PHP function to do this for me, and to create an array of attached images/links/files along with their labels.

Here’s an example of its use: suppose I need to attach 5 images to a post, each with their own label.
I could place them in the editor yourself, but using Custom Fields I could also create a nice slideshow.
To accomplish this I need to create several Custom Fields. First we have the “image1″, “image2″, “image*” to “image5″ keys, these will hold the image URL. This would be enough to create an array of images, but I’d like some of them to have a label too. Lets say the image with key “image2″ needs the label “Second Image”, I could accomplish that by adding a field called “image2_label” with the value “Second Image”.

In this example the function would create two PHP arrays, one called “$post_images” which contains the images, and another one “$post_images_label” which contains the labels for these images. I’ll show you how to loop through these arrays later on, but you should get the point of doing this now. If not, look at the bottom of this post. The list of links and files and the image slideshow is created using Custom Fields.

The function also simplifies fetching other (non-list keys) too, by putting all of them in the “$post_var”-object. If I created a Custom Field called “myField”, I could easily reach its value through $post_var["myField"]. This is shorter than the “get_post_meta()”-method mentioned above.

The magic function

Here’s the function that does the trick, copy/paste this in your functions.php file so you can access it from your theme. I’d appreciate it if you would keep the author notice at the top intact ;-)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
function bd_parse_post_variables(){
// bd_parse_post_variables function for WordPress themes by Nick Van der Vreken.
// please refer to bydust.com/using-custom-fields-in-wordpress-to-attach-images-or-files-to-your-posts/
// for further information or questions.
global $post, $post_var;
 
// fill in all types you'd like to list in an array, and
// the label they should get if no label is defined.
// example: each file should get label "Download" if no
// label is set for that particular file.
$types = array('image' => 'no info available',
'file' => 'Download',
'link' => 'Read more...');
 
// this variable will contain all custom fields
$post_var = array();
foreach(get_post_custom($post->ID) as $k => $v) $post_var[$k] = array_shift($v);
 
// creating the arrays
foreach($types as $type => $message){
global ${'post_'.$type.'s'}, ${'post_'.$type.'s_label'};
$i = 1;
${'post_'.$type.'s'} = array();
${'post_'.$type.'s_label'} = array();
while($post_var[$type.$i]){
array_push(${'post_'.$type.'s'}, $post_var[$type.$i]);
array_push(${'post_'.$type.'s_label'},  $post_var[$type.$i.'_label']?htmlspecialchars($post_var[$type.$i.'_label']):$message);
$i++;
}
}
}

Customizing the script to your needs

You may need to edit this function to suit your needs. It currently creates a list for files, links and images in these variables:

  • $post_images (hold the values given to “image1″, “image2″, “image*”)
  • $post_images_label (holds the values given to “image1_label”, “image2_label”, “image*_label”. If no label is specified but an image*-key is, the label for that image will be the default label specified in the script. This goes for all _label arrays.
  • $post_files (holds the values given to “file1″, “file2″, “file*”)
  • $post_files_label (holds the values given to “file1_label”, “file2_label”, “file*_label”)
  • $post_links (holds the values given to “link1″, “link2″, “link*”)
  • $post_links_label (holds the values given to “link1_label”, “link2_label”, “link*_label”)

All information for these arrays is included in the $types-variable. The only thing you need to do to add a type is adding that type to the array. For example if you want to output a list of your cats names and pictures, you’d need this:

1
2
3
4
5
6
7
8
// fill in all types you'd like to list in an array, and
// the label they should get if no label is defined.
// example: each file should get label "Download" if no
// label is set for that particular file.
$types = array('image' => 'no info available',
'file' => 'Download',
'link' => 'Read more...',
'cat' => 'This cat has no name');

With this example you could add Custom Keys named “cat1″, “cat1_label”, “cat2″, “cat2_label”, “cat*”, “cat*_label” where the “cat*”-key would hold the cats picture, and the “cat*_label”-key would be the cats name.
This function would create the arrays “$post_cats” and “$post_cats_label”, containing each cats picture and name.

Using the parsed Custom Fields in your theme

We now have our arrays which contain the values of the Custom Fields we’ve set up. You can use these as regular PHP arrays, here’s how I did it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
 
 <!-- Start the Loop. -->
 <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); 
// call the function in our functions.php file
bd_parse_post_variables(); 
// these variables are now available:
// $post_var
// $post_images and $post_images_label
// $post_links and $post_links_label
// $post_files and $post_files_label
?>
 
 <!-- Display the Post's Content in a div box. -->
 <div class="entry">
   <?php the_content(); ?>
 </div>
 
 
<!-- Display our Custom Field -->
<div class="link">
   link1: "<?php echo $post_var['myField']; ?>"
 </div>
 
<!-- Display the list of links -->
<ul>
<?php while(count($post_files) > 0): ?>
 <li class="file">
<a href="<?php echo array_shift($post_files); ?>" title="Click to download this file">
<?php echo array_shift($post_files_label); ?>
</a>
</li>
<?php endwhile; ?>
</ul>
 
 <!-- Stop The Loop (but note the "else:" - see next line). -->
 <?php endwhile; else: ?>
 
 <!-- The very first "if" tested to see if there were any Posts to -->
 <!-- display.  This "else" part tells what do if there weren't any. -->
 <p>Sorry, no posts matched your criteria.</p>
 
 <!-- REALLY stop The Loop. -->
 <?php endif; ?>

This example will output something like my list of links and files below. The image slideshow is created in the same way, but it uses the lightbox script.

I hope you’ve found this explenation usefull. If you used my code or made changes to it to increase its function, please let me know ;-)

Subscribe for updates

Leave us your name and email adress and we'll inform you when someone posts a new comment. unsubscribe?




There are 9 replies to this item:




XHTML:Please use "<pre>" to insert code: <pre lang="actionscript asp css html4strict javascript php sql xml[pick any of these languages]" line="45[starting line, optional]"> your code here </pre>

  • #9

    December 15th, 2009

    Ranadeep says:

    Can you help me to do this please?

    key image1 value image1.jpg
    key image2 value image2.jpg
    key link1 value link1.html
    key link2 value link2.html

    Now I want to display image1 linked to link1, image2 linked to link2 and so on…

    Can you please help me?

  • #8

    October 13th, 2009

    Usa says:

    Awesome.

    Your article resolve my problems understanding how to use Custom Fields.

    Thanks!

  • #7

    July 3rd, 2009

    Ronald Nunez says:

    Thanks for your informative post, easy to understand and detailed. It saved me a lot of time.

  • #6

    June 4th, 2009

    Katie says:

    Thanks so much! Your code saved me a couple hours of work, and a giant headache. :)

  • #5

    June 3rd, 2009

    Anonymous says:

    Hey Nick thanks for the reply, it looks like I got distracted from my issue and never came back here to see the answer. Just wanted to let you I removed that code and everything seems to work fine now.

    Thanks Again

    Jmartin

  • #4

    May 27th, 2009

    era says:

    تالتلاتلتل
    thanks

  • #3

    April 15th, 2009

    Nick says:

    Hi Martin,

    sorry for the late answer, didn’t have internet for the past 5 days.

    There’s an echo in the bd_parse_post_variables_function that I forgot to remove, if you comment or delete the following line it should be ok:

    echo $type.$i.' - '.${$type.$i.'_label'};

    I’ll remove it in this example too, thanks for notifying me :)

    Cheers,

    Nick

  • #2

    April 11th, 2009

    jmartin says:

    Thanks for the function and code, one of the few that are easy to implement. I do have a problem though.

    How do you get rid of the custom field names?

    I have two images and a link defined and this is what I get at the top of my post. Obviously they are the key names but how do I get rid of them. They appear right where the call to the function is. Everything else works great.

    TIA
    jmartin

    image1 - image2 - link1 -

  • #1

    February 18th, 2009

    Chris says:

    Thanks for the fields explenation.
    I didn’t got it to work but its all ok now.

    thank you