How to use Advanced Custom Fields with Genesis

Share this!

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

km-web-advanced-custom-fields

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:

  1. It’s easy to forget to enter some of the details.
  2. 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:

Advanced Custom Fields

Advanced Custom Fields setup for the “Photography” field group (Click to enlarge)

And here is what the post-edit screen looks like when adding or editing a post whose category is either “photography” or “infrared-photography”:

km-web-advanced-custom-fields-edit-screnn

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

screen capture of Advanced Custom Fields with Genesis

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.

Share this!

About JeffCohan.com

The nSiteful Tech Blog (the official blog of nSiteful Web Builders, Inc. since January of 2013) is where I (Jeff Cohan) and (occasionally) associates will be posting articles of potential interest to like-minded techies, nSiteful clients who are playing active roles in the maintenance of their own Web sites and blogs, and pretty much anyone interested in how Web strategies and tools can help them reach their goals.

This entry was posted in Techniques and tagged , , , by Jeff Cohan. Bookmark the permalink.

About Jeff Cohan

Jeff and his wife, Margie, are the proud parents of Sarah and Jake. Jeff is the founder, president and chief cook and bottle washer of nSiteful Web Builders, Inc., a Web development and Internet Consulting firm. In his spare time, Jeff builds Web sites and Web applications, plays guitar, putters around in his basement woodworking shop, mercilessly spoils his grandchildren, and creates videos from more than two decades of home movies. His current video project is an extended montage of people (mainly family members) asking him to stop filming them.

24 thoughts on “How to use Advanced Custom Fields with Genesis

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

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

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

      • add a rule for the image, giving it a width (e.g. 40%), setting display to block, and setting float to left
      • add a width declaration to the .custom-data selector (e.g., 40%)

      Does that help?

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

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

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

    • 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:

      <div class="shutter_speed">
      	<span class="label">Shutter Speed:</span>
      	<span class="value">1/250</span>
      </div>
      

      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:

      .shutter_speed .value {
      	font-style: italic;
      	font-weight: bold;
      	color: green;
      }
      

      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!

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

Leave a Reply

Your email address will not be published. Required fields are marked *