Liquid — различия между версиями

Материал из Insales Wiki
Перейти к: навигация, поиск
(newlines_to_br(input) – дополнить символ "NL" тегом конца строки)
(strip_newlines(input) – вырезать NL)
Строка 163: Строка 163:
 
====strip_newlines(input) – вырезать NL====
 
====strip_newlines(input) – вырезать NL====
  
Фильтр изымает из указанной последовательности символов служебный символ "Новая строка" ''(символ, обозначаемый NL, \n имеющий код '''0ah''')''.
+
Фильтр изымает из указанной последовательности символов служебный символ "Новая строка" ''(символ, обозначаемый NL, \n, имеющий код '''0ah''')''.
  
 
Removes all newlines from the input
 
Removes all newlines from the input

Версия 10:29, 8 января 2010

Содержание

О языке Liquid

Для управление дизайном в InSales используется язык шаблонов Liquid.

Это простой в освоении и достаточно мощный язык. Он был разработан компанией jadedPixel в рамках проекта shopify.com и сейчас является open source проектом.

Более подробная информация о нём, а также полная документация на английском языке находится на сайте: http://www.liquidmarkup.org/.

Более подробная инструкция http://wiki.github.com/tobi/liquid/liquid-for-designers. Справочник: http://liquid.rubyforge.org/.

Введение

В языке Liquid есть два основных вида конструкций: Вывод данных (Output) и Теги (Tag).

  • Вывод данных заключается в {{ двойные фигурные скобки }}
  • Теги заключаются в {% фигурные скобки с процентом %}

Блоки вывода данных всегда заменяются на то, на что они ссылаются. Если в шаблон передаётся информация о товаре через переменную product, то конструкция

{{ product.title }}

выведет его имя.

Теги управляют логикой шаблонов. При их помощи вы можете организовывать циклы и логику ветвления.

Вывод данных

Пример вывода данных:

 Привет, {{ name }}!
Привет, {{ user.name }}!
Привет, {{ 'Имярек' }}!


Фильтры

Для преобразования выходных данных можно использовать фильтры. Фильтры это обычные функции.

Первый аргумент пишется слева от имени фильтра и отделяется от него символом "|" (труба).

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

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

 Привет, {{ name | upcase }}!
 В слове 'магазин' {{ 'магазин' | length }} букв
 {{ product.sale_price | money }} 

Результат выполнения фильтра может быть первым аргументом для следующего фильтра, находящегося справа от него, если таковой имеется.

 {{ array | sort | last }} 

Если у фильтра больше одного аргумента, то остальные аргументы перечисляются справа от имени фильтра после символа ":" (двоеточие) через запятую:

 {{ 'Яндекс' | link_to: 'http://yandex.ru' }} => <a href="http://yandex.ru" title="">Яндекс</a> 
 {{ 'Яндекс' | link_to: 'http://yandex.ru', 'ссылка на яндекс' }} => <a href="http://yandex.ru" title="ссылка на яндекс">Яндекс</a> 

Список стандартных фильтров Liquid

Далее словом input обозначается первый аргумент фильтра; тот, что записывается слева от названия фильтра, словом array - массив; словом text - текстовая последовательность символов.

capitalize(input) – преобразовать первую букву строки в заглавную

Фильтр используется для преобразования первой буквы строки в заглавную

Пример:

@   {{ 'string' | capitalize }} #=> String @

escape(input) - преобразовать ссылку в esc-последовательность

Фильтр используется для преобразовывания текста ссылки в esc-последовательность; что необходимо, например, при применении в URL символов, отсутствующих в кодировке "Latin-1".

Use this filter to escape a string.

Пример:

@   {{ link.title | escape }}  @

append(input, ' ') - добавить символы к концу строки

Фильтр используется для добавления указанных символов к концу указанной строки.

Use this filter to append characters to a string.

Пример:

@   {{ 'sales' | append: '.jpg' }} #=> sales.jpg @

prepend(input, ' ') - добавить символы к началу строки

Фильтр используется для добавления указанных символов к началу указанной строки.

Use this filter to prepend characters to a string.

size(input) – вернуть размер массива или строки

Возвращает размер массива или строки.

Return the size of an array or string

Пример:

@   {{ 'this is an 30 character string' | size }} #=> 30 @

sort(input, property = z) – отсортировать массив

Фильтр используется для сортировки массива.

Пример:

Здесь должен быть пример

join(input, segmenter = ' ') – соединить элементы массива в строку

Фильтр объединяет массив в строку, используя как разделитель элементов указанную последовательность символов.

"joins" an array with the specified character.

