ООО «КОДЖЕЗ» (COGEZ LTD), 2025
Продукт: «Code Generation Zemlya» -
мультифункциональная универсальная система генерации кода/текста
Идентификатор - им может считаться последовательность
символов, начинающаяся с буквы латинского алфавита или символа
подчёркивания «_
», и состоящая из символов подчёркивания, букв
латинского алфавита и цифр. Примеры: «my_ident
», «__MyIdent42
»,
«_123
». Не могут содержать символы кирилицы, спецсимволы, пробелы
или начинаться с цифры. Идентификаторы не заключаются в кавычки.
Примеры невалидных идентификаторов: «123_asd
», «"Моя переменная"
».
Пустое значение - В нашем случае, нет "пустоты", как в других
языках (пустые указатели и так далее). Есть признак, что значение
отсутствует - null
(или Null
), но, это тоже является значением.
Ради совместимости с другими языками, в контексте значение null
ещё
представлено ключевым словом none
(как в Python), можно с большой
буквы None
(движок понимает). Null
можно сравнивать с другим
Null
- выражение None == Null
вернёт true
.
Аргумент - То, что передаётся в скобках при вызове Функций,
Фильтров, Тестеров. Синоним: Параметр.
Массив - Последовательность элементов. Хранить может любые
значения. Синонимы: Список, Array, Вектор (Vec, Vector), List.
Маппинг - Объект, хранящий пары "ключ: значение" (key: value
).
Значение может быть чем угодно (строка, число, Массив, другой Маппинг
и т.д.). Ключами могут выступать строки, целые числа (отрицательные
пока не поддерживаются) и булевы значения. Доступ к не строковым
ключам возможен только через функцию get
. При конвертации в JSON не
строковые ключи автоматически преобразуются в строки (формат JSON не
поддерживает). Подробности описаны ниже. Синонимы: Объект (англ.
Object), Мапа (англ. Map, Mapping), Словарь (англ. Dict, Dictionary).
Фильтр - Принимает значение self
и может быть использован
только после символа канала «|
». Возвращает какое-то значение (в
большинстве вариантов модифицированный self
).
Тестер - Похож на Фильтр, только возвращает логический тип -
значение true
/false
. В основном, используются в конструкциях if
для проверки значений. Перед тестером ставится ключевое слово is
.
Функция - Не принимает self
, то есть, её нельзя использовать
после символа канала «|
», вызывается самостоятельно, принимает
аргументы (не обязательно) и что-то возвращает (может возвращать
пустое значение (null
), но производить какие-либо действия).
Существует всего 3 вида разделителей:
{{
» и «}}
» - для выражений (результат выражения выводится на{%
» и «%}
» - для операторов управления, объявлений, директив{#
» и «#}
» - для комментариев (ни на что не влияют, на печать{% raw %}Привет {{ name }}!{% endraw %}
Будет напечатано «Привет {{ name }}!
», то есть, как есть, без
вычислений и подстановок. Не представляет особого интереса,
используется в редких случаях.
Добавьте минус «-
» в разделитель: используйте «{%-
» если вы хотите
удалить все пробелы и переносы строк (пустое пространство) перед
оператором, и «-%}
», если вы хотите удалить всё пустое пространство
после оператора. Это поведение также работает с выражениями, используя
«{{-
» и «-}}
», и с комментариями, используя «{#-
» и «-#}
».
Например, давайте посмотрим на следующий шаблон:
{% set my_var = 42 %}
{{ my_var }}
Будет напечатано:
пустая_строка_сверху
42
"пустая_строка_сверху" - просто обозначение пустой строки.
Если мы хотим избавиться от пустой строки сверху, можем написать
следующее:
{% set my_var = 42 -%}
{{ my_var }}
Или:
{% set my_var = 42 %}
{{- my_var }}
В обоих случаях, пустая строка исчезнет. Пустое пространство удаляется
до первого "значащего" символа.
Чтобы закомментировать часть шаблона, перенесите его в «{#
» и
«#}
». Все, что находится между этими тегами, отображаться не будет.
{# Это комментарий, он не влияет на печать шаблона. #}
{% set my_var = 42 %}{# Это тоже коментарий. #}
{{- my_var }}
{#-
Это многострочный комментарий.
* Всё, что написано в коментариях никогда не попадёт на печать.
-#}
Заведите привычку писать комментарии - это полезно. Через месяц можно
не вспомнить, что это за переменная или на что влияет представленное
выражение.
Их всего несколько:
true
(истина) илиfalse
(ложь), третьего не дано ("не задано" не бывает), так жеTrue
/False
(с большой буквы).
»).
»)'строка'
» или двойными кавычками «"строка"
», либо вот такими`строка`
» (в левом углу клавиатуры под клавишейEsc
»)[
» и «]
», запятая в конце допускается, подробнее вkey: value
),{% set my_map = {"key": "value", 42: 23, true: false, } %}
null
, оно имеет несколько синонимов в языке,null
, Null
,none
, None
Переменные определяются контекстом, заданным при рендеринге
(отрисовке) шаблона. Контекст, это и есть те данные из входных файлов,
которые переданы на рендеринг. Вы можете задать переменную с помощью
{% set my_name_is = "Alex" %}
, и она появится в контексте. Вы можете
отобразить переменную с помощью {{ my_name_is }}
. Можете
использовать переменную где угодно далее в шаблоне
{% if my_name_is == "Alex" %}...{% endif %}
. Но, помните! Попытка
получить доступ к переменной, которой не существует, или отобразить
ее, приведет к ошибке. Есть способы определить существует (задана ли)
переменная - это будет разобрано далее.
Вы можете присваивать значения переменным в процессе рендеринга.
Назначения в циклах for
и макросах ограничены их собственным
контекстом (область видимости переменных), но назначения вне их будут
задаваться в глобальном контексте. Кроме того, назначения в цикле
for
действительны только до конца текущей итерации. Примеры:
{% set my_var = "hello" %}
{% set my_var = 1 + 4 %}
{% set my_var = some_var %}
{% set my_var = macros::some_macro() %}
{% set my_var = global_fn() %}
{% set my_var = [1, true, some_var | round, ] %}
Есть способ присвоить значение переменной в глобальном контексте во
время выполнения цикла for
или в теле макроса, это делается через
set_global
:
{% set_global my_var = "hello" %}
{% set_global my_var = 1 + 4 %}
{% set_global my_var = some_var %}
{% set_global my_var = macros::some_macro() %}
{% set_global my_var = global_fn() %}
{% set_global my_var = [1, true, some_var | round, ] %}
Вне цикла for
или вне макроса, set_global
работает точно также,
как set
.
Внимание! При объявлении уже существующей переменной, её значение
будет перезаписано, а старое значение безвозвратно потеряно.
.
» Если вы имеете дело с Маппингом, и ключи в нём в нормальной форме, то
есть, начинаются с символа подчёркивания, либо латинской буквы и далее
состоят из латинских букв/цифр и символов подчёркивания без каких-либо
спецсимволов и пробелов, то есть, соответствуют правилам,
установленным для идентификаторов, то вы можете получить доступ к
содержимому ключа по упрощённой форме через точку «.
». Пример:
{{ product.name }}
С Массивами всё проще - можно получать доступ к элементам также (через
точку «.
»), но по индексу элемента (порядковый номер начиная с
нуля):
{{ my_array.0 ~ my_array.1 }}
{# Символ тильды `~` работает как конкатенация строк, то есть,
объединяет строки. Будет разобран далее. #}
Если ключ или индекс не найден - будет ошибка. Как получить значение
безопасным способом - описано ниже (смотри «get
» и «nth
»).
[
» и «]
» Более эффективная альтернатива точки «.
». Доступ к значению по ключу
{{ product['name'] }}
или {{ product["name"] }}
для Маппингов. Или
доступ к значению по индексу {{ list[0] }}
для Массивов.
{# Для Маппинга, через переменную: #}
{% set my_key = `name` %}
{{ product[my_key] }}
{# Или более кратко: #}
{{ product['name'] }}
{# И для Массива, тоже самое. #}
{% set my_index = 42 %}
{{ my_array[my_index] }}
{# Или более кратко: #}
{{ my_array[42] }}
Внимание! Если элемент не заключен в кавычки, он будет обрабатываться
как идентификатор (переменная), предполагая, что у вас есть эта
переменная в контексте (если нет, то будет ошибка рендеринга).
В качестве индекса для Массива могут использоваться только переменные,
преобразующиеся в строку или целое число соответственно. Всё
остальное будет ошибкой. То есть, теоретически и с Массивом можно
работать так: {{ my_array["42"] }}
. Но, лучше так не делать -
дополнительные проверки при преобразовании к числу скажутся на
быстродействии, и это реальный шанс внести ошибки.
Важно! Если значение не будет найдено по ключу или по индексу (выход
за диапазон Массива или отсутствие такого ключа в Маппинге), то будет
ошибка. Как получить значение безопасным способом, описано ниже
(см. «get
» и «nth
»).
Выражение - это некоторая последовательность каких-то
вычислений/вызовов. Выражения допускаются практически везде.
Вы можете выполнять некоторую базовую математику, но не следует
злоупотреблять ей, за исключением случая +1
и подобных.
Математические операции разрешены только с числами, их использование с
любыми другими значениями приведет к ошибке. Вы можете использовать
следующие операторы:
+
» - складывает 2 значения, {{ 1 + 1 }}
выведет 2
-
» - выполняет вычитание, {{ 2 - 1 }}
выведет 1
/
» - выполняет деление, {{ 10 / 2 }}
выведет 5
*
» - выполняет умножение, {{ 5 * 2 }}
выведет 10
**
» - выполняет возведение в степень, {{ 2 ** 3 }}
выведет 8
%
» - выполняет преобразование по модулю (остаток от деления),{{ 2 % 2 }}
выведет 0
, {{ 3 % 2 }}
выведет 1
//
» - выполняет целочисленное деление (сколько раз число делится{{ 10 // 3 }}
выведет 3
Приоритет операций следующий:
*
» и «**
» и «/
» и «%
» и «//
» - умножение, деление и т.д.+
» и «-
» - сложение и вычитание во вторуюДругими словами, сначала будут производиться операции деления,
умножения и т.д., затем сложения и вычитания. Используйте скобки для
управления последовательностью операций:
{{ (((4 + 1) / (7 - 5)) + 2) * 2 }}
.
==
» - true
, если значения равны, иначе false
!=
» - true
, если значения НЕ равны, иначе false
>=
» - true
, если левое значение равно или больше правого,false
<=
» - true
, если правое значение равно или больше левого,false
>
» - true
, если левое значение больше правого, иначе false
<
» - true
, если правое значение больше левого, иначе false
and
» - true
, если левый И правый операнды имеют значение true
or
» - true
, если левый ИЛИ правый операнды имеют значениеtrue
not
» - отрицание выражения, то есть true
превращается вfalse
, а false
превращается в true
(используется как приставкаИспользуёте скобки для объединения в группы: (... or ...) and (...)
.
Вы можете объединить несколько строк/чисел/идентификаторов, используя
оператор «~
» (тильда). На клавиатуре он находится под клавишей Esc
(в английской раскладке с нажатым Shift
).
{{ "hello " ~ 'world' ~ `!` }}
{{ an_ident ~ " and a string" ~ another_ident }}
{{ an_ident ~ another_ident ~ 42 }}
Идентификатор, преобразующийся во что-то отличное от строки или числа,
вызовет ошибку.
Важно!!! Оператор объединения «~
» имеет более высокий приоритет, чем
другие операторы, поэтому используйте скобки для группировки:
{{ an_ident ~ "\"" ~ ( 42 + 42 ) ~ "\n" ~ ( another_ident | upper ) }}
in
» Вы можете проверить, содержится ли левая сторона в правой стороне,
используя «in
» оператор.
{{ some_var in [1, 2, 3] }}
{{ 'Great' in product.categories }}
{{ an_ident not in an_obj }}
В правой части поддерживаются только литералы/переменные, приводящие к
Массиву, Строке (тоже, своего рода, Массив из символов) и Маппингу
(проверить существование ключа), всё остальное вызовет ошибку. В левой
части поддерживаются любые значения, но в пределах разумного (не стоит
искать null
или цифру в строке - это вызовет ошибку).
Вы можете изменять переменные с помощью фильтров. Фильтры отделяются
от переменной или значения символом канала |
, и могут иметь
именованные аргументы в круглых скобках. Несколько фильтров могут быть
объединены в цепочку - выходные данные одного фильтра переходят к
следующему.
Например, {{ name | lower | replace(from="junior", to="jun.") }}
примет переменную с именем name
, преобразует в нижний регистр, а
затем заменит все junior
на jun.
. Вся цепочка фильтров выполняется
последовательно.
Вызов фильтров для неправильного типа приведет к ошибке. Каждый фильтр
предусмотрен для каких-то определённых типов, например, lower
и
replace
работают только со строковыми значениями. Но, фильтры у
которых есть аргумент default
, являются исключением - при указании
default
они не вызовут ошибку, а вернут указанное в аргументе
default
значение.
Хотя фильтры можно использовать в математических операциях, они будут
иметь самый низкий приоритет и, следовательно, могут не
соответствовать вашим ожиданиям:
{% set a = [1, 2, 3, ] %}
{{ 1 + a | length }}{# Ошибка! #}
{# Эквивалентно следующей записи #}
{{ ( 1 + a ) | length }}{# Это приведет к ошибке
(сложение числа с Массивом). #}
{# Определить длинну массива `a` и прибавить к результату единицу.
Вот такой вариант позволит сделать то, что вы хотели изначально. #}
{{ ( a | length ) + 1 }}
Целые разделы также могут обрабатываться фильтрами, если они заключены
в теги {% filter name %}
и {% endfilter %}
, где name
- название
фильтра:
{% filter upper %}
Hello
{% endfilter %}
В этом примере весь блок с текстом Hello
преобразуется полностью в
верхний регистр (HELLO
). Это, пожалуй, единственная возможность
использования фильтров не после символа канала «|
».
Тесты могут использоваться после выражения или переменной для проверки
некоторого условия, и выполняются в if
блоках с использованием
ключевого слова is
. Например, вы могли бы написать следующее, чтобы
проверить, является ли выражение или переменная нечетным числом:
{% if my_number is odd %}
число НЕчётное
{% endif %}
Тесты также могут быть логически перевёрнуты с помощью not
:
{% if my_number is not odd %}
число чётное
{% else %}
число НЕчётное
{% endif %}
{# И так тоже можно.
`not` можно ставить как перед фильтром, так и перед выражением. #}
{% if not my_number is odd %}
число чётное
{% else %}
число НЕчётное
{% endif %}
Также тесты можно использовать не только в выражениях «if
»,
например:
{% set is_odd = my_number is odd %}
Если my_number
не чётное число, то переменная is_odd
будет равна
true
(логический тип), иначе false
.
Все тестеры возвращают только булевое значение, то есть true
или
false
.
Функции принимают аргументы и возвращают какое-то (в зависимости от
логики) значение. Например, функция range(end=5)
вернёт Массив из
пяти элементов [0, 1, 2, 3, 4]
. Можно использовать, например, в
цикле:
{% for i in range(end=5) %}
{{ i }}
{% endfor %}
Условные выражения полностью поддерживаются и идентичны тем, что есть
в Python.
{% if price < 10 or always_show %}
Price is {{ price }}.
{% elif price > 1000 and not rich %}
That's expensive!
{% else %}
N/A
{% endif %}
Неопределенные переменные считаются ложными. Это означает, что вы
можете проверить наличие переменной в текущем контексте, написав:
{% if my_var %}
{{ my_var }}
{% else %}
Sorry, my_var isn't defined.
{% endif %}
Каждый if
оператор должен заканчиваться endif
- закрывающим тегом.
Блоки elif
и else
не обязательны.
Важно! Если в оператор if
передано просто значение, пример
{% if value %}...{% endif %}
, то оно, проверяется на существование
в контексте (если не существует, то false
), если значение
существует, то оно проверяется на тип, для булевых значений всё
более-менее ясно, а вот пустые значения в виде пустой строки, числа
ноль, пустых Массивов и Маппингов, тоже будут считаться false
,
то есть, if 0
, if ""
, if []
и подобные вернут false
и
переведут выполнение сразу на блок elif
/else
. В общем, всё как в
Python (неоднозначно и запутано, но так исторически сложилось,
приходится соответствовать). В сложных ситуациях не используйте
краткую запись, а пользуйтесь чёткими условиями
if value is defined
, if value is undefined
,
if value is defined and value == 0
(мы вернёмся ещё к этому ниже,
просто запомните, что это место неоднозначно, и лучше писать более
ясные условия в операторе if
во избежание сюрпризов).
Также в синтаксисе поддерживаются тернарные операторы. Это своего
рода выражения, которые возвращают значения. Например:
{{ "Ok" if my_var is defined else "Fail" }}
, это легко читается как:
если my_var
представлена в контексте, то печатается «Ok
», иначе
«Fail
». Тернарные операторы можно использовать практически везде,
где ожидаются выражения.
Перебирайте элементы в Массиве:
{%- for product in products %}
{{- loop.index }}. {{ product.name }} - {{ product.price }}
{%- endfor %}
Или по символам строки:
{%- for letter in name %}
{%- if loop.index % 2 == 0 %}
{{- letter | upper }}
{%- else %}
{{- letter | lower }}
{%- endif %}
{%- endfor %}
Внутри циклов for доступно несколько специальных переменных:
loop.index
- текущая итерация начиная с единицыloop.index0
- текущая итерация начиная с нуляloop.first
- признак является ли это первой итерациейloop.last
- признак является ли это последней итерациейКаждый for
оператор должен заканчиваться endfor
- закрывающим
тегом.
Вы также можете перебрать Маппинг, используя следующий синтаксис:
{% for key, value in products %}
{{ key }}. {{ value.name }}
{% endfor %}
key
и value
могут быть привязаны к каким угодно переменным, их
просто нужно указать после for
и разделить запятой. То есть,
for k, v in product
, for x, y in product
и так далее.
Вы также можете применить фильтры к источнику данных:
{% for product in products | reverse %}
{{loop.index}}. {{product.name}}
{% endfor %}
Вы также можете выполнять итерации с литеральными Массивами или
Мапингами:
{% for a in [1, 2, 3, ] %}
{{ a }}
{% endfor %}
Наконец, вы можете установить поведение по умолчанию для отображения,
когда источник данных пуст с помощью необязательной директивы
{% else %}
:
{% for product in products %}
{{ loop.index }}. {{ product.name }}
{% else %}
Data no present.
{% endfor %}
Внутри цикла, break
и continue
могут использоваться для управления
итерацией.
Остановить итерацию при достижении значения переменной target_id
:
{% set target_id = 100 %}
{% for product in products %}
{% if product.id == target_id %}{% break %}{% endif %}
{{ loop.index }}. {{ product.name }}
{% endfor %}
Пропустить элементы с четными номерами:
{% for product in products %}
{% if loop.index is even %}{% continue %}{% endif %}
{{- loop.index }}. {{ product.name }}
{% endfor %}
Вы можете вставить дочерний шаблон для отображения с использованием
текущего контекста с помощью тега include
.
{% include "inner/path/childred.jinja" %}
Путь к шаблону должен быть статичной строкой. Такое недопустимо:
{% include "inner/path/" ~ name ~ ".jinja" %}{# Ошибка! #}
Нужно понять следующее. Движок должен заранее знать о подключаемых
шаблонах. Они должны быть статично заданы и заранее известны. Если у
вас есть желание использовать условия для подключения шаблонов, то
пользуйтесь инструкцией if
, пример:
{% if product in ['inner', 'extra'] %}
{% include "inner/child.jinja" %}
{% elif product == `outer` %}
{% include "outer/child.jinja" %}
{% else %}
{# Функция `throw` будет описана ниже. #}
{{ throw(message='missing include template: product "' ~ product ~
'" unknown') }}
{% endif %}
Движок передаёт глобальный пользовательский контекст в директиву
include
. Хотя вы и можете использовать set
значения во вложенных
шаблонах, эти значения существуют только во время рендеринга конкретно
этого подшаблона. Но они передаются и доступны в дочерних (вложенных)
шаблонах ниже по иерархии. В общем, шаблон-родитель не видит
переменных дочернего шаблона, но дочерний шаблон видит всё, что было
объявлено в родительском.
Компоненты - это по сути встроенные функции.
Компоненты могут быть определены, где угодно. Желательно в отдельной
поддиректории и в отдельных файлах. Импортировать не требуется.
Движок автоматически и самостоятельно их найдёт и подключит.
Текущий синтаксис (может немного измениться):
Определение компонента:
{% component func(greeting: string, age: integer, data: map = {})
{"ref": "./ref.json"} %}
{{ greeting }}: {{ body }}{# Да, у компонента есть доступ к телу
при блочном вызове -#}
{% endcomponent %}
Mетаданные (вот эти: {"ref": "./ref.json"}
) необязательны.
Вызовы:
{{ :func() }}
{% :func(greeting="Hello") %}
Anything in there will be available in the component as {{ null -}}
the `body` variable
{% endcomponent :func %}{# Конечное имя необязательно #}
Пока компоненты находятся в процессе разработки, лучше использовать
вложения (include
).
TODO: описаны компоненты будут подробнее позже, когда закончится
их разработка
Напоминаем, фильтры принимают self
, то есть, стоят после символа
канала «|
» (через этот символ, они получают значение с которым
работают).
Преобразует строку, соответственно, в нижний или верхний регистр.
Если self
не является строкой, то эти фильтры вернут ошибку,
подавить ошибку можно задав аргумент default
.
Удаляет пустые пространства (пробелы, переносы строк, непечатаемые
символы), если переменная является строкой. Соответственно, с обоих
концов - trim
, с начала - trim_start
, с конца - trim_end
.
Имеется не обязательный аргумент pat
- это подстрока для удаления.
Если аргумент pat
не указан, то удаляется пустое пространство.
Если self
не является строкой, то эти фильтры вернут ошибку,
подавить ошибку можно задав аргумент default
.
Возвращает строку со всеми ее символами в нижнем регистре за
исключением первого символа, который будет в верхнем регистре.
Преобразует строку в нижний регистр, а первую букву каждого слова
делает заглавной.
Производит замену в строке. Два параметра:
from
- фрагмент строки, который нужно заменитьto
- на что менятьПример:
{{ name | replace(from="Alex", to="Алексей") }}
Добавляет слэши «\
» перед кавычками, переносами строк, возвратами
каретки, табуляциями и слэшами (экранирование). Пример:
{%- set value = `"\\"'\n'"\r"'\t'`%}
До экранирования:
{{ value }}
После экранирования:
{{ value | addslashes }}
Экранирование блоком:
{% filter addslashes -%}
{{ value }} ''""\
{%- endfilter %}
Вывод:
До экранирования:
"\"'
'"
"' '
После экранирования:
\"\\\"\'\n\'\"\r\"\'\t\'
Экранирование блоком:
\"\\\"\'\n\'\"\r\"\'\t\' \'\'\"\"\\
Используется для получения значений по ключу из Маппинга. Ключом может
быть: строка, булево значение или целое число (даже отрицательное).
{# если не найдёт такого ключа, то будет ошибка #}
{{ my_map | get(key="My Key number 42") }}
{# если не найдёт, то вернёт "default 42" #}
{{ my_map | get(key="My Key number 42/content 1",
default="default 42") }}
{# если не найдёт, то вернёт 42 (число) #}
{{ my_map | get(key="My Key number 42/content 2", default=42) }}
Если ключ строковый, и содержит пробелы, спецсимволы и всякую другую
экзотику, то его нельзя использовать как идентификатор. Например:
{{ my_arr.My Key number 42/content 2 }}{# вызовет ошибку парсинга #}
{{ my_arr."My Key number 42/content 2" }}{# тоже вызовет ошибку #}
Есть только два варианта работы с подобными ключами в Маппинге -
воспользоваться квадратными скобками
{{ my_arr.["My Key number 42/content 2"] }}
или через get
. Через
get
безопаснее, если указать default
значение.
Возвращает элемент Массива по индексу (отсчёт начинается с нуля).
Пример: {{ my_array | nth(n=0) }}
. Фильтр nth
вызовет ошибку, если
индекс указанный в аргументе n
вышел за пределы диапазона. Чтобы
подавить эту ошибку, используёте аргумент default
, который может
быть любым значением. Также, позволяется указывать отрицательный
аргумент n
, тогда отсчёт начинается с конца Массива.
Операции над маппингами. Вставка единичного "ключа: значения",
обогащение другим Маппингом и удаление по ключу (списку ключей).
Примеры использования лучше показать кодом:
{# Все операции над Маппингами не изменяют исходный маппинг,
а лишь возвращают новый модифицированный Маппинг, который
можно сохранить, как новое значение, или использовать на месте.
Примечание: Да, создание клона Маппинга и операции над
ним немного сказываются на быстродействии и расходуют
память, но, если вы не сохраняете результаты в переменную,
то, они удаляются сразу после использования. Согласитесь,
удобно без опаски манипулировать исходными Маппингами,
например, до итерации в цикле (что-то добавить или убрать).
Это как конструктор - можно из кубиков собрать
то, что нужно и если это нужно далее, то сохранить, а
если не нужно, то оно само рассыпется на кубики, и кубики
не пострадают. Это удобно.
-#}
{% set map0 = {"key0": 0, } -%}
{% set map1 = {"key1": 1, "key2": 2, true: false, 42: 43, } -%}
map0 append return: {{ map0 | append(values=map1) }}
=> возвратился `map0` обогащённый значениями из `map1`
map0 after append: {{ map0 }} => исходный `map0` не изменился
map1 after append: {{ map1 }} => исходный `map1` не изменился
map0 insert return: {{ map0 | insert(key=1, value=42) }}
=> возвратился `map0` с вставленным одним `key: value`
map0 after insert: {{ map0 }} => исходный `map0` не изменился
map0 delete return: {{ map0 | delete(keys="key0") }}
=> возвратился `map0` с удалённым ключём `key0`
map0 after delete: {{ map0 }} => исходный `map0` не изменился
{% set map2 = map0 | append(values=map1)
| insert(key="key3", value=[1, 2, 3, 42, ])
| delete(keys=42) | delete(keys=true) | delete(keys="key0") -%}
map2 after: {{ map2 }}
{# В `delete` можно указывать один ключ, либо список ключей.
Напоминание: ключами в Маппинге могут быть только строки,
целые числа или логические значения (`true`/`false`). -#}
{% set map2 = map0 | append(values=map1)
| insert(key="key3", value=[1, 2, 3, 42, ])
| delete(keys=[42, true, "key0", ]) -%}
map2 after: {{ map2 }}
map0 after all: {{ map0 }} => исходный `map0` не изменился
Результат:
map0 append return: {"key0": 0, "key1": 1, "key2": 2, true: false, 42: 43}
=> возвратился `map0` обогащённый значениями из `map1`
map0 after append: {"key0": 0} => исходный `map0` не изменился
map1 after append: {"key1": 1, "key2": 2, true: false, 42: 43}
=> исходный `map1` не изменился
map0 insert return: {"key0": 0, 1: 42}
=> возвратился `map0` с вставленным одним `key: value`
map0 after insert: {"key0": 0} => исходный `map0` не изменился
map0 delete return: {} => возвратился `map0` с удалённым ключом `key0`
map0 after delete: {"key0": 0} => исходный `map0` не изменился
map2 after: {"key1": 1, "key2": 2, "key3": [1, 2, 3, 42]}
map2 after: {"key1": 1, "key2": 2, "key3": [1, 2, 3, 42]}
map0 after all: {"key0": 0} => исходный `map0` не изменился
Обрезает строку до указанной длины. Если длина строки меньше, то
строка возвращается, как есть. Пример:
{{ value | truncate(len=42) }}
. По умолчанию фильтр добавит
многоточие (...
) в конце, если текст был обрезан. Вы можете изменить
добавляемую строку, задав аргумент fill
. Например:
{{ value | truncate(len=42, fill="") }}
- ничего не добавит в конце.
Есть возможность задать отрицательную длинну, то есть,
{{ value | truncate( len = -42 ) }}
- отрежет последние 42 символа
и добавит многоточие (...
) уже в начале строки (или то, что указано
в аргументе fill
).
Массив в строку с разделителями:
{%- set my_array = [1, 2, 3] -%}
{{- my_array | join(sep=", ") -}}
Выведет: 1, 2, 3
.
Возвращает количество элементов. Применяется к Массивам, Маппингам и
строкам.
Переворачивает (задом наперёд). Применяется к Массиву или строке.
Сортирует Массив (только Массив) в соответствии с правилами. Если
Массив из чисел, то от наименьшего к наибольшему. Если из строк, то в
соответствии с номерами символов в кодовой таблице UTF-8 (побуквенно).
Если Массив состоит из других Массивов или Маппингов, то
руководствуется длинной каждого Массива/Маппинга (от наименьшего к
наибольшему). Если массив состоит из булевых значений, то true
=0
,
а false
=1
. Если Массив вперемешку, то результат будет не очень. В
общем, каждому элементу Массива будет присвоен индекс, в соответствии
с правилами изложенными выше, далее они выстраиваются по индексам.
Сортировка - сложная тема при данных, которые могут быть разнородны.
Пользуйтесь осторожно.
Если вы уверены, что Массив состоит из однородных объектов, например,
из Массивов или заранее известных структур (Маппингов, например), то
можно сортировать по какому-то атрибуту или Массиву атрибутов
(аргумент attribute
):
{# Если Массив состоит из Маппингов, и сортировка по ключу `name` #}
{{ people | sort(attribute="name") }}{# Сортировка по именам #}
{# Или состоит из Маппингов, в которых точно есть ключ `age` #}
{{ people | sort(attribute="age") }}{# Сортировка по возрасту #}
{# Множественая сортировка #}
{# Сортировка сначала по полу, внутри по возрасту и далее по имени #}
{{ people | sort(attribute=["sex", "age", "name", ]) }}
Убирает дубликаты в Массиве. Только при полной идентичности объектов
дубликаты будут убраны.
Фрагментирует Массив по заданным параметрам start
и end
. Оба
параметра необязательны, и при их опущении будет возвращен один и тот
же Массив. Используйте аргумент start
, чтобы определить, с чего
начать (включительно, по умолчанию - ноль (0
)) и end
аргумент,
определяющий, где остановиться, не включая элемент с этим индексом
(по умолчанию равен длине Массива). start
и end
проиндексированы
с нуля (0
).
{% set my_arr = [0, 1, 2, 3, 4, 5] %}
{# До 3 элемента не включая его - [0, 1, 2] #}
{% for i in my_arr | slice(end=3) %}...{% endfor %}
{# Всё, за исключением первого элемента - [1, 2, 3, 4, 5] #}
{% for i in my_arr | slice(start=1) %}...{% endfor %}
{# Выдаст - [1, 2, 3] #}
{% for i in my_arr | slice(start=1, end=4) %}...{% endfor %}
Вы также можете использовать отрицательные значения индекса для ссылки
на Массив с последнего элемента. -1
относится к последнему индексу,
-2
относится к предпоследнему индексу и так далее. Например:
{# Всё, за исключением 2-х последних элементов - [0, 1, 2, 3] #}
{% for i in my_arr | slice(end=-2) %}...{% endfor %}
{# Два последних элемента - [4, 5] #}
{% for i in my_arr | slice(start=-2) %}...{% endfor %}
Группирует Массив, используя attribute
аргумент. Фильтр принимает
Массив и возвращает Маппинг, где ключами являются значения attribute
преобразованное к строке, а значениями будут Массивы из элементов
исходного Массива, имеющие значение attribute
. Значения, в которых
отсутствует значение attribute
или где attribute
равно null
,
будут отброшены.
{# В результате получим Маппинг с ключами, по возрасту
преобразованными к строке, а значениями будут Массивы из Маппингов
с этими персонами. #}
{{ persons | group_by( attribute = "age" ) }}
Фильтрует значения Массива, возвращая только те значения, где
attribute
равно value
. Значения, в которых отсутствует
attribute
или где attribute
равен null
, будут отброшены.
{# Выбрать всех сорокадвухлетних #}
{{ persons | filter( attribute = "age", value = 42 ) }}
{# Выбрать всех с именем Alex #}
{{ persons | filter( attribute = "name", value = "Alex" ) }}
attribute
- обязательный аргумент. Если аргумент value
не задан,
то будут отброшены элементы, в которых нет заданного attribute
или
он равен null
. Сформулируем иначе - останутся элементы, в которых
есть заданный attribute
, и там есть значение, отличное от null
.
Извлекает атрибут из каждого объекта в Массиве. Аргумент attribute
является обязательным и указывает, что извлекать.
{% set ages = persons | map(attribute="age") | unique | sort %}
Для наглядности применяем ещё фильтры unique
и sort
(описанные
ранее). В результате, в переменной ages
будет отсортированный
список из возрастов всех персон (не повторяющийся список, другими
словами - уникальный).
Фильтр принимает Массив и возвращает новый Массив со значениями из
атрибута with
.
{% set persons = [pers1, pers2, pers3,] %}
{% set persons = persons | concat(with=[pers4, pers5, pers6,]) %}
{% set persons = persons | concat(with=[pers7,] ) %}
{{ persons | concat(with=[pers8,]) | concat(with=[pers9,]) }}
Фильтр concat
никак не влияет на исходный Массив, а только
возвращает новый объединённый Массив.
Возвращает абсолютное значение. Пример: {{ negative_number | abs }}
.
Если negative_number
равно -1
, вывод будет равен 1
. Если
negative_number
равно -3.25
, вывод будет равен 3.25
.
Возвращает число, округленное в соответствии с указанным методом.
Метод по умолчанию - common
, который округляется до ближайшего
целого числа. ceil
и floor
доступны в качестве альтернативных
методов. ceil
- округляет в меньшую сторону, floor
- в большую.
Для выбора точности округления доступен другой необязательный
аргумент - precision
. По умолчанию используется значение 0, которое
округляет до ближайшего целого числа, но вы можете указать до
скольких знаков после запятой округлять.
{{ 42.42 | round }}
{# результат 42 (ближайшее целое) #}
{{ 42.424242 | round(method="ceil", precision=2) }}
{# результат 42.42 #}
{{ -42.424242 | round(method="ceil", precision=2) }}
{# результат -42.43 #}
Обратите внимание на последнюю строку, где результат -42.43
. Это не
опечатка автора. Метод округления ceil
округляет в МЕНЬШУЮ сторону
(-42.43
меньше чем -42.42
). С отрицательными числами метод
работает наоборот, так же как и метод floor
, который вернул бы
округлив в большую сторону: 42.43
и -42.42
.
Преобразует временную метку из строки даты/времени или из числа. По
умолчанию используется формат YYYY-MM-DD
. Синтаксис форматирования
времени заимствован из strftime
, а полная информация доступна на
сайте:
Пример: {{ ts | date }} {{ ts | date(format="%Y-%m-%d %H:%M") }}
Если вы используете строки даты ISO 8601
или временную метку UTC
,
вы можете дополнительно указать часовой пояс для даты, в которой
будет отображаться. Пример:
{{ "2019-09-19T13:18:48.731Z" | date(timezone="Europe/Moscow") }}
{{ "2019-09-19T13:18:48.731Z"
| date(format="%Y-%m-%d %H:%M", timezone="Asia/Shanghai") }}
{{ 1648252203 | date(timezone="Europe/Berlin") }}
Может быть указан язык (за исключением случаев, когда вводится
временная метка без аргумента часового пояса), по умолчанию
используется POSIX
.
Пример:
{{ 1648252203
| date(
format = "%A %-d %B",
timezone = "Europe/Paris",
)
}}
Для конвертации даты-времени из одного формата в другой можно
использовать параметр out_format
(формат на выходе).
Пример:
{{ "05051972" | date(format="%d%m%Y", out_format="%Y-%m-%d") }}
{# Как результат напечатается `1972-05-05` #}
Экранирует символы в строке в соответствии со спецификацией HTML.
&
» => &
<
» => <
>
» => >
"
» (double quote) => "
'
» (single quote) => '
Экранирует символы в строке в соответствии со спецификацией XML.
&
» => &
<
» => <
>
» => >
"
» (double quote) => "
'
» (single quote) => '
Экранирует символы в строке в соответствии со спецификацией XML
специально для Informatica PC. На символ экранирования \
(слэш)
"ругается" в строковых значениях, пришлось добавить код символа:
&
» => &
<
» => <
>
» => >
"
» => "
'
» => '
\
» => \
Разделяет строку по заданным разделителям (аргумент pat
).
Возвращает Массив из строк (частей входящей строки).
{{ path | split(pat="/") }}
Обратите внимание. Предположим, что path
равен //
, то результат
будет таким ["", "", ""]
. То есть, в результате будут пустые строки.
Аргумент pat
не обязательный, то есть, по умолчанию фильтр split
разбивает строку по "пустому пространству".
Преобразует значение в целое число. Аргумент default
может
использоваться для указания значения, которое будет возвращено при
ошибке преобразования, аргумент base
может использоваться для
указания способа интерпретации числа - основания 2
, 8
и 16
-
двоичные, восьмиричные и шеснадцатиричные числа (понимает
префиксы 0b
, 0o
, 0x
соответственно).
Если аргумент default
не указан, то ошибка преобразования остановит
процесс генерации (рендеринга). Не забываем,default
может быть не
только числом, но и любым другим типом.
Преобразует значение в число с плавающей точкой. Аргумент default
может использоваться для указания значения, которое будет возвращено
при ошибке.
Если аргумент default
не указан, то ошибка пойдёт уровнем вверх, и
процесс генерации (рендеринга) будет прерван.
Возвращает строковое представление заданного значения. То есть,
форматирует переданный объект, преобразуя его в строку. Можно просто
вывести объект на печать - происходит точно такое же преобразование
объекта к строке.
Внимание! Это не сериализует объект, как это делает фильтр to_json
,
а только приводит к строковому виду. Результаты могут отличаться.
Гарантий, что это будет строка JSON не даётся. Используйте фильтр
to_json
, если вам требуется корректный JSON.
Возвращает значение по умолчанию, если переменная отсутствует в
контексте (не определена).
{{ value | default(value=0) }}
Это краткая запись для такого выражения:
{% if value is defined %}{{ value }}{% else %}0{% endif %}
Важно!!! Фильтр default
проверяет только существование значения в
контексте, в отличие от if
, который проверяет не только
существование значения в контексте, но и само значение на логическое
(true
/false
), пустоту (null
), пустую строку (""
), на ноль
(0
) (если значение является числом), на пустой Массив или Маппинг.
То есть, {{ "" | default(value="Значение не задано.") }}
-
напечатает пустую строку (""
), так как, пустая строка тоже
значение, и оно задано. Также и в случае с
{{ null | default(value=42) }}
- напечатает null
, т.е.
напечатает НИЧЕГО, так как, значение null
существует в контексте.
Не забываем - null
это тоже значение!
Записывает self
в указанный файл. Если self
является строкой, то
записывает эту строку в файл. Если self
НЕ(!!!) строка, то
преобразует значение к строке в формате JSON (с форматированием и
переносами (pretty)) и записывает в файл. Единственный и обязательный
аргумент (путь к файлу) - file
(тип: строка).
Внимание! Этот фильтр возвращает то же значение, что получил. То есть,
записал значение в файл и передал значение неизменным дальше по
цепочке. Его можно без опаски вставлять в любую цепочку из каналов
«|
» (для "просто посмотреть").
{# Просто посмотреть, что там внутри my_map #}
{{ my_map | write(file="work/rendered/out.txt") | get(key="key 42") }}
{# Или преобразовать значение в YAML, записать в файл и снова
преобразовать (из строки YAML) в объект (на выходе получается
тот же самый объект, что и на входе) #}
{% set first_element = my_arr
| to_yaml
| write(file="work/rendered/out.yaml")
| from_yaml
| get(key=42) %}
Фильтры преобразования в строку (to_...
) и обратно из строки
(from_...
). Другими словами, сериализация (преобразование в
строку)/десериализация(из строки в объект). Это можно делать не только
со словарями и списками, но и с любыми значениями.
Например:
{# Преобразуем объект `d` в строку json.
Параметр `pretty` по умолчанию `false`, то есть, в одну строку,
если поставить в `true`, то будет форматирование с переносами
(human-readable format - удобочитаемый формат). #}
{% set d_string = d | to_json(pretty=true) %}
{# Преобразуем обратно из строки в объект #}
{% set d_object = d_string | from_json %}
{# Теперь d_object полноценный объект #}
Примечание: параметр pretty характерен только для функции
преобразования объекта в строку JSON, остальные форматы итак
human-readable (удобочитаемы), то есть, с форматированием.
Фильтр проверяет self
(что стоит слева от символа |
канала(пайпа))
на существование. Аргументы:
empty
- Массив, содержащий значения, которые нужно считатьself
.yes
- Всё что угодно, любое значение, которое возвратится, еслиself
успешно пройдёт проверку на существование (НЕ найдётсяempty
).no
- Всё что угодно, любое значение, которое будет возвращено, вself
НЕ пройдёт проверку на существование (найдётсяempty
).Все аргументы не обязательны, и могут следовать в любом порядке. Если
аргумент empty
не указан, то, по умолчанию он будет содержать
массив с элементами: null
, пустой Массив, пустой Маппинг, пустая
строка. И, обратите внимание, если вы указываете список значений
empty
, то дефолтные значения уже не будут работать (не забудьте
указать их самостоятельно). Если аргумент yes
не указан, то он
будет равен self
. Если аргумент no
не указан, то он по умолчанию
будет равен null
.
{{ 1 | exist( empty = [1,2,3], yes = "Yes", no = "No" ) }}
{# напечатается "No", потому что, единичка входит в список `empty` #}
Фильтр принимает self
только типа string и возвращает "срез" (часть
строки). Нет обязательных параметров, все не обязательные. Параметры:
start
- с какой позиции начать, целое число (по умолчанию ноль0
)end
- где остановиться, целое число (по умолчанию равно длинеcount
- сколько символов вырезать, целое ПОЛОЖИТЕЛЬНОЕ числоdefault
- любое значение, которое будет возвращено, если неВернёт ошибку в случаях:
default
)default
)self
) не является строкой, считается ошибкойdefault
не спасает, делайте предварительныеend
и count
, ну, тут точноdefault
не спасает)Повторим. Если start
не указан, то считается, что с начала строки
(по умолчанию 0
), если end
не указан, то считается, что до конца
строки (по умолчанию равен длине строки). Проиллюстрируем работу
фильтра на примерах:
Оригинальный text >> "0123456789"
{{ text | substr }} >> "0123456789"
{{ text | substr() }} >> "0123456789"
{{ text | substr(start=0) }} >> "0123456789"
{{ text | substr(start=1) }} >> "123456789"
{{ text | substr(start=5) }} >> "56789"
{{ text | substr(start=1000) }} >> ""
{{ text | substr(start=-1) }} >> "9"
{{ text | substr(start=-5) }} >> "56789"
{{ text | substr(start=-1000) }} >> "0123456789"
{{ text | substr(end=0) }} >> ""
{{ text | substr(end=1) }} >> "0"
{{ text | substr(end=5) }} >> "01234"
{{ text | substr(end=1000) }} >> "0123456789"
{{ text | substr(end=-1) }} >> "012345678"
{{ text | substr(end=-5) }} >> "01234"
{{ text | substr(end=-1000) }} >> ""
{{ text | substr(count=0) }} >> ""
{{ text | substr(count=1) }} >> "0"
{{ text | substr(count=5) }} >> "01234"
{{ text | substr(count=1000) }} >> "0123456789"
{{ text | substr(start=1, count=4) }} >> "1234"
{{ text | substr(start=1, count=1000) }} >> "123456789"
{{ text | substr(start=-7, count=4) }} >> "3456"
{{ text | substr(start=-7, end=4) }} >> "3"
{{ text | substr(start=-5, end=4,
default=null()) }} >> ""
// Вот тут! ^^^^^^^^^^^^^^ Обратите внимание!
// Если `default` не указать, то генерация остановится с ошибкой,
// потому что точка старта находится за точной останова.
// Не однозначная ситуация, видимо ошибка в логике.
// В данном случае, может спасти указание дефолтного значения.
{{ text | substr(start=2, end=-2) }} >> "234567"
{{ text | substr(start=-4, end=-2) }} >> "67"
{{ text | substr(start=-7, count=4) }} >> "3456"
{{ text | substr(start=-7, count=1000) }} >> "3456789"
Обратите внимание, что если start
или end
указать далеко за
пределами строки, то ошибки не будет (они будут автоматически
приведены к началу и/или концу строки соответственно). Это вполне
нормальная ситуация - просто вернётся пустая строка. Но, если вы
указываете одновременно и start
и end
, то будьте осторожны!
Следите за тем, чтоб точка старта всегда стояла до точки останова.
Примечание:
end
иcount
нельзя использовать вместе. Либо одно,
либо другое. Это считается грубой ошибкой, и никакойdefault
тут
не поможет.
Фильтр возвращает строку, где подменяет символы, в соответствии с
регулярным выражением. Аргументы:
reg
- регулярное выражение, захватывающее последовательностиto
- последовательность символов, на которые будут заменены{#- Строка #}
{%- set str =
"_123_ $%^#asdf$&@123gh$^&jkl_123;:,.__$%^&#_ab[]{}$%_876^@" %}
Исходная строка:
"{{ str }}"
{#- Символ-разделитель #}
{%- set separator = "_" %}
{#- Регулярное выражение, которое захватывает с начала строки все
символы, отличные от латинских букв в верхнем и нижнем регистре.
И в конце строки все символы, которые отличны от латинских букв,
цифр и символа-разделителя (захваченное мы будем заменять). #}
{%- set reg_trim = "^[^A-Za-z]+|[^A-Za-z0-9" ~ separator ~ "]+$" %}
{#- Регулярное выражение, которое захватывает все последовательности
символов, отличные от латинских букв и цифр. #}
{%- set reg_clear = "[^A-Za-z0-9]+" %}
{#- Очищаем строку от конечных пробелов и спецсимволов, заменяя все
последовательности одним сепаратором. #}
{%- set str = str | regex_replace(reg=reg_trim, to="")
| regex_replace(reg=reg_clear, to=separator) %}
{#- Печатаем результат #}
Очищенная строка:
"{{ str }}"
Вывод:
Исходная строка:
"_123_ $%^#asdf$&@123gh$^&jkl_123;:,.__$%^&#_ab[]{}$%_876^@"
Очищенная строка:
"asdf_123gh_jkl_123_ab_876"
Подробнее по поддерживаемому синтаксису тут:
Проверяет self
на эквивалент переданному списку в параметре
true_arr
, если значение присутствует, возвращает true
, иначе -
проверяет на эквивалент переданному списку в параметре false_arr
,
если находит соответствие, возвращает false
. Также есть параметр
default
, который возвращается, если значение не нашлось ни в одном
из списков. Параметр default
может быть только true
или false
,
если что-то другое, то будет считаться, что false
.
Параметры могут быть не указаны вообще или частично, значения по
умолчанию для параметров:
true_arr
= [ true, ]
false_arr
= [ false, ]
default
= false
Если self
является строкой, то она автоматически очистится от
лидирующих и конечных пробелов перед поиском по спискам. Этот фильтр
удобно использовать для преобразования различных строковых значений в
логические, например:
{% set my_bool_property = my_val | get_bool(
true_arr = [],
false_arr = [0, false, "false", "False", "No",
"no", "N", "n", "Нет", "нет"],
default = true
) %}
{# То есть, если активного несогласия не обнаружено, то считаем,
что согласен и точка #}
Тесты отличаются от всего остального тем, что всегда возвращают булево
значение. В любом случае возвращается либо true
либо false
.
defined
- вернёт true
, если значение определено в контексте
undefined
- логический перевёртыш, то есть, вернёт true
, если
значение НЕ определено в контексте (аналог value is not defined
)
odd
- вернёт true
, если число НЕ чётное
even
- вернёт true
, если число чётное
Возвращает true
, если данное выражение делится без остатка на
заданный аргумент divisor
.
{% if rating is divisible_by(divisor=2) %}
Divisible
{% endif %}
Возвращает true
, если данная переменная является итерируемой,
то есть, Массив или Маппинг.
Проверяют строку, на "начинается с" или "заканчивается на",
соответственно.
{% if path is starting_with(pat="x/") %}
In section x
{% endif %}
По-русски "содержит". Проверяет для:
{% if username is containing(pat="xXx") %}
User is Bad
{% endif %}
Возвращает true
, если данная переменная является строкой и
соответствует регулярному выражению в аргументе.
{% set name = "king Artur" -%}
{% if name is matching(pat="^[Qq]ueen") %}
Her Royal Highness, {{ name }}!
{% elif name is matching(pat="^[Kk]ing") %}
His Royal Highness, {{ name }}!
{% else %}
Hi {{ name }}!
{% endif %}
Подробное описание синтаксиса регулярных выражений можно найти на этом
ресурсе:
uinteger
- Проверяет значение на то, что это целое положительноеinteger
- Проверяет значение на то, что это целое число (знак ужеfloat
- Проверяет значение на то, что это число с плавающейnumber
- Проверяет значение на то, что это число (любое число,Вернут true, если значение является соответственно: Маппингом,
Массивом, строкой, логическим (true
/false
), пустым значением
(null
).
{% set d = {"key1": "value1"} %}
{{ d is map }}{# напечатает true #}
{{ d is array }}{# напечатает false, так как `d` не является
Массивом #}
По-русски "диапазон". Возвращает Массив целых чисел, созданный с
использованием приведенных аргументов. Есть 3 аргумента, все целые
числа:
end
- остановиться перед, обязательный аргумент (должен бытьstart
)start
- с чего начать, по умолчанию 0step_by
- на какое число увеличивать значение, по умолчанию 1По-русски "сейчас". Возвращает локальную дату-время в виде строки или
временную метку в виде целого числа (если запрошено).
Есть 2 не обязательных аргумента, оба логические (true
/false
) и
оба по умолчанию false
:
timestamp
- возвращать ли временную метку в виде числа вместоdatetime
utc
- возвращать ли дату и время UTC вместо локальногоФорматирование не встроено в глобальную функцию, но вы можете
использовать date
фильтр, подобно этому now() | date(format="%Y")
если вы хотите получить текущий год. Подробнее по формату смотрите
фильтр date
.
Если передать timestamp=true
, то параметр utc
уже не работает.
Он всегда по Гринвичу, и не содержит временной зоны. Поэтому,
эти два параметра взаимоисключающие.
Таймстэмп всегда целое число в секундах, прошедших с даты 1970-01-01,
И, как все целые числа, поддерживает математические операции. Если
вам нужно оперировать с датой, то работайте с ней именно, как с
таймстемпом.
Примеры:
{{ now() }}
напечатает >> 2024-10-17T14:42:48.907501289+03:00
{{ now( timestamp = true ) }}
напечатает >> 1729165368
{{ now( utc = true ) }}
напечатает >> 2024-10-17T11:42:48.907506441+00:00
{{ now( timestamp = true, utc = true ) }}
напечатает >> 1729165368
{{ now( timestamp = true, utc = false ) }}
напечатает >> 1729165368
{{ now() | date() }}
напечатает >> 2024-10-17
{{ now() | date( format = "%Y" ) }}
напечатает >> 2024
{{ now() | date( format = "%d/%m/%Y %H:%M:%S%.6f" ) }}
напечатает >> 17/10/2024 14:42:48.907523
{{ now() | date( format = "%Y%m%d%H%M%S%.6f" ) }}
напечатает >> 20241017144248.907528
{{ now() | date( format = "%Y-%m-%dT%H:%M:%S%.6f" ) }}
напечатает >> 2024-10-17T14:42:48.907532
{{ "2019-09-19T13:18:48.731Z" |
date(format="%Y-%m-%d %H:%M:%S%.6f", timezone="Europe/Moscow") }}
напечатает >> 2024-10-17 17:39:40.511000
{{ "2019-09-19T13:18:48.731Z" |
date(format="%Y-%m-%d %H:%M:%S%.6f", timezone="Asia/Shanghai") }}
напечатает >> 2024-10-17 22:39:40.511000
{{ "2024-10-17T14:39:40.511687132+03:00" |
date(format="%Y-%m-%d %H:%M:%S%.6f", timezone="Europe/Moscow") }}
напечатает >> 2024-10-17 14:39:40.511687
{{ "2024-10-17T14:39:40.511687132+03:00" |
date(format="%Y-%m-%d %H:%M:%S%.6f", timezone="Asia/Shanghai") }}
напечатает >> 2024-10-17 19:39:40.511687
{{ 1648252203 |
date(format="%Y-%m-%d %H:%M:%S%.6f", timezone="Europe/Berlin") }}
напечатает >> 2022-03-26 00:50:03.000000
{{ 0 | date(format="%Y-%m-%d %H:%M:%S%.6f",
timezone="Europe/Moscow") }}
напечатает >> 1970-01-01 03:00:00.000000
{{ now() | date(format="%Y-%m-%d %H:%M:%S%.6f",
timezone="Europe/Moscow") }}
напечатает >> 2024-10-17 14:42:48.907556 <- сейчас в Москве
{{ now() | date(format="%Y-%m-%d %H:%M:%S%.6f",
timezone="Asia/Shanghai") }}
напечатает >> 2024-10-17 19:42:48.907560 <- сейчас в Шанхае
{{ now() | date(format="%Y-%m-%d %H:%M:%S%.6f",
timezone="Europe/Berlin") }}
напечатает >> 2024-10-17 13:42:48.907563 <- сейчас в Берлине
{{ now(timestamp=true)+7*24*60*60 |
date(format="%Y-%m-%d %H:%M:%S%.6f", timezone="Europe/Moscow") }}
напечатает >> 2024-10-24 14:42:48.000000
(+7 дней к текущей дате/времени по Московскому)
Два аргумента:
message
- сообщение в лог, может быть строковым значением, тогдаlevel
- по сути - уровень логирования, варианты: "trace", "debug",Для безопасности (чтоб не "завалить" журнал лога), значение message
обрезается до первых 10 000 символов. Если вы хотите больше, то
используйте вывод в файл с помощью фильтра write
.
По-русски "бросок, выброс". При столкновении с этой функцией,
рендеринг будет остановлен с выбросом ошибки. Существует только один
строковый аргумент:
message
- сообщение, отображаемое как ошибка рендерингаВозвращает случайное целое число в заданном диапазоне. Есть 2
аргумента, оба целые числа:
end
- обязательный аргументstart
- по умолчанию равно 0, если отсутствуетstart
является инклюзивным (то есть, может быть возвращен), а end
является эксклюзивным (то есть, не включённым в диапазон - строго
"до").
Возвращает значение переменной окружения процесса для указанного
имени. Если переменная окружения не найдена, и значение по умолчанию
не задано, то будет ошибка.
name
- имя переменной среды окружения для поиска, обязательныйdefault
- значение по умолчанию, на случай, если переменная средыЕсли переменная среды окружения найдена, она всегда будет строкой, в
то время, как по умолчанию (default
) может быть любого типа.
Возвращает null
, то есть, пустое значение. Соответствует значению
null
в JSON. Можно использовать аналогичные предопределённые
константы: null
, Null
, none
, None
. Это всё синонимы "пустоты".
{# Это всё `null`-ы: -#}
{% set val1 = null() %}
{% set val2 = null %}
{% set val3 = Null %}
{% set val4 = none %}
{% set val4 = None %}
Но, лучше везде пользоваться null
. Остальные синонимы для обратной
совместимости.
Читает файл и возвращает его содержимое в виде строки в кодировке
UTF-8.
{# Читаем файл и сразу парсим json (преобразуем содержимое в объект).
*** Фильтр from_json описан в разделе Фильтры. #}
{%- set data = read(file="something_directory/something_file.json")
| from_json -%}
Можно не только читать и парсить файлы. Фильтр write
может
записывать объект в файл (его описание в разделе Фильтры).
Возвращает первое не пустое значение из переданного списка в аргумент
values
. Пустые строки, строки состоящие только из пробелов,
переносов строк и других пустот - считаются пустыми. Также,
считаются пустыми Массивы и Маппинги нулевой длины.
{{ nvl(
values=[null(), "", " ", [], {}, 1.23, "Не пустая строка",]
) }}
Вернётся значение 1.23
. Потому что, это первое по порядку не
пустое значение. Если все переданные аргументы пусты или их нет, то
вернётся пустое значение (null
).
ООО "КОДЖЕЗ", 2025. Все права защищены.
COGEZ LTD, 2025. All right reserved.
Программа защищена авторским правом действующего законодательства
Российской Федерации, и имеет Свидетельство о государственной
регистрации программы для ЭВМ № 2024681535. Исключительные права
пренадлежат ООО «КОДЖЕЗ». Нелегальное использование, копирование и
распространение преследуется законом.