Last updated October 10th, 2018 at 08:04 am
Do you want to use Advanced Custom Fields with Genesis? This article will show you one simple method for displaying the values of those custom fields in your Genesis framework child theme.
(I can’t explain why I’ve waited so long to try out the Advanced Custom Fields plugin. All I can say is I’m glad I finally did. Today.)
Setting up the Advanced Custom Fields plugin
This article does not cover the process for installing and configuring Advanced Custom Fields. Frankly, that process is so intuitive and straightforward — and well-documented elsewhere — that I couldn’t do better if I tried. Instead, what I’ll describe here is my particular use case.
Use Case: Web Site for Artist
The Web site in question (still in development) is for an artist who makes paintings and photographs. We’re using the Modern Portfolio Pro child theme with Genesis. Each blog post consists of a large image of either a painting or a photograph. Posts are categorized accordingly, either as ‘painting’, ‘photography’ or ‘infrared-photography’ (a subcategory of ‘photography’).
Photographers often like to share details about their photographs. And while my client could have entered these details free-form in the body of the post-edit box, there are a couple of problems with that approach:
- It’s easy to forget to enter some of the details.
- Doing it free-form isn’t the best way to display the details for those interested in them.
Therefore, I created (what Advanced Custom Fields refers to as) a field group called “Photography” with Location rules for displaying the custom fields on posts in either the ‘photography’ or ‘infrared-photography’ categories. The fields in this field group are the following:
- Camera
- Lens
- Lighting
- Aperture
- Shutter Speed
- Processing Details
Here’s the field group setup screen:

