【问题标题】:Twig sort array of objects by fieldTwig 按字段对对象数组进行排序
【发布时间】:2014-10-01 09:36:45
【问题描述】:

我有带有字段的实体:

用户

  • 姓名
  • 姓氏
  • 年龄

还有更多。我用对象用户发送到 Twig 数组。

在表格中显示用户:

 {% for user in users %}
     <td>{{ user.name }}<td> <td>{{ user.lastname}}<td> <td>{{ user.age}}<td>
 {% endfor %}

如何在 Twig 中通过姓名或姓氏等对用户进行排序。我想创建可排序的表。

【问题讨论】:

  • 我认为这不是 twig 的任务。您应该在控制器(或模型,可能更好)中对它们进行排序,并将已经排序的列表传递给 twig。
  • 是的。这不是真正的模板。 1.您说您有两个实体字段,这表明您从数据库中获取了列表。发出请求时在查询中设置排序。

标签: twig


【解决方案1】:

我正在使用 Timber for Wordpress,它仍然使用 Twig 1+,所以我不能使用箭头参数。我刚刚使用 PHP 的 usort 函数创建了一个这样的过滤器:

// sort an array of objects by parameter
$twig->addFilter( new Twig_SimpleFilter( 'sort_by_key', 
    function ( $array, $key, $order = 'asc', $type = 'string' ) {
        usort( $array, function($a, $b) use ($key, $order, $type) {
        $a = $a[$key]; $b = $b[$key];
        if( $type === 'date' ) {
            $a = strtotime( $a );
            $b = strtotime( $b );
        }
        if( $a == $b ) {
            return 0;
        }
        switch( $order ) {
            case 'desc' : case  'DESC' :
                return $a < $b ?  1 : -1;
                break;
            default :
                return $a < $b ?  -1 : 1;
        }
        }  );
        return $array;
    }));

然后在我的树枝模板中:

    {% set array = myArrayOfObjects | sort_by_key('date', 'desc', 'date') %}

适用于高级自定义字段重复器字段。

【讨论】:

    【解决方案2】:

    对于那些使用Collections in Grav 的人,您可以这样做:

    {% for user in users.order("name", "asc") %}
         ...
    {% endfor %}
    

    当然,name 可以是给定对象的任何属性,asc 也可以是desc

    这也适用于点连接属性:

    {% for child in page.children.order("page.headers.foo.bar", "desc") %}
    

    【讨论】:

      【解决方案3】:

      使用新版本的树枝,您可以按冒号排序

      {% set fruits = [
      { name: 'Apples', quantity: 5 },
      { name: 'Oranges', quantity: 2 },
      { name: 'Grapes', quantity: 4 },] %}
      {% for fruit in fruits|sort((a, b) => a.quantity <=> b.quantity)|column('name') %}
          {{ fruit }}
      {% endfor %}
      

      https://twig.symfony.com/doc/2.x/filters/sort.html

      【讨论】:

        【解决方案4】:

        从 Twig 2.12(2019 年 10 月 5 日发布)开始,您可以在 arrow 参数中使用带有箭头函数的 sort 过滤器。

        例如,按名称订购:

        {% for user in users|sort((a, b) => a.name <=> b.name) %}
            <td>{{ user.name }}</td> <td>{{ user.lastname}}</td> <td>{{ user.age}}</td>
        {% endfor %}
        

        Twig 文档:https://twig.symfony.com/doc/2.x/filters/sort.html

        【讨论】:

        • 真棒,最优雅和最简单的解决方案,对我来说就像一个魅力。我认为应该是公认的答案。对于那些想知道的人 是spaceship operator
        • 你知道如何进行多字段排序吗?例如对年龄 desc 排序,然后命名为 asc?
        • @biko |sort((a, b) =&gt; a.age &lt;=&gt; b.age ?: a.name &lt;=&gt; b.name) 这应该可以。如果你想从 asc 切换到 desc(或其他方式),只需用 b 切换 a。
        • 我希望在阅读所有其他内容之前看到这一点。
        • Octobercms 也可以使用!
        【解决方案5】:

        twig 开箱即用,无法按特定字段排序。 您可以在 twig 中使用 PHP asort 按 id 排序,这将是 |sort 过滤器,或者您可以编写一个自定义的 twig 扩展来满足您的需要。

        {% for user in users|sort %}
            ...
        {% endfor %}
        

        并使用 |reverse filter 反转顺序

        {% for user in users|reverse(true) %}
            ...
        {% endfor %}
        

        【讨论】:

          【解决方案6】:

          倒序排列:

          {% for user in users|sort|reverse %}
              ...
          {% endfor %}
          

          排序和反转是可以组合的。

          【讨论】:

            【解决方案7】:

            是的,您可以添加自定义过滤器:

            {% for user in users|usort %}
                ...
            {% endfor %}
            

            然后将扩展/新过滤器添加到 Twig:

            new \Twig_SimpleFilter('usort', array($this, 'usortFilter'))

            public function usortFilter($item){
                usort($item, function ($item1, $item2) {
                    if ($item1['orderNo'] == $item2['orderNo']) return 0;
                    return $item1['orderNo'] < $item2['orderNo'] ? -1 : 1;
                });
            
                return $item;
            }
            

            【讨论】:

            • 我知道这是一个旧的 Q/A,但如果有人在这里徘徊,我不久前创建了这个自定义过滤器:gist.github.com/DarkMukke/f3b0243f957a9f820999e3b18766467b
            • 当我使用这个代码时,我得到了Illegal string offset 'orderNo'
            • @JeremyJohn,因为你的数组中没有orderNo
            • 如何给树枝添加过滤器?
            【解决方案8】:

            您必须在模型中使用“Order by”子句来执行此操作。但是,如果你想要一个可以动态排序的表格,你应该注意 jQuery 表格排序器插件(如果你不想使用 jQuery,或者等效的插件)。

            http://tablesorter.com/docs/

            【讨论】:

              猜你喜欢
              • 2011-05-16
              • 2015-03-11
              • 1970-01-01
              • 2011-10-30
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多