如何防止灵活的内容字段只呈现最后一项?

How can i prevent a flexible content field to only render the last item?

我正在开发这个灵活的字段,我已经在其中设置了它,以便 wp-admin 中的用户可以更改内容的顺序并添加新的内容模块。但是,如果一个模块被多次使用,则只有最后一个模块可以使用。我相信这是我在循环中做错的事情。您可以看到下面的代码:

基本上,如果用户添加两个 "overview_layout",最后一个将起作用,第一个将不会呈现。你会如何解决这个问题?

我的 ACF:https://pastebin.com/xAuqEtma

$context = Timber::get_context();
$post = new Timber\Post();
$context['post'] = $post;

$context['layout'] = get_field('cancer_type_layout');

if(have_rows('cancer_type_layout')):
  while(have_rows('cancer_type_layout') ): the_row();
    if(get_row_layout() == 'overview_layout'):
      $context['overview'] = array (
        'title' => get_sub_field('ct_overview_title'),
        'text' => get_sub_field('ct_overview_text'),
        'image' => get_sub_field('ct_overview_picture'),
        'class' => 'bg-gray-100',
        'gradient' => true
      );
    elseif(get_row_layout() == 'video_layout'):
      $context['video'] = get_sub_field('ct_video_url');
    elseif(get_row_layout() == 'statlist_layout'):
      $context['statlist'] = array (
        'title' => get_sub_field('ct_statlist_title'),
        'text' => get_sub_field('ct_statlist_text'),
        'list' => get_sub_field('ct_statlist_statlist'),
        'button' => get_sub_field('ct_statlist_button'),
        'buttontext' => get_sub_field('ct_statlist_button_text'),
        'buttonlink' => get_sub_field('ct_statlist_button_link'),
        'buttonfile' => get_sub_field('ct_statlist_button_file')
      );
    elseif(get_row_layout() == 'text_layout'):
      $context['text'] = array (
        'text' => get_sub_field('ct_text_text'),
        'button' => get_sub_field('ct_text_button'),
        'buttontext' => get_sub_field('ct_text_button_text'),
        'buttlink' => get_sub_field('ct_text_button_link')
      );
    elseif(get_row_layout() == 'image_layout'):
      $context['image'] = get_sub_field('ct_image_image');
    elseif(get_row_layout() == 'qoutelist_layout'):
      $context['quotelist'] = get_sub_field('ct_quotelist_quotes');
    elseif(get_row_layout() == 'postlist_layout'):
      $context['postlist'] = get_sub_field('ct_postlist_posts');
    endif;
  endwhile;
endif;

主要问题是您在每个循环中覆盖上下文中的变量。当你在循环中设置$context['overview]时,你设置的内容不会添加现有内容,而是覆盖你已经设置的内容有。如果你想让它工作,你必须使用一个数组并在那里添加你的数据。

$context['overview'] = array();

if ( have_rows( 'cancer_type_layout' ) ):
    while ( have_rows( 'cancer_type_layout' ) ): the_row();
        if ( get_row_layout() == 'overview_layout' ):
            $context['overview'][] = array(
                'title'    => get_sub_field( 'ct_overview_title' ),
                'text'     => get_sub_field( 'ct_overview_text' ),
                'image'    => get_sub_field( 'ct_overview_picture' ),
                'class'    => 'bg-gray-100',
                'gradient' => true
            );

通过使用 $context['overview'][],您可以将数据添加到现有数组中,而不是覆盖它。但是,如果您对每个布局都这样做,您最终会编写大量代码。然后将数据拆分为不同的变量。这将打破布局的顺序,因为您只将相同的灵活内容布局分组到数组中。

我建议使用不同的方法,您不必准备 PHP 中的所有数据并减少必须编写的代码量。

首先,当您使用 get_field() 时,您并没有使用 Timber 的功能。您可以改用 $post->meta()

$context['layout'] = $post->meta( 'cancer_type_layout' );

然后,在您的 Twig 文件中,您可以遍历布局并包含一个显示块的文件:

{% if layout is not empty %}
    {% for block in layout %}
        {% include 'block/' ~ block.acf_fc_layout ~ '.twig' ignore missing %}
    {% endfor %}
{% endif %}

对于您拥有的每个布局,您现在可以使用布局名称创建一个新的 Twig 文件。在该文件中,布局中的所有数据都在 block 变量下可用。

block/overview_layout.twig

{{ block.title }}
{{ block.text }}
{# … #}

block/statlist_layout.twig

{{ block.title }}
{{ block.text }}
{{ block.list }}
<a href="{{ block.buttonlink }}">{{ block.buttontext }}</a>
{# … #}