Пример:

@   {{ product.tags | join: ', ' }} #=> wooden, deepsnow, season2006 @

downcase(input) – преобразовать строку к нижнему регистру

Фильтр преобразовывает строку к нижнему регистру.

convert a input string to 'downcase'

Пример:

@   {{ 'StRiNg' | downcase }} #=> string @

upcase(input) – преобразовать строку к верхнему регистру

Фильтр преобразовывает строку к верхнему регистру.

convert a input string to UPCASE

Пример:

@   {{ 'StRiNg' | downcase }} #=> STRING @

strip_html(text) – вырезать html-теги

Этот фильтр мзымает из указанного текста все HTML-теги. Очень эффективен в сочетании с truncate.

This will strip all html tags from the text passed to the block. Very useful in combination with truncate.

strip_newlines(input) – вырезать NL

Фильтр изымает из указанной последовательности символов служебный символ "Новая строка" (символ, обозначаемый NL, \n, имеющий код 0ah).

Removes all newlines from the input

truncate(input, characters = x) – обрезать строку до x символов

Фильтр укорачивает строки до указанного количества символов удалением конца строки.

В случае, если обрабатываемый текст содержит HTML-теги, можно сперва применить фильтр strip_html(см. выше). Truncate a string down to x characters. Take care with truncating text which has html elements in it. In these cases you probably want to run the string through the strip_html filter first (see below).

truncatewords(input, words = y) - обрезать строку до y слов

Фильтр укорачивает строку до указанного количества символов удалением конца строки.

Truncate string down to y words

date(input, format) - преобразовать формат даты к нужному

Фильтр преобразует формат даты в указанный (все даты - григорианского календаря) Reformat a date

%a - Сокращённое обозначение дня недели The abbreviated weekday name (``Sun'')

%A - Полное обозначение дня недели The  full  weekday  name (``Sunday'')

%b - Сокращённое обозначение названия месяца The abbreviated month name (``Jan'')

%B - Полное обозначение названия месяца The  full  month  name (``January'')

%c - Предпочтительное местное представление даты и времени The preferred local date and time representation

%d - День месяца (01..31) Day of the month (01..31)

%H - Час суток, 24-часовое представление (00..23) Hour of the day, 24-hour clock (00..23)

%I - Час суток, 12-часовое представление (01..12) Hour of the day, 12-hour clock (01..12)

%j - Номер дня года (001..366) Day of the year (001..366)

%m - Номер месяца года (01..12) Month of the year (01..12)

%M - Номер минуты часа (00..59) Minute of the hour (00..59)

%p - Указатель времени суток (``AM''  or  ``PM'') ''после полудня'' или ''до полудня'' соответственно Meridian indicator (``AM''  or  ``PM'')

%S - Секунда минуты (00..60) Second of the minute (00..60)

%U - Неделя текущего года, начиная с первого воскресенья года как первого дня первой недели (00..53) Week number  of the current year, starting with the first Sunday as the first day of the first week (00..53)

%W - Неделя текущего года, начиная с первого понедельника года как первого дня первой недели (00..53) Week  number  of the current year, starting with the first Monday as the first day of the first week (00..53)

%w - Номер деня недели (Воскресенью соответствует 0, 0..6) Day of the week (Sunday is 0, 0..6)

%x - Предпочтительное представление только даты, без указания времени Preferred representation for the date alone, no time

%X - Предпочтительное представление только времени, без указания даты Preferred representation for the time alone, no date

%y - Номер года двузначный (00..99) Year without a century (00..99)

%Y - Номер года четырёхзначный Year with century

%Z - Имя временной зоны Time zone name

%% - Обозначает символ ``%'' Literal ``%'' character

first(array) – вернуть первый элемент массива

Фильтр возвращает первый элемент из массива Get the first element of the passed in array

Пример:

<code>
{{ product.images | first | to_img }}
</code>

last(array) – вернуть последний элемент массива

Фильтр возвращает элемент из массива Get the last element of the passed in array

Пример:

<code>
{{ product.images | last | to_img }}
</code>

newlines_to_br(input) – дополнить символ "NL" тегом конца строки

Фильтр добавляет тег конца строки <br /> перед каждым служебным символом "Новая строка" (символ, обозначаемый NL, \n, имеющий код 0ah).

Inserts a <br /> linebreak tag in front of every \n linebreak character.

replace(input, substring, replacement) - заменить все

Фильтр заменяет все вхождения в input последовательности substring на последовательность replacement Will replace all occurrences of a string with another.

Пример:

{{ product.description | replace: 'super', 'mega' }}

