Roots Discourse

ACF Flexible Content setup

I would like to move an ACF Flexible Content Field into Sage, specifically focusing on how to handle Relationship Fields or other loop fields inside a Flexible Content field.

Default ACF way:

<?php if ( have_rows( 'content_blocks' ) ): ?>
 <?php while ( have_rows( 'content_blocks' ) ) : the_row(); ?>
   <?php if ( get_row_layout() == 'text_block' ) : ?>
    <?php the_sub_field( 'text_block_text' ); ?>
   <?php elseif ( get_row_layout() == 'producers' ) : ?>
    <?php the_sub_field( 'producer_title' ); ?>
	<?php $featured_producers = get_sub_field( 'featured_producers' ); ?>
	<?php if ( $featured_producers ): ?>
	 <?php foreach ( $featured_producers as $post ):  ?>
	   <?php setup_postdata ( $post ); ?>
	   <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
	  <?php endforeach; ?>
	  <?php wp_reset_postdata(); ?>
        <?php endif; ?>
	<?php $producers = get_sub_field( 'producers' ); ?>
	<?php if ( $producers ): ?>
	  <?php foreach ( $producers as $post ):  ?>
	    <?php setup_postdata ( $post ); ?>
	      <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
	  <?php endforeach; ?>
	  <?php wp_reset_postdata(); ?>
	<?php endif; ?>
	<?php elseif ( get_row_layout() == 'stats' ) : ?>
	  <?php if ( have_rows( 'stats_items' ) ) : ?>
	    <?php while ( have_rows( 'stats_items' ) ) : the_row(); ?>
	      <?php $stats_items_image = get_sub_field( 'stats_items_image' ); ?>
	      <?php if ( $stats_items_image ) { ?>
	        <?php echo wp_get_attachment_image( $stats_items_image, 'full' ); ?>
	      <?php } ?>
	      <?php the_sub_field( 'stats_items_number' ); ?>
	      <?php the_sub_field( 'stats_items_text' ); ?>
	    <?php endwhile; ?>
	    <?php else : ?>
	      <?php // no rows found ?>
	    <?php endif; ?>
	<?php endif; ?>
	<?php endwhile; ?>
<?php else: ?>
	<?php // no layouts found ?>
<?php endif; ?>

My Controller - app/Controllers/Page.php - for page.php as the ACF Flexible Content Field is default for every page. (Setup from this posts - Anybody using any page builders with sage?)

namespace App\Controllers;

use Sober\Controller\Controller;

class Page extends Controller
{

    public function page_builder()
    {

        $page_builder = get_field('content_blocks');

            $data = [];

            foreach ($page_builder as $block) {
                if ($block['acf_fc_layout'] == 'text_block') {

                    $this_block = (object) [
                        'block_type' => $block['acf_fc_layout'],
                        'text_block_text' => $block['text_block_text'],
                    ];

                    array_push($data, $this_block);

                } elseif ($block['acf_fc_layout'] == 'producers') {

                    $this_block = (object) [
                        'block_type' => $block['acf_fc_layout'],
                        'producer_title' => $block['producer_title'],
                    ];

                    array_push($data, $this_block);

                } elseif ($block['acf_fc_layout'] == 'stats') {

                    $this_block = (object) [
                        'block_type' => $block['acf_fc_layout'],
                    ];

                    array_push($data, $this_block);

                }

            }

            $data = (object) $data;

            return $data;
        }

}

My view:

@foreach ($page_builder as $block)

  @if ($block->block_type == 'text_block')
    @include('partials.page-builder.text-block')
  @elseif ($block->block_type == 'producers')
    @include('partials.page-builder.producers')
  @elseif ($block->block_type == 'stats')
    @include('partials.page-builder.stats')
  @endif

@endforeach

The partials then access the data like - $block->text_block_text

What I need to do is include the logic for a Relationship Field or other loops inside these Objects, then figure out how to access that data.

$this_block = (object) [
  'block_type' => $block['acf_fc_layout'],
  **LOOP / REALTIONSHIP HERE**
];

Are you missing the the following before your page_builder() function?

protected $acf = true;

Thank you, I can piut that in place yes. However I’m looking for some guideance on what a loop might look like in order to access the data.

So the way we work it we create a flexible component let’s say called “hero” and it has a title. We create a file in our views folder in a folder called “flexible” hero.blade.php.

Then in our page (or whatever) template we simply

if( have_rows(‘flexible_content’) ):
while ( have_rows(‘flexible_content’) ) : the_row();
@include(‘flexible.’ . get_row_layout())
endwhile;

endif;

Then in hero.blade.php
section class=‘hero’
h1 {{ get_sub_field(‘title’) }} /h1
/section

This was all written on my phone so I am sure the code is wrong but you get the idea I hope

Thanks. This makes sense as a simple example, but i’m trying to outpout the data in a nested repeater field within a Flexible Content Field.

To highlight my raw ACF functionality:

        <?php elseif ( get_row_layout() == 'stats' ) : ?>
	  <?php if ( have_rows( 'stats_items' ) ) : ?>
	    <?php while ( have_rows( 'stats_items' ) ) : the_row(); ?>
	      <?php $stats_items_image = get_sub_field( 'stats_items_image' ); ?>
	      <?php if ( $stats_items_image ) { ?>
	        <?php echo wp_get_attachment_image( $stats_items_image, 'full' ); ?>
	      <?php } ?>
	      <?php the_sub_field( 'stats_items_number' ); ?>
	      <?php the_sub_field( 'stats_items_text' ); ?>
	    <?php endwhile; ?>
	    <?php else : ?>
	      <?php // no rows found ?>
	    <?php endif; ?>
	<?php endif; ?>

I’m trying to create a setup to run this code through the Controller.

OK so I’ve got a functional setup - not sure it’s the best way to approach this but here it is:

Controller (snippet for relevant example) Page.php

public function pageBuilder()
  {
  $page_builder = get_field('content_blocks');
  $data = [];
  
  if ($page_builder) {
    foreach ($page_builder as $block) {
      if ($block['acf_fc_layout'] == 'stats') {

        $this_block = (object) [
        'block_type' => $block['acf_fc_layout'],
        'stats_intro_subtitle' => $block['stats_intro_subtitle'],
        'stats_intro_title' => $block['stats_intro_title'],
        'stats_intro_text' => $block['stats_intro_text'],
        'stats_items' => $block['stats_items'],
      ];

      array_push($data, $this_block);

    }

    $data = (object) $data;

    return $data;

  }
}

View (snippet for relevant example)

@if ($page_builder)
  @foreach ($page_builder as $block)
    @if ($block->block_type == 'stats')
      @include('partials.page-builder.stats')
    @endif
  @endforeach
@endif

Partial (snippet for relevant example)

@foreach ($block->stats_items as $stat_item)
  {{ $stat_item['stats_items_image'] }}
  {{ $stat_item['stats_items_number'] }}
  {{ $stat_item['stats_items_text'] }}
@endforeach
1 Like