DEV Community

leanminmachine
leanminmachine

Posted on

Wordpress: ACF Repeater & Flexible Content fields

So basically, one of my clients wanted me to do something like having a content field (repeater: ACF | Repeater) where he can add any amount of rows and have it show up on the front-end.


Just an example of what I was supposed to do… basically my client wants to have multiple sections and I wouldn’t know how many sections he would want, its a variable number

All the while, I’ve been shamefully using pre-fixed names because what I had intended for my clients to do was just edit the content within the pre-defined fields itself. And because I was lazy. :(

After a few hours of researching about this, it seems like I’ve managed to solve my issue..?

Firstly, I used the handy-dandy Google, and I got this as one of the search results: List All Sub Fields in a Repeater or Flex Field - ACF Support. I’ve learnt that oh, a Repeater field actually consists of an array. So it means I can iterate through to display the subfields that I want!

The problem is, how do I exactly go about doing this? Using php’s var_dump($array) to ‘inspect’ the array seemed to return me this (for the repeater array):

array(1) { [0]=> array(2) { ["performance_parameters"]=> string(35) "
Performance parameters here

" ["application_area"]=> string(29) "
Application area here

" } }
Enter fullscreen mode Exit fullscreen mode

Somehow, the array structure doesn’t seem to be like the one that was shown on the ACF support page :( Trying to further access the array led me to this (using $array[0]):

array(2) { ["performance_parameters"]=> string(35) "
Performance parameters here

" ["application_area"]=> string(29) "
Application area here

" }
Enter fullscreen mode Exit fullscreen mode

And if I use $array[0][0], I get back NULL.

To be honest, I am still not completely sure why. I’ve tried reading up on index vs associative arrays. But if my field / key names are not pre-fixed, how would I retrieve the values?

More googling turned up these few search results: How to echo an array in PHP? - Stack Overflow & the more precise one for my use case, wordpress - how to list a repeater sub fields with label and value in Advanced Custom Field? - Stack Overflow. In the end, the main idea was to use a foreach to iterate and extract the values, in the following structure:

foreach($array as $key=>$value) {
    // do stuff
}
Enter fullscreen mode Exit fullscreen mode

So this settled the first problem of getting values from a repeater field.

                    <?php

                    $fields = get_field(‘flexible_content’);


//                    $keys = array_keys($repeater);

//                    $repeater2 = array_values($repeater); // does not work, nests another layer of array


                    if($fields){

                    foreach($fields as $field_type => $field){

                            foreach($field as $row) {
                                echo($row);
                            }

                        }
                    }
                    ?>
Enter fullscreen mode Exit fullscreen mode

Next, was the problem of the flexible content field. Strangely, the first field of the flexible content would be its name. I didn’t want to display its name (for now), so I was wondering how to get rid of the first element… As usual I var_dump and look inside what I’m facing:

array(1) { [0]=> array(3) { ["acf_fc_layout"]=> string(8) "row_name" ["test_1"]=> string(14) "
Test 1

" ["test_2"]=> string(428) "
Test 2
Enter fullscreen mode Exit fullscreen mode

I came across this: How to get the first item from an associative PHP array? - Stack Overflow which says to use reset() to retrieve the first element of the array. So I accessed the object itself, and then used reset() as such:

                    <?php

                    $flexibleContent = get_field('flexible_content_2');


                    if($flexibleContent){


                        // A bit of a hack to not display the first field, which is field name
                        $firstValue = reset($flexibleContent[0]);


                        foreach($flexibleContent as $field_type => $field){


                            foreach($field as $row) {

                                if($row === $firstValue) {
                                    // do nothing

                                } else echo $row;
                            }
                        }
                    }
                    ?>
Enter fullscreen mode Exit fullscreen mode

I’m still a bit hazy on how these php arrays actually work, so if anyone can shed some light on this, it’d be great! But I’m pretty happy I learnt some useful stuff like var_dump(), reset(), and iterating through the arrays in general :)

Top comments (2)

Collapse
 
kyleakelly profile image
Kyle Kelly

I may be misunderstanding your requirements, but the built in ACF functions should handle this for you.

If you're using a flexible content field use something like this to loop through the fields and pick out the layout type:

<?php

// check if the flexible content field has rows of data
if( have_rows('flexible_content_field_name') ):

     // loop through the rows of data
    while ( have_rows('flexible_content_field_name') ) : the_row();

        if( get_row_layout() == 'paragraph' ):

            the_sub_field('text');

        elseif( get_row_layout() == 'download' ): 

            $file = get_sub_field('file');

        endif;

    endwhile;

else :

    // no layouts found

endif;

?>

In this example the flexible_content_field_name is the name of the field you setup in ACF and the if/else-if area is where you place your layout code to handle the various flexible content layouts you may have for this field.

Based on your screenshot though, you may not need a flexible layout if the type of content will be the same, just the number of items will be variable then the repeater field should do the job.

If that's the case then the example code should do the trick, I'll customize it to your screenshot:

<?php

// check if the repeater field has rows of data
if( have_rows('field_name_goes_here') ):

    // loop through the rows of data
    while ( have_rows('field_name_goes_here') ) : the_row();

        // display a sub field value
        ?><h3><?php the_sub_field('title'); ?></h3>
          <p><?php the_sub_field('paragraph'); ?></p>
<?php
    endwhile;

else :

    // no rows found

endif;

?>

If I misunderstood completely, please let me know.

Collapse
 
leanminmachine profile image
leanminmachine • Edited

hey there Kyle! thank you for your reply.
Hmm, yeah I think maybe you misunderstood the use case a little.

I wouldn't know the row layout name will be called 'paragraph'. Cos the client would be creating their own rows. Or adding more rows / removing pre-existing ones. Hence I need something that can iterate through pretty generically without a certain row name ;)