Ask your WordPress questions! Pay money and get answers fast! (more info)

How to display ACF Repeater in my Single.php File WordPress

  • SOLVED

I am using ACF Pro (current version) and have a repeater setup with 4 sub-fields, the code for the set-up is:
if( function_exists('register_field_group') ):

register_field_group(array (
'key' => 'group_55034c2e80cd6',
'title' => 'Address Details',
'fields' => array (
array (
'key' => 'field_55034c470a82f',
'label' => 'Address Details',
'name' => 'address_details',
'prefix' => '',
'type' => 'repeater',
'instructions' => '',
'required' => 1,
'conditional_logic' => 0,
'wrapper' => array (
'width' => '',
'class' => '',
'id' => '',
),
'min' => '',
'max' => 100,
'layout' => 'table',
'button_label' => 'Add Row',
'sub_fields' => array (
array (
'key' => 'field_55034cc00a830',
'label' => 'Date Added',
'name' => 'date_added',
'prefix' => '',
'type' => 'date_picker',
'instructions' => '',
'required' => 1,
'conditional_logic' => 0,
'wrapper' => array (
'width' => '',
'class' => '',
'id' => '',
),
'display_format' => 'd/m/Y',
'return_format' => 'F j, Y',
'first_day' => 1,
),
array (
'key' => 'field_55034d370a831',
'label' => 'Address',
'name' => 'address',
'prefix' => '',
'type' => 'textarea',
'instructions' => '',
'required' => 1,
'conditional_logic' => 0,
'wrapper' => array (
'width' => '',
'class' => '',
'id' => '',
),
'default_value' => '',
'placeholder' => '',
'maxlength' => '',
'rows' => '',
'new_lines' => 'wpautop',
'readonly' => 0,
'disabled' => 0,
),
array (
'key' => 'field_55034d840a832',
'label' => 'Author',
'name' => 'author',
'prefix' => '',
'type' => 'text',
'instructions' => '',
'required' => 1,
'conditional_logic' => 0,
'wrapper' => array (
'width' => '',
'class' => '',
'id' => '',
),
'default_value' => 'AutographSearch',
'placeholder' => '',
'prepend' => '',
'append' => '',
'maxlength' => '',
'readonly' => 0,
'disabled' => 0,
),
array (
'key' => 'field_55034dc50a833',
'label' => 'Status',
'name' => 'status',
'prefix' => '',
'type' => 'select',
'instructions' => '',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => array (
'width' => '',
'class' => '',
'id' => '',
),
'choices' => array (
'active' => 'Active',
'expired' => 'Expired',
),
'default_value' => array (
'' => '',
),
'allow_null' => 0,
'multiple' => 0,
'ui' => 0,
'ajax' => 0,
'placeholder' => '',
'disabled' => 0,
'readonly' => 0,
),
),
),
),
'location' => array (
array (
array (
'param' => 'post_type',
'operator' => '==',
'value' => 'post',
),
),
),
'menu_order' => 0,
'position' => 'normal',
'style' => 'default',
'label_placement' => 'top',
'instruction_placement' => 'label',
'hide_on_screen' => '',
));

endif;


I am using a child theme and I am working on the assumption that as the fields will be displayed on a standard post the code needs to be inserted into single.php in the child theme. The code for the child theme without any modifications is:

<?php
/**
* The template for displaying a single post
*
* @package Layers
* @since Layers 1.0.0
*/

get_header(); ?>

<section id="post-<?php the_ID(); ?>" <?php post_class( 'content-main clearfix' ); ?>>
<div class="row">

<?php get_sidebar( 'left' ); ?>

<?php if( have_posts() ) : ?>

<?php while( have_posts() ) : the_post(); ?>
<article <?php layers_center_column_class(); ?>>
<?php get_template_part( 'partials/content', 'single' ); ?>
</article>
<?php endwhile; // while has_post(); ?>

<?php endif; // if has_post() ?>

<?php get_sidebar( 'right' ); ?>
</div>
</section>

<?php get_footer(); ?>


I believe the code I need to insert to show my repeater in a table is:

<?php if( have_rows('address_details') ):?>
<table>
<!-- Header row for all cols in table -->
<tr>
<th>Date Added</th>
<th>Address</th>
<th>Author</th>
<th>Status</th>
</tr>
<?php while ( have_rows('address_details') ) : the_row(); ?>
<tr>
<td><?= the_sub_field('date_added'); ?></td>
<td><?= the_sub_field('address'); ?></td>
<td><?= the_sub_field('author'); ?></td>
<td><?= the_sub_field('status'); ?></td>
</tr>
<?php endwhile; ?>
<?php else: ?>
<!-- if no rows are found add markup below -->
<?php endif;?>


I need to understand where in the single.php I should insert the repeater code so it shows after the post content in a table format.

Answers (2)

2015-03-15

Dbranes answers:

You will want to place the repeater inside the loop, for example:


<?php while( have_posts() ) : the_post(); ?>

<article <?php layers_center_column_class(); ?>>

<?php get_template_part( 'partials/content', 'single' ); ?>

<!-- ADD YOUR CODE HERE -->

</article>

<!-- OR ADD YOUR CODE HERE -->

<?php endwhile; // while has_post(); ?>


You might also add it into <em>/wp-content/your-theme/partials/content-single.php</em> if it's only included in the <em>single.php</em>.

You could also use the <em>the_content</em> filter (e.g. with output buffering ) to inject it into your post content on single posts, by checking if <em>is_single()</em> is true.


fergusga comments:

I inserted my code as per my original post and pasted after <?php get_template_part( 'partials/content', 'single' ); ?> so the file now looks like this:

?php
/**
* The template for displaying a single post
*
* @package Layers
* @since Layers 1.0.0
*/

get_header(); ?>

<section id="post-<?php the_ID(); ?>" <?php post_class( 'content-main clearfix' ); ?>>
<div class="row">

<?php get_sidebar( 'left' ); ?>

<?php if( have_posts() ) : ?>

<?php while( have_posts() ) : the_post(); ?>
<article <?php layers_center_column_class(); ?>>
<?php get_template_part( 'partials/content', 'single' ); ?>
<?php if( have_rows('address_details') ):?>

<table>

<!-- Header row for all cols in table -->

<tr>

<th>Date Added</th>

<th>Address</th>

<th>Author</th>

<th>Status</th>

</tr>

<?php while ( have_rows('address_details') ) : the_row(); ?>

<tr>

<td><?= the_sub_field('date_added'); ?></td>

<td><?= the_sub_field('address'); ?></td>

<td><?= the_sub_field('author'); ?></td>

<td><?= the_sub_field('status'); ?></td>

</tr>

<?php endwhile; ?>

<?php else: ?>

<!-- if no rows are found add markup below -->

<?php endif;?>
</article>
<?php endwhile; // while has_post(); ?>

<?php endif; // if has_post() ?>

<?php get_sidebar( 'right' ); ?>
</div>
</section>

<?php get_footer(); ?>


If you look at my site [[LINK href="http://autographsearch.com/michael-stipe/"]][[/LINK]] this breaks the formatting and the footer area content appears above the repeater text.

Can you advise what changes need to be made to format this correctly as per my original post?

Thanks


Dbranes comments:

It looks like your missing <em></table></em> to close the opening table tag.


Dbranes comments:

You might want to create a partial like:

<?php get_template_part( 'partials/repeater', 'single' ); ?>

where you create the file:

/wp-content/your-theme/partials/repeater-single.php

that contains your code.

Or create a custom function in your child theme's <em>functions.php</em> file:

if( ! function_exists( 'wpq_display_repeater' ) ) {
function wpq_display_repeater() {
?>

<!-- ADD YOUR REPEATER CODE HERE -->

<?php
}
}


and then use this in your template file:


// Add repeater stuff
if( function_exists( 'wpq_display_repeater' ) ) {
wpq_display_repeater();
}


This will be easier to maintain, than copy/paste the repeater code directly into your templates.


Dbranes comments:

ps: you might also want to use for example this check in your code:

if( function_exists('register_field_group') ) {
// ... your code here
}


just to make sure your template won't break if you uninstall the ACF plugin ;-)


fergusga comments:

Hi Dbranes,

I have tried this and I can't get it to work ( I am sure that is due to my lack of understanding of the coding) but at this point I am no further forward as I was able to get the values to display previously just not above the footer area..

I took your recommendation and updated the single.php to reference a function in the functions.php, the code is below:

Single.php:
<?php
/**
* The template for displaying a single post
*
* @package Layers
* @since Layers 1.0.0
*/

get_header(); ?>

<section id="post-<?php the_ID(); ?>" <?php post_class( 'content-main clearfix' ); ?>>
<div class="row">

<?php get_sidebar( 'left' ); ?>

<?php if( have_posts() ) : ?>

<?php while( have_posts() ) : the_post(); ?>
<article <?php layers_center_column_class(); ?>>
<?php get_template_part( 'partials/content', 'single' ); ?>
// Add repeater stuff

if( function_exists( 'wpq_display_repeater' ) ) {

wpq_display_repeater();

}
</article>
<?php endwhile; // while has_post(); ?>
<?php endif; // if has_post() ?>
<?php get_footer(); ?>
<?php get_sidebar( 'right' ); ?>
</div>
</section>

<?php get_footer(); ?>


Functions.php:

