Модуль (или его отсутствие) в шаблонном движке Ruby's Liquid - PullRequest
21 голосов
/ 11 февраля 2010

Я работаю на сайте Jekyll и пытаюсь вывести три столбца div, вложенных в строку div. Liquid делает это довольно легко с помощью фильтра cycle:

{% for p in site.categories.post %}
    {% cycle 'add rows': '<div class="row">', nil, nil %}
        <div class="column">
            <a href="{{ p.url }}">{{ p.title }}</a>
        </div>
    {% cycle 'close rows': nil, nil, '</div>' %}
{% endfor %}

Однако, это действительно работает только при наличии 3, 6, 9 и т. Д. Сообщений.Когда общее количество сообщений не кратно трем, <div class="row"> никогда не закрывается - цикл for заканчивается до того, как закрывающий тег может быть выведен как часть цикла close rows.

В RubyPHP, или любой другой язык, который я мог бы легко исправить с помощью оператора модуля, поэтому в дополнение к циклу close rows я бы вывел </div> при if site.categories.size % 3 == 0.Однако Liquid, потому что это безопасный язык шаблонов, не поддерживает модуль.

Что еще можно сделать, чтобы правильно закрыть <div class="row">, если общее количество сообщений не кратно трем?

Ответы [ 7 ]

13 голосов
/ 04 августа 2014

Я нашел этот способ отлично работать!

{% assign mod = forloop.index0 | modulo:4 %}
{% if mod == 0 %}
   <!-- Do stuff -->
{% endif %}
13 голосов
/ 14 мая 2010

Для вашего конкретного примера вы можете использовать {% cycle 'close rows': nil, '</div>', '</div>' %} после {% endfor %}.

8 голосов
/ 02 июня 2010

Единственный способ на данный момент - написать жидкостный фильтр для достижения этой цели. Зарегистрируйте фильтр где-нибудь в своем коде, где это уместно (в разных местах, если вы используете с рельсами и без них).

Жидкое :: Template.register_filter (LiquidFilters)

В вашем каталоге проектов / lib добавьте liquid_filters.rb:

module LiquidFilters  
  # makes modulus operation available to templates
  def mod(data, param)
    data % param
  end  
end

После этого вы можете использовать его следующим образом в своих шаблонах: {{переменная | мод: 5}}

И если вам нужно использовать его для некоторой логики, вы можете зафиксировать значение.

{% capture modulus %}{{ variable | mod:5 }}{% endcapture %}

Просто я заметил, что захваченное значение является строкой, поэтому для сравнения вы используете

{% if modulus == "0" %}
 ..
{% endif %}
3 голосов
/ 26 сентября 2015

Я понимаю, что вопрос для автора был решен, но недавно я столкнулся с такой ситуацией в Liquid и подумал, что я предоставлю свое решение на случай, если оно поможет кому-то с аналогичными требованиями разметки.

В моем случае я уже передал оператор if, проверяющий наличие хотя бы одного поста, поэтому я создал первый div "row" вне цикла. Я также закрываю его после цикла for. Это защищает от случая, когда есть менее трех сообщений.

<div class="row">

    {% for p in posts %}
        <div class="column">
            <!-- Post code here -->
        </div>
        {% unless forloop.last %}
            {% cycle '', '', '</div><div class="row">' %}
        {% endunless %}
    {% endfor %}

</div>

После каждых трех постов цикл закроет текущую строку и откроет новую unless пост был последним в forloop, и в этом случае мы не хотим открывать новую строку, и пусть упаковка </div> закрой.

3 голосов
/ 09 декабря 2011

Я использовал другой трюк в цикле for: бесполезен в вашем случае, полезен, если вы просто хотите по модулю узнать, закончилась ли ваша строка, и вам нужен новый ряд, как я.

В этом примере я приведу строку из 4 элементов:

{% assign currentRow = 1 %}
# enter the for loop ... then, with 4 as the divisor:
{% if forloop.index == 4 * currentRow %}
  # do whatever you want
  {% assign currentRow = currentRow + 1 %}
{% endif %}
# exit the for loop

Не очень красиво, но легко.

2 голосов
/ 09 августа 2015

Я многому научился из этого поста, и эти три паттерна я использовал в своем проекте. С Bootstrap он тоже отлично работал. Просто измените класс столбца в следующем коде. Вместо столбцов те же шаблоны могут применяться к другим сценариям, где полезно по модулю, таким как нечетно-четные строки. Надеюсь, это кому-нибудь поможет -

Четыре столбца:

<div class="container">
    {% for post in site.posts %}
        {% cycle 'add row' : '<div class="row">', nil, nil, nil %}
            <div class="column">
                <!-- liquid tags here -->
            </div>
        {% cycle 'end row' : nil, nil, nil, '</div>' %}
    {% endfor %}
    {% cycle 'end row' : nil, '</div>', '</div>', '</div>' %}
</div>

Три столбца:

<div class="container">
    {% for post in site.posts %}
        {% cycle 'add row' : '<div class="row">', nil, nil %}
            <div class="column">
                <!-- liquid tags here -->
            </div>
        {% cycle 'end row' : nil, nil, '</div>' %}
    {% endfor %}
    {% cycle 'end row' : nil, '</div>', '</div>' %}
</div>

Два столбца:

<div class="container">
    {% for post in site.posts %}
        {% cycle 'add row' : '<div class="row">', nil %}
            <div class="column">
                <!-- liquid tags here -->
            </div>
        {% cycle 'end row' : nil, '</div>' %}
    {% endfor %}
    {% cycle 'end row' : nil, '</div>' %}
</div>
1 голос
/ 12 февраля 2010

IIRC Liquid не блокирует операцию по модулю, только символ %. Вы можете выполнить модуль без использования оператора %. Например, 14.modulo(3) => 2 вместо 14 % 3.

...