Support

Account

Home Forums Add-ons Flexible Content Field using a layout twice

Solved

using a layout twice

  • Im using the flexible field as a sort of page builder.
    I created a few layout fields.

    A gallery field, a paragraphs field. A few other fields… Like Gutenberg blocks but with acf. Easier and more support for now 🙂 .

    Everything is great I have a whole system and to works. we have used it now on a few sites.
    Today we had a site where there needed to be two similar sections. I simply added two gallery sections, both with different content and quickly found a bug where only the first one shows up while the second one is completely ignored.

    get_row_layout does not get ALL the layouts :/ it won’t get a layout twice.

    What can I do to get each section? Is it not possible with the acf system? (using have_rows and the_row…)

    If I cant use ACF functions I will have to switch to get_post_meta, I don’t mind. But how can I do this with flexible fields and getting sub fields?
    And getting a wysiwyg field with get_post_meta might not be output with style…

  • So playing around I was able to sort of trick it… I check to see if any layouts are left even if have rows is now false.

    
    $id = get_the_ID();
    
    $sections = get_field( 'sections'); //get the section names
    $sections_count = count($sections); //count them
    
    if( have_rows('sections', $id) ):
    //check if have row OR THERE ARE STILL LAYOUTS LEFT
    
        while( have_rows('sections', $id) || $sections_count ): the_row();
        $section = get_row_layout();
    
    //lower amount of layouts left
    	$sections_count--;
    
    //each layout has its own file. very clean output. It's how I do.
    		if( file_exists( locate_template( 'template-parts/blocks/' . $section . '.php') )) {
    			include( locate_template( 'template-parts/blocks/' . $section . '.php' ) );
    		}
    
        endwhile;
    endif;
  • I can’t say where you’re code is going wrong. You can have any number of layouts and you could repeat the same layout 20 times if you wanted to and each one would have it’s own row.

    The only thing that might upset this is that if the current “Post ID” or the current “Row” is somehow being altered by the code in your template part. This could happen if you are calling wp_reset_postdata() in your template part and it is not working as you expect it to work.

    I also don’t really understand the whole if (file_exists).... part of your code.
    the WP function get_template_part() includes all of those checks and only loads the file if it exists.

    
    if (have_rows('sections')) {
      while (have_rows('sections')) {
        the_row();
        get_template_part('template-parts/blocks/'.get_row_layout());
      }
    }
    
  • Thank you for responding.

    I contacted support with a ticket originally and they said it wasnt possible….
    :/

    So I concocted this crap.

    Now I see that they are wrong and it is possible.
    My issue was one of my layouts had a relationship field.
    I wanted to get the relationship ID’s.
    So I used
    get_sub_field('relationship_field', false)

    This does get the ID’s only but breaks the_row and stops the rest of sections outputting.

    I got the Id’s a different way (got the whole object and then used $object->ID)

    As for the file exists voodoo:

    get_template_part doesnt keep variables so if you make something like this:

    
    $var = 5;
    get_template_part()....
    

    You cant use $var inside that template.
    So it’s kinda stupid.

    This allows you to get a template part without losing your variables, or needing to use global.
    It also uses locate_template which gets the right template if there is a child theme.
    Works nicely 🙂

  • Ah, I understand the reason for what you’re doing with the template pare. There is a way to do this in WP, but it’s complicated.

    The main issue with post loops nested multiple levels is that after the first nesting things go south if you try to use wp_reset_postdata().

    This explanation is for anyone that comes across this in the future as well because it is a very common misunderstanding about how wp_reset_postdata() or even wp_reset_query() works.

    Basically

    
    // lets say that this is the main WP loop
    while(have_posts()) {
      the_post(); // this is the post that wp_reset_post_data() will reset to
      // now you do another query and you have another loop
      if ($nested_query->have_posts()) {
        while($nested_query->have_posts()) {
          $nested_query->the_post();
          // then if you have a 3rd nesting, for example an ACF relationship field
          $related = get_field('relationship_field'));
          foreach ($related as $post) {
            setup_postdata($post);
            
            // do stuff
            
            // resetting post data here completely screws up the nested query loop
            // instead of resetting to the post of the nested loop
            // it resets to the post of the main loop
            wp_reset_postdata();
          }
        } // end while nested posts
        wp_reset_postdata(); // this works correctly
      } // end if nested posts
    } // end main while
    

    rather than using setup_postdata() and wp_reset_postdata() in the 3rd (and beyond) nesting you need to manage these another way and not mess with the global $post value. For example when you say

    I got the Id’s a different way (got the whole object and then used $object->ID)

  • Thanks for the support John.

Viewing 6 posts - 1 through 6 (of 6 total)

The topic ‘using a layout twice’ is closed to new replies.