replace_first(input, substring, replacement) - заменить первый

Фильтр заменяет первое вхождение в input последовательности substring на последовательность replacement Will replace the first occurrence of a string with another.

Пример:

{{ product.description | replace_first: 'super', 'mega' }}

remove(input, substring) - удалить все

Фильтр удаляет из input все вхождения последовательности substring Removes all occurrences of the substring from the input.

Пример:

{{ product.description | remove: 'way too expensive'}}

remove_first(input, substring) - удалить первый

Фильтр удаляет из input первое вхождение последовательности substring Removes only the first occurrence of the substring from the input.

Пример:

{{ product.description | remove_first: 'remove-me'}}

plus(input, operand) - сложить

Фильтр возвращает результат сложения input и operand. Если это строки, то они приводятся к формату "целое" перед сложением. Gets the result of adding input to operand. When strings are passed, it parses strings as integers before adding.

Пример:

Showing {{ paginate.current_offset }}-{{ paginate.current_offset | plus: paginate.page_size }} items

minus(input, operand) - вычесть

Фильтр возвращает результат вычитания operand из input. Если это строки, то они приводятся к формату "целое" перед вычитанием. Gets the result of subtracting input from operand. When strings are passed, it parses strings as integers before adding.

Пример:

{{ product.price | minus: 10 | money_with_currency }}

times(input, operand) - умножить

Фильтр возвращает результат умножеия input и operand.

Пример:

{{ ‘foo’ | times:4 }} #=> ‘foofoofoofoo’
{{ 5 | times:4 }} #=> 20

divided_by(input, operand) - умножить

Фильтр возвращает результат деления input на operand.

Пример:

{{ 10 | divided_by:2 }} #=> 5

Список специфических фильтров в системе InSales

В ПО InSales дополнительно к стандартным реализовано несколько специфических фильтров.

asset_url

Фильтр формирует полный путь до ассета темы

{{ 'reset.css' | asset_url }}

global_asset_url

Фильтр формирует полный путь до глобального ассета (файлы, доступные для всех магазинов)

{{ 'shadowbox/shadowbox.js' | global_asset_url }}

money

Фильтр выводит сумму денег

{{product.sale_price | money}}

locale_url

Фильтр преобразует URL с учетом текущего языка (нужно только в мультиязычных магазинах)

  {{'/page/about' | locale_url}}

Выражения сравнения

При сравнении доступны следующие операторы:

==равенство
!=неравенство
<>неравенство
<меньше
>больше
>=больше либо равно
<=меньше либо равно
containsстрока слева содержит строку справа
andлогическое и
orлогическое и

Для вызова фильтров при сравнении надо использовать ".", а не "|"'. Так можно использовать только фильтры с одним аргументом.

 {% if array.size > 10 %}   - правильно
 {% if array | size > 10 %} - неправильно

Обратите внимание на отсутствие оператора отрицания; если вам нужно отрицание, надо либо преобразовать условие, либо использовать else, а основную ветку оставить пустой.

  {% if product.title contains 'asus' %}
  {% else %}
     ...
  {% end %}

При сравнении объектов разного типа, например, чисел со строками, всегда возвращается false.

  {% if products.size == 0 %}    - правильно
  {% if products.size == '0'  %} - неправильно

При обращении к несуществующим методам тоже возвращается false.

  {% if products.size == 0 %}    - правильно
  {% if products.empty %}        - не вернет ошибку, но будет всегда возвращать false 

Список значений, которые при приведении к Boolean становятся false в языке Liquid, совпадает с языком ruby, который сильно отличается от аналогичного списка в PHP.

False

  • false
  • nil


True - все остальное

  • “”
  • 0
  • “0”
  • “false”

Теги

Теги используются для добавления логики в шаблон.

Комментарии

Комментарий должен начинаться с "{% comment %}" и заканчиваться "{% endcomment %}". Все что заключено между этими тегами будет игнорироваться и не попадёт на конечную страницу. Комментарии могут быть как однострочными так и многострочными.

{% comment %} закомментированный текст {% endcomment %}

Условия If / Else / Unless

Оператор позволяет проверить условие и, в зависимости от результата, выполнить ту или иную ветку. Оператор Unless, в отличии от оператора If, удобен, если надо проверить отрицание условия, так как в Liquid нет оператора отрицания.

{% if user %}
  Привет, {{ user.name }}
{% endif %}

{% if user.name == 'Вася' %}
  Привет, Вася!
{% endif %}

{% if product.title contains 'колбаса' %} 
  Это колбаса
{% endif %}

