I discovered the free plugin Advanced Custom Fields last summer, and was blown away. This is such a powerful plugin. I immediately bought the Repeater Field addon for $25. With repeater fields you can make multiple rows of the same type of field. Loops of fields!
An example of a nice way to use this plugin combo would be a page of customer testimonials on a website. In the past I would have made a Custom Post Type called Testimonial, and made a page to list all the testimonials, with an intro and a WP_query
loop. But using Repeater Fields is much nicer; its simpler to code and has easier content management. That’s because you can edit all the testimonials on one page, and sequence them just by drag-and-drop.
To start, make a page in your WordPress site called Testimonials, and write an intro.
Now you need to have the two plugins mentioned above installed. Go to Custom Fields in your Admin area, and make a new Field Group. Call it Testimonial Fields, and under field type choose repeater.
You can add any number of sub-fields to a repeater field. It depends on your design. I used 4 sub-fields in a recent site: pullquote, testimonial text, attribution, and video link. Note that you can label the fields helpfully, and drag them to re-sequence them. These are the touches that make this plugin so awesome.
There is metabox called Location where you can specify the pages or posts where you want these fields to show up. So set your Testimonial Fields to display on the Testimonials page.
Then you need to make a testimonials template in your theme. If you duplicate your page.php file and rename it page-testimonials.php that will do.
The code that loops through the Testimonials is very simple. Paste this into your new template file, somewhere below the_content()
:
<?php if( have_rows('testimonial_fields') ): ?>
<ul class="testimonial-list">
<?php while( have_rows('testimonial_fields') ): the_row(); ?>
<li>
<div>
<h2><?php the_sub_field('pullquote'); ?></h2>
<div><?php echo wp_oembed_get(get_sub_field('video_link')); ?></div>
<p ><?php the_sub_field('testimonial_text'); ?></p>
<p><?php the_sub_field('attribution'); ?></p>
</div>
</li>
<?php endwhile; ?>
</ul>
<?php endif; ?>
This system is so much better than using a custom post type! Unless every testimonial needs its own permalink that is. Only use CPTs for stuff that needs individual permalinks.
Now add a little jQuery
Another lovely use for Repeater Fields is making client-editable accordions. I generally make custom post types for staff pages on business sites—because each staff member needs their own URL. And often these staff members have 2 thousand word resumes. When posting very long content online, an accordion is helpful to show and hide sections one at a time. See this lawyer’s resume page.
After you make your Custom Post Type you go to the Custom fields section. Make a Repeater Field called Resume. It has two sub-fields: Resume Heading (resume_heading
) and Resume Content (resume_content
). Set the fields to display on Staff type posts. Then make a staff post, and enter the resume, bit by bit, with rows of headings and content blocks.
To display the resume, now you have to call these fields in your template. Start by making a template for staff posts, called single-staff.php
.
You need to add two loops to your template: one to call the list of headings, and one to call the content blocks.
The first list calls the headings:
<?php if( have_rows('resume') ): ?>
<ul id="accordion">
<li><a href="#biography" class="active">biography</a></li>
<?php while(have_rows('resume')) : the_row(); ?>
<li>
<a href="#<?php echo sanitize_title(get_sub_field('resume_heading')); ?>" class="ready"><?php the_sub_field('resume_heading'); ?></a></li>
<?php endwhile; ?>
</ul>
<?php endif; ?>
The first list item is a link to the Bio, which is not in a custom field; its simply the regular content section of the post. The resume sections will hide it when they display.
We can make the anchor links from the resume_heading
field by passing the string through the function sanitize_title
.
This code displays the resume content blocks:
<div class="entry-content">
<div id="biography" class="resume-content showing">
<?php the_content(); ?>
</div>
<?php while( have_rows('resume') ): the_row(); ?>
<div id="<?php echo sanitize_title(get_sub_field('resume_content')); ?>" class="resume-content" >
<h2><?php the_sub_field('resume_heading'); ?></h2>
<?php the_sub_field('resume_content'); ?>
</div>
<?php endwhile; ?>
</div>
It needs CSS to initially hide the resume:
.resume-content { display:none; }
.resume-content.showing { display:block; }
And a little jQuery to make it work:
jQuery(document).ready(function($) {
$('#accordion li a').click(function(e) {
var accordionid = $(this).attr("href");
$('.resume-content').not(accordionid).slideUp();
$(accordionid).slideDown();
e.preventDefault();
});
});