Pug - интерполяция, фильтрация, текст

plug and filter
  1. Интерполяция
  2. Plain text
  3. Фильтры

Интерполяция

Строковая интерполяция

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

- var title = "On Dogs: Man's Best Friend";
- var author = "enlore";
- var theGreat = "<span>escape!</span>";

h1= title
p Written with love by #{author}
p This will be safe: #{theGreat}
<h1>On Dogs: Man's Best Friend</h1>
<p>Written with love by enlore</p>
<p>This will be safe: &lt;span&gt;escape!&lt;/span&gt;</p>

В случае с title идёт обычное добавление текста. Чтобы вставить переменную непосредственно в текст её нужно заключить между #{ и }.

Внутри #{ и } может быть Javascript код.

- var msg = "not my inside voice";
p This is #{msg.toUpperCase()}
<p>This is NOT MY INSIDE VOICE</p>

Pug достаточно умен, чтобы понять, где заканчивается выражение, так что можно использовать символ } без экранирования.

p No escaping for #{'}'}!
<p>No escaping for }!</p>

Если вам нужно использовать # {, вы можете либо использовать \, либо использовать интерполяцию.

p Escaping works with \#{interpolation}
p Interpolation works with #{'#{interpolation}'} too!
<p>Escaping works with #{interpolation}</p>
<p>Interpolation works with #{interpolation} too!</p>

Вставляем не экранированный код

- let riskyBusiness = "<em>Some of the girls are wearing my mother's clothing.</em>";
.quote
  p Joel: !{riskyBusiness}
<div class="quote">
  <p>Joel: <em>Some of the girls are wearing my mother's clothing.</em></p>
</div>

Имейте в виду, что добавление неэкранированного контента в шаблоны может быть не безопасным, если этот контент исходит от ваших пользователей. Никогда не доверяйте пользовательскому вводу!

Интерполяция тегов

Интерполяция работает не только для значений JavaScript, но и для Pug. Используйте синтаксис тегов, например:

p.
  This is a very long and boring paragraph that spans multiple lines.
  Suddenly there is a #[strong strongly worded phrase] that cannot be
  #[em ignored].
p.
  And here's an example of an interpolated tag with an attribute:
  #[q(lang="es") ¡Hola Mundo!]
<p>This is a very long and boring paragraph that spans multiple lines. Suddenly there is a <strong>strongly worded phrase</strong> that cannot be
  <em>ignored</em>.</p>
<p>And here's an example of an interpolated tag with an attribute:
  <q lang="es">¡Hola Mundo!</q></p>

Можно сделать то же самое для HTML-тэгов. Для этого оберните объявление тега в # [и].

Управление пробелами

Синтаксис интерполяции тегов особенно полезен для встроенных тегов, где важно наличие пробела до и после тега. Однако по умолчанию Pug удаляет все пробелы до и после тегов. Посмотрите на следующий пример:

p
  | If I don't write the paragraph with tag interpolation, tags like
  strong strong
  | and
  em em
  | might produce unexpected results.
p.
  If I do, whitespace is #[strong respected] and #[em everybody] is happy.
<p>If I don't write the paragraph with tag interpolation, tags like<strong>strong</strong>and<em>em</em>might produce unexpected results.</p>
<p>If I do, whitespace is <strong>respected</strong> and <em>everybody</em> is happy.</p>

Plain text

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

Inline in a Tag

Самый простой способ добавить текст. Первое слагаемое в строке - это сам тег. Все, что находится после тега и одного пробела будет текстовым содержимым этого тега. Это наиболее полезно, когда текстовое содержимое короткое (или если вы не против длинных строк).

p This is plain old <em>text</em> content.
<p>This is plain old <em>text</em> content.</p>

Literal HTML

Строки обрабатываются как обычный текст, когда они начинаются с левой угловой скобки (<), что иногда может быть полезно для написания тегов HTML в местах, которые в противном случае могли бы быть неудобными, например - условные комментарии. Поскольку теги HTML не обрабатываются, они не закрываются самостоятельно, в отличие от тегов Pug.

<html>

body
  p Indenting the body tag here would make no difference.
  p HTML itself isn't whitespace-sensitive.

</html>
<html>

<body>
  <p>Indenting the body tag here would make no difference.</p>
  <p>HTML itself isn't whitespace-sensitive.</p>
</body>

</html>

Piped Text

Еще один способ добавить простой текст к шаблонам - это поставить префикс |. Этот метод полезен для смешивания простого текста со встроенными тегами, как мы обсудим позже, в разделе Управление пробельными символами.

p
  | The pipe always goes at the beginning of its own line,
  | not counting indentation.
<p>The pipe always goes at the beginning of its own line, not counting indentation.</p>

Block in a Tag

Часто вам могут понадобиться большие блоки текста внутри тега. Например кода JavaScript и CSS в тегах script и style. Для этого добавьте точку сразу после имени тега или после закрывающей скобки, если тег имеет атрибуты.

script.
  if (usingPug)
    console.log('you are awesome')
  else
    console.log('use pug')
<script>
  if (usingPug)
    console.log('you are awesome')
  else
    console.log('use pug')
</script>

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

div
  p This text belongs to the paragraph tag.
  br
  .
    This text belongs to the div tag.
<div>
  <p>This text belongs to the paragraph tag.</p><br/>This text belongs to the div tag.
</div>