{% unless product.title contains 'колбаса' %} 
  Это не колбаса
{% endunless %}

{% if product.description == null %}
   В разработке
{% endif %}

Конструкция Case

Если у вас несколько проверок на равенство, то удобно использовать Case.

{% case condition %} 
{% when 1 %} 
hit 1 
{% when 2 %} 

hit 2 
{% else %} 
elseblock 
{% endcase %} 


{% case template %}
	
{% when 'index' %}
     // {{ page.title }}
{% when 'product' %}
     // {{ product.title }}
{% else %}
     // {{ title }}
{% endcase %}

Чередование Cycle

Часто есть необходимость чередовать цвета, для таких задач в Liquid есть тег cycle. Например,

{% cycle 'odd', 'even' %}<br /> 
{% cycle 'odd', 'even' %}<br /> 
{% cycle 'odd', 'even' %}<br /> 
{% cycle 'odd', 'even' %}

вернёт:

odd
even
odd
even

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

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

{% cycle 'group 1': 'odd', 'even' %}<br /> 
{% cycle 'group 1': 'odd', 'even' %}<br /> 
{% cycle 'group 2': 'one', 'two', 'three' %}<br /> 
{% cycle 'group 2': 'one', 'two', 'three' %} 

вернёт:

odd
even
one
two

Цикл For

Цикл применяется для обхода массивов

{% for item in array %} 
  {{ item }}
{% endfor %}

При обходе массива доступны дополнительные переменные:

 forloop.length      # => количество элементов в массиве
 forloop.index       # => номер текущей итерации 
 forloop.index0      # => номер текущей итерации (считая от нуля) 
 forloop.rindex      # => сколько элементов осталось
 forloop.rindex0     # => сколько элементов осталось (считая от нуля)
 forloop.first       # => первая итерация?
 forloop.last        # => последняя итерация?

Можно задавать сдвиг и максимальное число элементов для обхода:

limit позволяет ограничить число обходимых элементов. offset позволяет начать обход с n-ого элемента.

  # Если array = [1,2,3,4,5,6] ...
  {% for item in array limit:2 offset:1 %} 
    {{ item }}
  {% endfor %}
  # вернёт 2,3

Вместо обхода значений существующего массива, можно задать диапазон чисел, которые надо обойти. Диапазон можно прописать в коде или задать переменной:

  # Если item.quantity = 4 ...
  {% for i in (1..item.quantity) %}
    {{ i }}
  {% endfor %}
  # вернёт 1,2,3,4

Таблицы

Liquid can create table rows and cells for you (you still need to wrap a table tag around the tablerow instruction):

Используя Liquid, можно создавать таблицы (аналогично с циклом for), при этом нужно применить тег table, обрамляющий инструкцию tablerow:

  {% tablerow item in items cols: 2 limit: 6 %}
    {{ item }}
  {% endtablerow %}

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

  tablerowloop.length       # => количество элементов в массиве
  tablerowloop.index        # => номер текущей итерации 
  tablerowloop.index0       # => номер текущей итерации (считая с нуля) 
  tablerowloop.rindex       # => сколько элементов осталось
  tablerowloop.rindex0      # => сколько элементов осталось (считая  с нуля)
  tablerowloop.first        # => первый элемент?
  tablerowloop.last         # => последний элемент? 
  tablerowloop.col          # => номер колонки в текущей строчке
  tablerowloop.col0         # => номер колонки в текущей строчке (считая с нуля)
  tablerowloop.col_first    # => первая колонка?
  tablerowloop.col_last     # => последняя колонка?

Определение переменных

При помощи тега assign вы можете определять и менять значения своих переменныx, которые потом будут использованы наравне с имеющимися.

  {% assign name = 'свежая' %}
  {% for product in collection.products %}{% if product.description contains name %}
     <p>Свежая!</p>
  {% endif %}{% endfor %}

Для объединения нескольких переменных в одну строку, которая становится значением новой переменной, удобно использовать тег capture. При этом содержимое тегов попадает в переменную с указанным именем (в примере select_id), а не в итоговый текст.

  {% capture select_id %}option-{{ option.id }}{% endcapture %}

  <label for="{{ select_id }}">Цвет:</label>
  <select name="options[{{ option.id }}][]]" id="{{ select_id }}">
    <option value="black">Черный</option>
    <option value="yellow">Жёлтый</option>
    <option value="white">Белый</option>
  </select>

Примеры использования Liquid

Как сделать хлебные крошки для текущей коллекции?

 {% for collection in current_collections %}
    <a href="{{ collection.url }}">{{ collection.title }}</a>
 {% endfor %}