从 PHP 和 Timber/Twig 中的高级自定义字段中对重复器字段进行排序

问题描述 投票:0回答:3

我正在尝试使用 Twig 1.34 的 WordPress Timber 插件实现对 WordPress 插件高级自定义字段 (ACF) 的转发器字段的输出进行排序。下面从 ACF 进行排序的基本 PHP 示例来自 https://www.advancedcustomfields.com/resources/how-to-sorting-a-repeater-field/ 并且在 ACF 论坛中没有针对我的问题的可用答案.

所以我尝试将此函数从示例转换为 Timber/Twig:

// get repeater field data
$repeater = get_field('repeater');

// vars
$order = array();

// populate order
foreach( $repeater as $i => $row ) {
    $order[ $i ] = $row['id'];
}

// multisort
array_multisort( $order, SORT_DESC, $repeater );

// loop through repeater
if( $repeater ): ?>

    <ul>

    <?php foreach( $repeater as $i => $row ): ?>

        <li><?php echo $row['id']; ?>. <?php echo $row['name']; ?></li>

    <?php endforeach; ?>

    </ul>

<?php endif; ?>

我在

view.twig
文件中实现的有效内容如下。我的 ACF 中继器字段称为时间线,有两个子字段,日期和描述。

{% set repeater = timeline %}

   {% for i, row in repeater %}

      {{ row.date}}

      {{ row.description}}

  {% endfor %}

输出 ACF 中继器的现有字段(一个数组)

timeline
- 两个字段日期和描述 - 按照最早的日期顺序,这是默认值,如下所示:

2010 年 1 月

Lorum Ipsum 等等等等

2011 年 7 月

Lorum Ipsum 等等等等 Lorum Ipsum

但我想先按最新日期排序。

根据这个答案Twig_Error_Syntax for "Unknown filter" with a Twig filter in Timber我需要创建一个使用

Twig_SimpleFilter
的过滤器函数,并对转发器字段数组进行排序。

我已经测试过了,该答案中的示例

rot13
过滤器适用于
{{ 'test text'|rot13 }}

但是当尝试使用相同的

Twig_SimpleFilter
结构与代码按日期对数组进行排序时,即在我的主题的
functions.php
文件中使用它:

add_filter('timber/twig', function($twig) {
   $twig->addExtension(new Twig_Extension_StringLoader());

   $twig->addFilter(
     new Twig_SimpleFilter(
       'sort_timeline', 
       function($string) {

$repeater = get_field('timeline');

$order = array();

foreach( $repeater as $i => $row ) {
    $order[ $i ] = $row['date'];
}

array_multisort( $order, SORT_DESC, $repeater );

       }
     )
   );

   return $twig;
});

并在

{% for i, row in repeater|sort_timeline %}
 中的 for 循环中像这样调用过滤器 
view.twig

{% set repeater = timeline %}

       {% for i, row in repeater|sort_timeline %}

          {{ row.date}}

          {{ row.description}}

      {% endfor %}

我得到的只是白屏,并且 php 日志中没有错误。

FWIW,使用像

rot13
这样的
{% for i, row in repeater|rot13 %}
过滤器也会显示白屏,所以整体
Twig_SimpleFilter
有问题。

(顺便说一句,我还意识到我可能需要转换

$row['date']
中的php日期格式才能正确排序,也许使用
strtotime
,因为现在只是月份和年份。)

在 Twig 中使用过滤器是尝试此操作的正确方法吗?或者是否可以直接在

array_multisort( $order, SORT_DESC, $repeater );
模板中改编并使用
.twig
函数?


编辑2018年4月17日

@num8er 的代码适用于 php5+。 php7 运算符似乎是一个问题。

并且,下面的另一个函数将对中继器的后端行进行排序;更改值并添加到主题的

functions.php
文件中。请参阅https://support.advancedcustomfields.com/forums/topic/sort-repeater-in-back-end-where-data-is-entered/

要获取要排序的行的 MySQL

field_123456789
名称,请转到 ACF 导出页面并导出字段组。 https://support.advancedcustomfields.com/forums/topic/how-to-retrieve-a-group-field-key/

add_filter('acf/load_value/name=timeline', 'my_acf_load_value', 10, 3); //repeater name is timeline
function my_acf_load_value( $rows)
{
 foreach( $rows as $key => $row ) {
  $column_id[ $key ] = $row['field_5967e7639a09b'];

 }

 array_multisort( $column_id, SORT_DESC, $rows );
 return $rows;
}
php wordpress twig advanced-custom-fields timber
3个回答
2
投票

直接解决您的问题。

试试这个代码:

add_filter('timber/twig', function($twig) {
   $twig->addExtension(new Twig_Extension_StringLoader());

   $twig->addFilter(
     new Twig_SimpleFilter(
       'timeline_latest_first', 
       function($timeline) {

         usort($timeline, function($a, $b) {
           if(strtotime($a['date']) === strtotime($b['date'])) return 0;
           return strtotime($a['date']) > strtotime($b['date']) ? -1 : 1; 
           // or simply (if php 7.x):
           // return -1*(strtotime($a['date']) <=> strtotime($b['date']));
         });

         return $timeline;
       }
     )
   );

   return $twig;
});


{% set timeline_sorted = timeline|timeline_latest_first %}

{% for i, row in timeline_sorted %}

  {{ row.date}}

  {{ row.description}}

{% endfor %}

0
投票

在 Twig 中,您可以创建自定义过滤器并将其添加到正在运行的 Twig 环境中。这样,您就可以创建自己的

multisort
过滤器:

$multisort_filter = new Twig_Filter('multisort', function ($repeaters) {
    $order = array();


    foreach( $repeaters as $i => $row ) {
       $order[ $i ] = $row['id'];
    }

    // multisort
    array_multisort( $order, SORT_DESC, $repeaters );

    return $repeaters;
});

然后将其添加到树枝上:

$twig = new Twig_Environment($loader);
$twig->addFilter($filter);

现在您可以从模板中调用

multisort
过滤器。

{% for i, row in repeater|multisort %}

      {{ row.date}}

      {{ row.description}}

{% endfor %}

有关扩展 Twig 的更多信息可以在他们的文档中找到:https://twig.symfony.com/doc/2.x/advanced.html


0
投票

如果需要在页面顶部显示ACF Repeater的最新记录。您可以将记录添加到转发器表的顶部。

© www.soinside.com 2019 - 2024. All rights reserved.