Управление пробелами

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

  1. Pug удаляет отступы и все пробелы между элементами. Таким образом, закрывающий тег элемента HTML будет касаться открывающего тега следующего. Как правило, это не проблема для элементов уровня блока, таких как абзацы, потому что они все равно будут отображаться как отдельные абзацы в веб-браузере (если вы не изменили их свойство отображения CSS). Если нужно вставить пробел между элементами, смотри методы описанные ниже.
  2. Pug сохраняет пробелы внутри элементов в том числе:
    * все пробелы в середине строки текста
    * ведущий пробел за отступом блока
    * замыкающий пробел
    * разрывы строк внутри простого текстового блока или между piped строками |.

Pug убирает пробелы между тегами, но сохраняет их внутри. Такое поведение дает контроль над тем, должны ли теги и/или простой текст касаться.

| You put the em
em pha
| sis on the wrong syl
em la
| ble.
You put the em<em>pha</em>sis on the wrong syl<em>la</em>ble.

Если нужно чтобы точка появлялась за пределами гиперссылки в конце предложения - этого легко добиться, поскольку это поведение по умолчанию, если вы не укажете Pug иначе.

a ...sentence ending with a link
| .
<a>...sentence ending with a link</a>.

Если вам нужно добавить пробел, у вас есть несколько вариантов

Рекомендуемые решения

Вы можете добавить одну или несколько пустых pipe line. Это вставит пробел в HTML.

| Don't
|
button#self-destruct touch
|
| me!
Don't <button id="self-destruct">touch</button> me!

Если встроенные теги не требуют большого количества атрибутов, может оказаться проще использовать интерполяцию тегов или Literal HTML в блоке текста.

p.
  Using regular tags can help keep your lines short,
  but interpolated tags may be easier to #[em visualize]
  whether the tags and text are whitespace-separated.
<p>Using regular tags can help keep your lines short, but interpolated tags may be easier to <em>visualize</em> whether the tags and text are whitespace-separated.</p>

Не рекомендуется

В зависимости от того, где вам нужны пробелы, вы можете добавить дополнительный пробел в начале текста (после отступа блока, символа | , или тега). Или вы можете добавить пробел в конце текста. В примере ниже дополнительный пробел для наглядности заменён _.

| Hey, check out_
a(href="http://example.biz/kitteh.png") this picture
| _of my cat!
Hey, check out <a href="http://example.biz/kitteh.png">this picture</a> of my cat!

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

Фильтры

Фильтры позволяют использовать другие языки в шаблонах Pug, принимая на вход блок текста.

Чтобы передать параметры в фильтр, добавьте их в круглых скобках после имени фильтра (так же, как атрибуты тегов): :less(ieCompat=false).

Все JSTransofmer могут быть использованы в качестве фильтров. Самые популярные фильтры :babel, :uglify-js, :scss, и :markdown-it. Опции поддерживаемые фильтрами смотрите в документации JSTransformer.

Если вы не можете найти подходящий фильтр, можете написать свой собственный. Подробнее об этом далее.

Если вы хотите использовать CoffeeScript и Markdown (используя Markdown-it Renderer) в своем шаблоне Pug, вы должны сначала установить следующие пакеты:

$ npm install --save jstransformer-coffee-script
$ npm install --save jstransformer-markdown-it

Теперь такой шаблон отрендериться правильно

:markdown-it(linkify langPrefix='highlight-')
  # Markdown

  Markdown document with http://links.com and

  ```js
  var codeBlocks;
  ```
script
  :coffee-script
    console.log 'This is coffee script'
<h1>Markdown</h1>
<p>Markdown document with <a href="http://links.com">http://links.com</a> and</p>
<pre><code class="highlight-js">var codeBlocks;
</code></pre>
<script>
  (function() {
    console.log('This is coffee script');

  }).call(this);
</script>

Внимание

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

По умолчанию компиляция в браузере не имеет доступа к фильтрам на основе JSTransformer, если только модули JSTransformer явно не упакованы и не доступны через платформу CommonJS (например, Browserify или Webpack).

Шаблоны, предварительно скомпилированные на сервере, не имеют этого ограничения.

Inline синтаксис

Если содержимое фильтра короткое, его можно использовать, как если бы он был тегом:

p
  :markdown-it(inline) **BOLD TEXT**

p.
  In the midst of a large amount of plain
  text, suddenly a wild #[:markdown-it(inline) *Markdown*]
  appeared.
<p><strong>BOLD TEXT</strong></p>
<p>In the midst of a large amount of plain text, suddenly a wild <em>Markdown</em> appeared.
</p>

Вы также можете применять фильтры к внешним файлам, используя синтаксис include

Вложенные фильтры

Вы можете применить несколько фильтров к одному блоку текста. Для этого укажите фильтры в одной строке. Фильтры применяются в обратном порядке.

В следующем примере скрипт сначала преобразуется с помощью babel, а затем cdata-js.

script
  :cdata-js:babel(presets=['es2015'])
    const myFunc = () => `This is ES2015 in a CD${'ATA'}`;

Кастомные фильтры

В Pug можно добавить свой фильтр с помощью параметра  filters.

options.filters = {
  'my-own-filter': function (text, options) {
    if (options.addStart) text = 'Start\n' + text;
    if (options.addEnd)   text = text + '\nEnd';
    return text;
  }
};

p
  :my-own-filter(addStart addEnd)
    Filter
    Body
<p>
  Start
  Filter
  Body
  End
</p>