Подтвердить что ты не робот

Модуль (или его отсутствие) в двигателе с шаблоном Ruby Liquid

Я работаю над сайтом 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.

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

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

Спасибо!

4b9b3361

Ответ 1

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

Ответ 2

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

{% assign mod = forloop.index0 | modulo:4 %}
{% if mod == 0 %}
   <!-- Do stuff -->
{% endif %}

Ответ 3

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

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

В каталоге projects/lib добавьте файл liquid_filters.rb:

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

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

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

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

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

{% if modulus == "0" %}
 ..
{% endif %}

Ответ 4

Я использовал еще один трюк в цикле 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

Не очень приятно, но легко.

Ответ 5

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

В моем случае я уже передал оператор if, проверяющий, что есть хотя бы одно сообщение, поэтому я создал первый "row" div вне цикла. Я также закрываю его после цикла 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, и в этом случае мы не хотим открывать новую строку, и пусть wrapping </div> закрыть его.

Ответ 6

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

Ответ 7

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

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

<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>