Скука и рутина это зло

run{}

Mustache, шаблонизатор лишённый логики

Наверное вы уже видели Mustache? Это удобный шаблонизатор, имеющий множество реализаций для различных платформ и исповедующий принцип: «Шаблоны без логики» (logic-less templates). Сейчас немного расскажу что это такое и почему это круто.

Если вы когда-нибудь видели простыню php-кода где весело перемешаны вызовы к БД, обращения к каким-то глобальным переменным, вывод html-шаблона – всё-всё строк эдак в тыщу? Я видел. Это добро к тому же это ещё и постоянно ломалось где-то посередине.

Подобные вещи оставляют глубокое впечатление а также ясное понимание что код нужно структурировать всегда (например с помощью MVC, может как-то иначе), кроме редчайших случаев.

Mustache – это шаг в сторону большей структуризации. В PHP нет чёткого разделения на обычный код и html-шаблоны, в Ruby/Rails есть erb для шаблонов, но даже там можно наварить кашу. Если вы используете Mustache у вас просто нет шансов. Код отдельно, шаблоны отдельно, только так, только хардкор! Вы даже не можете вызвать какой-то фильтр в шаблоне, такой код необходимо писать вне шаблона.

Шаблонизатор принимает JSON-подобную структуру (вложенные словари, списки; строки, числа) и буквально отображает данные на шаблон (разговорным языком, маппит).

Вот пара примеров:

Welcome, would you like some coffee?

{{#drinks?}}
  We can offer some of this:
  {{#drinks}}
    {{name}}
    {{#alcohol?}}
      (only if you older 21)
    {{/alcohol?}}
  {{/drinks}}
{{/drinks?}}

Это собственно шаблон. Ниже несколько примеров входных данных (в формате YAML) и результата.

Здесь drinks? обычное поле, используется для проверки существования списка. (Да, это один из костылей которые планируется исправить в Mustache 2.0)

Если попить нечего:

---
drinks?: true
drinks: []
---
Welcome, would you like some milk?

  We can offer some of this:

Если таки есть:

---
drinks?: true
drinks:
  - { name: wine, alcohol?: true }
  - { name: milk }
---
Welcome, would you like some milk?

  We can offer some of this:
    wine
      (only if you older 21)
    milk

Вот занятный пример того как работает вложенность контекстов, можно определить alcohol? в самом верху (будет как по-умолчанию), и для различных частей входных данных переопределять значение:

---
drinks?: true
drinks:
  - { name: wine }
  - { name: milk, alcohol?: false }
alcohol?: true
---
Welcome, would you like some milk?

  We can offer some of this:
    wine
      (only if you older 21)
    milk

Вообще тэг {{#thing}} работает следующим образом:

  • Если это словарь, то отрисовать содержимое используя новый контекст, с этим словарём.
  • Если это список, то сделать то же что для обычного значения, но для каждого элемента.
  • Если thing ложное значение или пустой список – проигнорировать содержимое.
  • Если не ложное, но не словарь и не список, просто отрисовать содержимое.

Вот пример того, как можно отрисовать один элемент (не список из одного), хотя изначально шаблон писался в надежде что drinks таки будет списком.

---
drinks?: true
drinks: { name: wine, alcohol?: true }
---
Welcome, would you like some milk?

  We can offer some of this:
    wine
      (only if you older 21)

Разумеется у таких шаблонов есть плюсы:

  • Можно использовать на серверной стороне, а также скомпилировать в js-код и отрисовывать в браузере данные, стянутые с помощью AJAX. Удобно и не приходится дублировать код.
  • Можно удобно верстать с правдоподобными тестовыми данными, (на другой платформе) а потом легко подключить в проект. На случай если ваш верстальщик вендузятник.
  • Приятно работать с одним шаблонизатором в разных проектах, на разных платформах.
  • Структуризация и разбиение есть дело православное. Меньше бардака, больше порядка.

и минусы:

  • Вынуждает городить отдельные модули для какой-то мелкой фигни. По-началу раздражает.
  • Если не получается выразить что необходимо с помощью данных и набора partials, то приходится городить уродливые костыли. У самого не случалось, но примеры в сети встречались.

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

Вот здесь потихоньку пилю реализацию mustache на Erlang. (Рабочая версия будет объявлена отдельным постом) Та что указывается как официальная (mustache.erl) недостаточно фитчастая.

Comments