Pug. Начало работы. Часть вторая из двух

22.06.2021

Теги: HTMLJavaScriptWeb-разработкаВерсткаТеорияШаблонСайта

Синтаксис Pug

И это еще далеко не все возможности. Циклы позволяют выполнять какие-то множественные операции, например — вывести список пунктов меню. Миксины позволяют создавать многократно повторяемые блоки кода. Это практически то же самое, что и функции в языке программирования.

10. Циклы внутри шаблона

Циклы позволяют выполнять какие-то множественные операции, например — вывести список пунктов меню:

nav.menu
    ul.menu__list
        each name in ['Главная', 'Каталог', 'Контакты']
            li
                a(href="#")= name
<nav class="menu">
  <ul class="menu__list">
    <li><a href="#">Главная</a></li>
    <li><a href="#">Каталог</a></li>
    <li><a href="#">Контакты</a></li>
  </ul>
</nav>

Также есть возможность перебрать ключи и значения в объекте:

nav.menu
    ul.menu__list
        each value, key in {'home.html': 'Главная', 'catalog.html': 'Каталог', 'contact.html': 'Контакты'}
            li
                a(href=key)= value
<nav class="menu">
  <ul class="menu__list">
    <li><a href="home.html">Главная</a></li>
    <li><a href="catalog.html">Каталог</a></li>
    <li><a href="contact.html">Контакты</a></li>
  </ul>
</nav>

C циклом each разобрались, теперь давайте посмотрим на while:

- var i = 1;
ul.list
    while i <= 3
        li= i++
<ul class="list">
  <li>1</li>
  <li>2</li>
  <li>3</li>
</ul>

Поскольку в шаблонах допускается использование js-кода (после дефиса) — можно использовать js-цикл for:

ul.list
    - for (var i = 1; i <= 3; i++)
        li Элемент #{i}
<ul class="list">
  <li>Элемент 1</li>
  <li>Элемент 2</li>
  <li>Элемент 3</li>
</ul>

11. Условия внутри шаблона

Можно использовать if, else, unless, case:

- var user = {description: 'Информация о пользователе'}
- var authorised = false
div#user
    //- если есть описание — показываем
    if user.description
        h2.green Описание
        p.description= user.description
    //- если нет — предлагаем добавить
    else if authorised
        h2.blue Описание
        p.description.
            Добавить описание можно #[a(href="/user/edit") здесь]
    //- просматривает анонимный юзер
    else
        h2.red Описание
        p.description Отсутствует
<div id="user">
  <h2 class="green">Описание</h2>
  <p class="description">Информация о пользователе</p>
</div>

Выбор из нескольких вариантов с помощью case работает аналогично switch:

- var friends = 10
case friends
    when 0
        p У вас нет друзей
    when 1
        p У вас один друг
    default
        p У вас #{friends} друзей
<p>У вас 10 друзей</p>

Условие unless является противоположностью условия if:

unless user.isAnonymous
    p You're logged in as #{user.name}
if !user.isAnonymous
    p You're logged in as #{user.name}

12. Миксины (mixin)

Миксины позволяют создавать многократно повторяемые блоки кода. Это практически то же самое, что и функции в языке программирования.

//- объявление миксина
mixin listItems()
    ul.list-items
        li Элемент раз
        li Элемент два
        li Элемент три

//- вызов миксина
+listItems()
<ul class="list-items">
  <li>Элемент раз</li>
  <li>Элемент два</li>
  <li>Элемент три</li>
</ul>
Если у миксина нет аргументов, то круглые скобки при объявлении и при вызове можно опустить.

Миксин может принимать также и аргументы:

//- объявление миксина
mixin listItems(items)
    ul.list-items
        each value in items
            li= value 

- var items = ['Элемент раз', 'Элемент два', 'Элемент три']
//- вызов миксина
+listItems(items)
<ul class="list-items">
  <li>Элемент раз</li>
  <li>Элемент два</li>
  <li>Элемент три</li>
</ul>

Можно установить значение аргумента по умолчанию:

//- объявление миксина
mixin article(title="Заголовок по умолчанию")
    article.article
        h1= title

//- вызов миксина
+article("Это заголовок статьи")
//- вызов миксина
+article()
<article class="article">
  <h1>Это заголовок статьи</h1>
</article>
<article class="article">
  <h1>Заголовок по умолчанию</h1>
</article>

Есть возможность передавать неизвестное количество аргументов:

mixin list(id, ...items)
    ul(id=id)
        each item in items
            li= item

+list('items', 'Элемент раз', 'Элемент два', 'Элемент три')
<ul id="items">
  <li>Элемент раз</li>
  <li>Элемент два</li>
  <li>Элемент три</li>
</ul>

Есть еще одна возможность (довольно сомнительная) — добавить блок после вызова миксина и управлять показом этого блока из тела миксина.

//- объявление миксина
mixin article(title="Заголовок по умолчанию")
    article.article
        h1= title
        if block
            block
        else
            p Нет контента для отображения