And here is what the post-edit screen looks like when adding or editing a post whose category is either “photography” or “infrared-photography”:
I went ahead and populated all of these custom fields for one of the blog posts in the ‘photography’ category. (Note: We’re at the “demo” stage as of this writing, and the fields and filled-in values are all preliminary and for demo purposes only.)
Displaying the Values of the Advanced Custom Fields in Genesis
End Result
Here’s the end result, with the photo meta information in a box below the image and any caption and/or basic descriptive content (click to enlarge):
Display Advanced Custom Fields data on the front end using a Genesis Action Hook
I chose to use the genesis_entry_content action hook, calling a custom function named ‘nwb_acf_photography’. The way this works is that anything the custom function echoes to the screen will appear after the main entry content.
Add this line to the child theme’s functions.php file:
add_action ('genesis_entry_content', 'nwb_acf_photography' );
Custom Function
And here is the code for the custom function, with spacing and line breaks for readability (also added to the child theme’s functions.php file):
function nwb_acf_photography() { if ( ! ( is_single() && in_category(array(2, 7, 15)) ) ) { return; } // else // These are the custom field keys JC defined in the dashboard $metas_photo = array( 'camera', 'lens', 'lighting', 'aperture', 'shutter_speed', 'processing_details'); // If ANY of these fields is filled in, // then we'll proceed and start the div. $has_meta = false; // init foreach ($metas_photo as $test ) { if ( get_field($test) ) { $has_meta = true; continue; // Just need one meta field filled to create the div. } } if ( $has_meta ) { echo '<div class="custom-data photography-custom-data">'; echo '<h2>Photo Details:</h2>'; foreach ( $metas_photo as $meta_photo ) { $$meta_photo = get_field($meta_photo); if ( $$meta_photo ) { $f_object = get_field_object($meta_photo); $label = $f_object['label']; echo '<div class="' . $meta_photo . '"><span class="label">' . $label . ':</span> ' . '<span class="value">' . $$meta_photo . '</span></div>'; } } echo '</div><!-- /.custom-data -->'; } }
Notes
- Lines 2 – 4: The function should invoke only for single blog posts in the ‘photography’ (catgegory ID 2) or ‘infrared-photography’ (category ID 7) categories.
- Lines 7 – 14: I’m lazy, so I define a simple numeric array whose elements are the keys of the custom fields. This will allow me to iterate through a foreach loop to display the label and value for each custom field used for the post.
- Lines 17 – 23: I want to assemble a container div for the meta content, but only if there’s actually some meta content to display. So I initialize a custom $has_meta variable to false and then switch it to true if any of the six custom fields has any stored value. I’m using the ACF get_field function for this test. The continue statement kicks me out of the loop if/when the condition is true.
- Lines 25 – 39: This is where the content for the meta data is assembled. Line 29 stores the value of each custom field key in a variable variable whose name is the key (using the $$ double dollar sign method). For each custom field that has been defined for the post, I use the ACF get_field_object function, which returns an associative array of values for the given field key, so that I can get the key’s label (line 32). The rest of the code block simply echoes out the photo’s meta data.
The CSS
And here is the pertinent CSS:
.custom-data { padding: 2em; margin-top: 2em; margin-bottom: 3em; border: 1px solid #333; } .custom-data .label { color: #999; margin-right: 1em; } .custom-data .value { color: #000; font-weight: 500; }
Comments Welcome
I hope you found this article helpful. If so, feel free to share. If you have questions or comments, including suggestions for improvements, please comment below.
Hi,
Thanks for this… I apologise for the very basic question but…
Where are you adding the first two sets of code? Is it to your child theme’s functions.php file?
No need to apologize. An excellent question. Yes, both segments of code should be added to the child theme’s functions.php file. (Thanks for the question; I updated the article accordingly.)
Great post! Thanks for sharing it — saw it in the GenesisWP Facebook group.
Thanks, Jeff! It’ll probably be another week before I can put your code into action, but you probably just saved my hairline, and my client a lot of money. 🙂
Nice to hear, Adam. Thanks for your comment.
Actually, never mind! I got it!
Kewl! I was just about to reply. What was your solution?
If I understood your question, then I think all you need to do is enter valid html in the box for band link, like this:
<a href="http://soundcloud.com/band-link-here">Band 99<a>
Hi Jeff,
Sorry for my late reply; I didn’t see a note that you’d replied. 🙂
My solution was this:
if ( $has_meta ) {
echo '';
echo '' ?>
<?php
foreach ( $metas_links as $meta_links ) {
$$meta_links = get_field($meta_links);
if ( $$meta_links ) {
$f_object = get_field_object($meta_links);
$label = $f_object['label'];
echo '' .
'' . $label . '' .
'';
}
}
echo '';
}
}
Hi again, Jeff,
As I thought, I’m just getting to this. Could you throw me a quick bone, as my aptitude for php isn’t that great? I’ve tried a few things, and I’m just getting a white page of death.
I need to link field labels to their inputs. I’ve changed your photography metadata to band links, so in my case, I need to link the Soundcloud label to http://www.soundcloud.com. Is that easy? Thanks again!
Adam
Hi Jeff
Sorry to resuscitate an older thread but I have used your code and all is working perfectly – apart from the fact that I want to add an image for each entry. How did you add your image as there isn’t an image field in your code? (As far as I can see)
I am aiming to have an image aligned left with the fields on the right. Any help would be very much appreciated. I have combed through every article on the topic on Google with no luck!
Thanks!
Best…
Lynne
In my case, the image is in the post itself, not part of the custom fields. The only custom fields in my illustration are the ones that show up in the “Photo Details” box. You could do the same. To achieve your desired presentation, you could try this CSS markup (and experiment):
Does that help?
Thanks. I really appreciate you sharing this code. Hooked into genesis_entry_header so my fields display after the title, but before the content. Doing a gardening website which is in development. Used it like this…
———–
Agastache rugosa – Honey Bee Blue – Anise Hyssop
—————–
Zone: 4
Height: 24″
Spread: 24″
Light: Full Sun
Moisture: Dry
Type: Perennial
————-
Feature Image
————-
Content
I’m glad it helped, Mark.
Jeff,
Great post and very easy to understand walk-through. This is also applicable in a template page. I have used it here: http://pastoradamsummers.org/musical-specials/the-potter-knows-the-clay/ but also have YouTube video being injected by using only the url end code.
Great stuff!
Thanks, Paul. I’m glad it helped. Nice implementation at Pastor Adam Summer site.
I would be willing to hit your PayPal link on this one. I am using the Advanced Custom Fields plugin with a Genesis theme. I have organized the data into field groups. The code seems to only want to display one group (and it doesn’t appear to matter which one). Even if I stack all the fields into one array, it won’t work, Then I get a 500 internal server error. Thoughts? Do I ditch the field groups completely and just have one group?
Hey, Joni –
Can you provide more information about your use-case, the field groups you’re using, and the code you’re using for the output?
PS: I do think your problem may be that you’re using the get_field() ACF function, which is for a single field group.
PPS: When I have time, I plan to update my post to show how I’d accomplish the same result using native WordPress functions for meta data. Bill Erickson makes a very good case for NOT using ACF’s front-end functions in this post of his.
Hi
This looks like a great solution. I use repeater fields from ACF a lot. Would these work as well with this approach?
Mark: I have not worked with ACF repeater fields yet, but I can think of no reason why the approach I’ve described would not work with them. When you have things working, please feel free to come back here and post a link so we can see what you’ve done. Thanks.
Feeling a bit like a dummy, but how would you change the style of one specific value in one of the fields?
Not a dumb question at all.
Using the example in my post, suppose you want the shutter speed value to display italicized, bold, and green.
The loop in lines 28-37 will generate HTML for the shutter speed custom field as follows:
The span whose class is “value” is a descendant of the div whose class is “shutter_speed”. So now add a rule to your CSS stylesheet as follows:
The above rule uses what is known as a descendant (or contextual) selector. It reads as follows: “Apply these rules to any element with a class name of “value” that is found within any element with a class name of “shutter speed”.”
HTH!
Brilliant! I was so close. Thanks a million for the tips.
Jeff:
Very helpful, thank you. I this as a basis for my own functions; in my case I tested for different post types using switch statements but I’m using the core of the logic you have here.
One question: wouldn’t it be slightly more efficient to use to use break instead on continue on L22, since the only purpose of the loop is to set $has_meta ?
Hey, Scott. Thanks for your comments. And
I thinkyou’re right about usingbreak
instead ofcontinue
.Just found this, great stuff! Can’t you just put this in a custom page template made for the post type instead of all of adding all that code to your functions.php file?
Hello, Amy –
I’m glad you liked.
As for your question: I’m not using a custom page template for this. I think that’s part of the “beauty” of the approach. The post type is simply ‘post’. In other words, it’s a blog article.
By adding the action (hooked to the ‘genesis_entry_content’ hook) in functions.php, it forces WordPress to reads the nwb_acf_photography() function. If the current post is a single blog post and its category ID is one of the specified IDs and the author actually added the meta data, then the meta data will be displayed. Otherwise, WordPress does a quick return and ignores the rest of the function.
Does that make sense?
Yes it does, thank you so much for your speedy reply! Am I correct in seeing that you don’t even need to make a custom post type for this and that’s why you didn’t need to add extra support in an array for ‘custom-fields’ ?? This is simply adding custom fields to designated categories, do I have that right?
Thank you!!
You’re right, Amy. Custom fields can be used with standard posts and pages and any custom post type. In this case, I’m using custom fields with blog posts that are assigned any of three categories: Photography, Infrared Photography, and Multimedia (category IDs 2, 7, and 15, respectively.
It’s understandable that people think custom fields are for custom post types because (if you ask me) there’s no reason to create a custom post type if you’re not planning to associate custom fields with it. So you’re pretty much always using custom fields when you’re using custom post types.
I will admit, though, that there’s a minor workflow problem with my implementation, and I hope this explanation makes sense. Namely, since WordPress does not “know” that a blog post belongs to one of the applicable categories when first adding the post, the custom fields do not appear in the editing screen until after the post is saved once. In practice, this means that you’d have to start creating the post, assign it to the appropriate category, and then save as draft before finishing and publishing. After saving as draft, the custom fields will appear in the editing screen.
Are you trying to incorporate custom fields somewhere? If so, please tell me about it. I’m always interested in learning how others use this feature of WordPress.
I am making a page that will display ‘reviews’, I’m trying to decide if I want to do a custom post type and just show the archive page in the nav bar or make a page template and pull the reviews in with the loop. It is nice how the CPR archive page kind of ‘makes itself’ (not sure how to say that, but if you have Custom Post Types then the archive page will just ‘work’ if you just use the slug at the end of the archive url to see the archive page), but I may go for the page template so that I can bring in the review on one page so they just show but aren’t ‘clickable’ to their own single post page… does that make sense?
Yes, an archive page for a custom post type “makes itself”; but without coding, any custom fields wouldn’t show up.
Have you started this yet? Can you point me to a URL?
Here’s a link to a series of pages I created on one of my domains for “Useful Plugins”. If you click around, you’ll see that you can:
– view the details for a specific plugin
– view an archive of all plugins that are assigned a specific category
– view an archive of all plugins that are assigned a specific tag
But each of those pages needed coding to bring in custom fields.
HTH.
Ok yep, I understand. No that page is in my Local version at this point. Thank you I will check out your link! Thank you so much!!
Wow you link shows some great stuff! Those extra details were all made with custom fields and no CPT’s then – the ones in the main content area?
Yes, custom fields applied to the “uplug” custom post type.
Nice, that’s great! You offer a lot of information on your site! Esp luv the Genesis info!