<?php
add_action( 'wp_enqueue_scripts', 'theme_enqueue_styles' );
function theme_enqueue_styles() {
wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css' );
wp_enqueue_style( 'child-style',
get_stylesheet_directory_uri() . '/style.css',
array('parent-style')
);
}
if( ! function_exists( 'wpq_display_repeater' ) ) {

function wpq_display_repeater() {

?>
<?php if( have_rows('address_details') ):?>
<table>
<!-- Header row for all cols in table -->
<tr>
<th>Date Added</th>
<th>Address</th>
<th>Author</th>
<th>Status</th>
</tr>
<?php while ( have_rows('address_details') ) : the_row(); ?>
<tr>
<td><?= the_sub_field('date_added'); ?></td>
<td><?= the_sub_field('address'); ?></td>
<td><?= the_sub_field('author'); ?></td>
<td><?= the_sub_field('status'); ?></td>
</tr>
<?php endwhile; ?>
<?php else: ?>
<!-- if no rows are found add markup below -->
<?php endif;?>
<?php

}

}


On my site I now get this returned '// Add repeater stuff if( function_exists( 'wpq_display_repeater' ) ) { wpq_display_repeater(); } although it is in the right place!

I probably need some specifics in terms of line numbers etc where any changes are required.


Dbranes comments:

you're just missing the enclosing <em><?php ?></em> part around your PHP code:

<?php
// Add repeater stuff

if( function_exists( 'wpq_display_repeater' ) ) {
wpq_display_repeater();
}
?>

2015-03-15

Andrea P answers:

As Dbranes said previously, you need to close the table html.
also, the_sub_field() is already echoing the value, so you don't need to use <?= before it. especially because it's not good to use php shortened opening and closing tags, because some servers won't accept them.


<table>
<!-- Header row for all cols in table -->
<tr>
<th>Date Added</th>
<th>Address</th>
<th>Author</th>
<th>Status</th>
</tr>

<?php while ( have_rows('address_details') ) : the_row(); ?>
<tr>
<td><?php the_sub_field('date_added'); ?></td>
<td><?php the_sub_field('address'); ?></td>
<td><?php the_sub_field('author'); ?></td>
<td><?php the_sub_field('status'); ?></td>
</tr>

</table>


fergusga comments:

Hi,

I made the suggest change and the addresses display (as I was previously able to do) but they appear below the footer as you can see on this page [[LINK href="http://autographsearch.com/michael-stipe/"]][[/LINK]]

The code for single.php is:

<?php
/**
* The template for displaying a single post
*
* @package Layers
* @since Layers 1.0.0
*/

get_header(); ?>

<section id="post-<?php the_ID(); ?>" <?php post_class( 'content-main clearfix' ); ?>>
<div class="row">

<?php get_sidebar( 'left' ); ?>

<?php if( have_posts() ) : ?>

<?php while( have_posts() ) : the_post(); ?>
<article <?php layers_center_column_class(); ?>>
<?php get_template_part( 'partials/content', 'single' ); ?>
<?php
// Add repeater stuff
if( function_exists( 'wpq_display_repeater' ) ) {
wpq_display_repeater();
}
?>
</article>
<?php endwhile; // while has_post(); ?>
<?php endif; // if has_post() ?>
<?php get_footer(); ?>
<?php get_sidebar( 'right' ); ?>
</div>
</section>

<?php get_footer(); ?>


fergusga comments:

Andrea,

I have used the code exactly as you have used it and as you can see from my page only the first row is now in a table alebit in the correct position, [[LINK href="http://autographsearch.com/michael-stipe/"]][[/LINK]]

<?php
add_action( 'wp_enqueue_scripts', 'theme_enqueue_styles' );
function theme_enqueue_styles() {
wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css' );
wp_enqueue_style( 'child-style',
get_stylesheet_directory_uri() . '/style.css',
array('parent-style')
);
}
if( ! function_exists( 'wpq_display_repeater' ) ) {

function wpq_display_repeater() {

?>
<?php if( have_rows('address_details') ):?>

<table>
<!-- Header row for all cols in table -->
<tr>
<th>Date Added</th>
<th>Address</th>
<th>Author</th>
<th>Status</th>
</tr>
<?php while ( have_rows('address_details') ) : the_row(); ?>
<tr>
<td><?php the_sub_field('date_added'); ?></td>
<td><?php the_sub_field('address'); ?></td>
<td><?php the_sub_field('author'); ?></td>
<td><?php the_sub_field('status'); ?></td>
</tr>
</table>
<?php endwhile; ?>
<?php else: ?>
<!-- if no rows are found add markup below -->
<?php endif;?>
<?php

}

}


Andrea P comments:

first think I can see that in your template file the footer is called twice.
it should still display below the table (and not the other way round), but maybe this duplicated call, it's causing conflicts and break the page, so that the table displays below the footer.

you should delete the get_footer() which is above get_sidebar('right')

let me know if then you still have issues.

p.s. I don't know why, but I can't see the url that you have posted so I can't see the page, could you place it in the code tag and repost it?


Andrea P comments:

ah, also, in the table you should place the endwhile, above the closing of the table tag


fergusga comments:

Great, thank you both, is now working perfectly!


Andrea P comments:

perfect! :)

I would suggest you to double check all your template files to see if the get_footer() is duplicated.

cheers!