//- вызов миксина
+article("Это заголовок статьи")
    p Lorem ipsum dolor sit amet, consectetur adipisicing elit.
    p Lorem ipsum dolor sit amet, consectetur adipisicing elit.
<article class="article">
  <h1>Это заголовок статьи</h1>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
</article>

Помимо аргументов миксины также могут принимать и атрибуты:

mixin link(href, name)
    //- attributes == {class: "button"}
    a(href=href class!=attributes.class)= name

+link('page.html', 'ссылка')(class="button")
<a class="button" href="page.html">ссылка</a>

Обратите внимание, что атрибуты выводятся через !=. Символы <, >, & при передаче экранируются автоматически — чтобы избежать двойного экранирования, нужно использовать !=.

По-моему, тоже довольно сомнительная возможность, только усложняет синаксис. Что мешает передать атрибуты дополнительным аргументом?

mixin link(href, name, attr)
    a(href=href class=attr.class title=attr.title)= name

+link('page.html', 'ссылка', {class: 'button', title: 'ссылка'})
<a class="button" href="page.html" title="ссылка">ссылка</a>

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

Управление пробелами в отображаемом HTML — одна из немногих сложных частей в изучении. Когда pug-код преобразуется в html-код — все пробелы и переносы строк внутри тега сохраняются. Например, добавим в начало и в конец абзаца несколько пробелов + добавим перенос строки между предложениями абзаца.

<p>  Lorem ipsum dolor, sit amet consectetur adipisicing elit.
Molestias quisquam accusamus odit alias numquam.  </p>

Но пробелы между элементами удаляются — если не использовать ключ pretty. Для блочных элементов это не представляет проблемы, но для строчных элементов может создавать трудности.

em Lorem ipsum dolor sit.
em Lorem ipsum dolor sit.
<em>Lorem ipsum dolor sit.</em><em>Lorem ipsum dolor sit.</em>

Исправить это легко:

em Lorem ipsum dolor sit.
//- после | два пробела: один требуется синтаксисом после вертикальной черты,
//- а второй добавляет пробел между закрывающим </em> и открывающим <em>; но
//- pug достаточно умный, и вставит пробел, даже если их будет не два, а один
|  
em Lorem ipsum dolor sit.
<em>Lorem ipsum dolor sit.</em> <em>Lorem ipsum dolor sit.</em>

Но тут следует помнить, что многие редакторы удаляют пробелы в конце строк при сохранении файла. Так что есть смысл использовать две вертикальные черты — в этом случае будет добавлен не пробел, а символ новой строки.

em Lorem ipsum dolor sit.
|
|
em Lorem ipsum dolor sit.
<em>Lorem ipsum dolor sit.</em>
<em>Lorem ipsum dolor sit.</em>

Еще один пример — как избежать примыкания вплотную текста перед и после кнопки:

| нет пробела перед кнопкой
button#button кнопка
| нет пробела после кнопки
нет пробела перед кнопкой<button id="button">кнопка</button>нет пробела после кнопки
//- вместо символа пробела « » используется символ подчеркивания «_»
| есть пробел перед кнопкой_
button#button кнопка
| _есть пробел после кнопки
есть пробел перед кнопкой_<button id="button">кнопка</button>_есть пробел после кнопки
| есть пробел перед кнопкой
|
button#button кнопка
|
| есть пробел после кнопки
есть пробел перед кнопкой
<button id="button">кнопка</button>
есть пробел после кнопки

14. Дополнительные возможности

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

div#foo(data-bar="bar value")&attributes({'data-baz': 'baz value'}) Lorem ipsum dolor sit amet.
<div id="foo" data-bar="bar value" data-baz="baz value">Lorem ipsum dolor sit amet.</div>

Атрибут class может быть не только строкой, но и массивом:

- var classes = ['foo', 'bar', 'baz']
a.bang(class=classes class=['bing'])
<a class="bang foo bar baz bing">ссылка</a>

Мало того — объектом, значения которого true или false:

- var classes = {foo: false, bar: true, baz: false}
a.bang(class=classes class=['bing']) ссылка
<a class="bang bar bing">ссылка</a>

Атрибут style тоже может быть объектом:

a(style={color: 'red', background: 'green'}) ссылка
<a style="color:red;background:green;">ссылка</a>

И еще один момент. Строка pug-кода, которая начинается с символа < расматривается как обычный текст и попадает в итоговый html-код без изменений — это дает возможность использовать нативные html-теги и html-комментрии.

<!-- Комментарий -->
<body>
    p Lorem ipsum dolor sit amet, consectetur adipisicing elit.
    p Lorem ipsum dolor sit amet, consectetur adipisicing elit.
</body>
<!-- Комментарий -->
<body>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
</body>

Поиск: HTML • JavaScript • Web-разработка • Теория • Шаблон сайта • Pug • Верстка

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.