Html шаблонизатор Pug, документация на русском

Html шаблонизатор Pug, документация на русском

1 071 в Html5, Css3 2

Всем привет! Давно хотел написать хорошую развернутую документацию про Html препроцессор Pug и вот этот момент настал. Я довольно давно использую Pug в своей работе и просто балдею от него dance. Я не понимаю, как можно сегодня верстать и писать обычный нативный Html-код. Это же так нудно и долго.

Вообще Pug это примерно тоже самое, что и препроцессор Sass. Я имею ввиду тут логику, хотя и сам синтаксис немного похож. Если вы поняли, чем хорош Sass, то Pug вам понравится еще больше.

Pug — это шаблонизатор Html, написанный на языке JavaScript для Node.js. После интерпретации сервером синтаксис Pug превращается в Нtml код. Старое название Pug — Jade. Подробности не знаю, но у разработчика возникли проблемы с авторскими правами и проект был переименован в Pug. Так что, если встретите упоминание Jade, знайте, что речь идет о Pug.

Наиболее подробно ознакомиться с Pug и изучить документацию вы сможете на официальном сайте проекта — pugjs.org.

Начало работы

Для того, чтобы работать с Pug вам необходим установить Node.js. Скачать его можно с официального сайта nodejs.org. После установки открываем консоль (в Windows это комбинация клавиш Win + R) и вводим команду:

$ npm install pug

Дождитесь пока установщик завершит установку. Чтобы проверить, что все прошло удачно введите команду в консоли:

$ npm pug -v

Вам должно выдать последнюю версию Pug, например — 6.13.4.

Далее запускаем еще одну команду:

npm install pug-cli -g

Если все прошло без ошибок, то можно начинать работу.

Теперь, чтобы начать создайте файл с расширением .pug, например, index.pug с классическим содержанием Hello, World:

html(lang="ru")
  head
    meta(charset="utf-8")
    title= "Учимся работать с шаблонизатором Pug"
  body
      h1 Hello, World!

Чтобы скомпилировать все это в Html необходимо в консоли перейти в директорию с данным файлом и запустить команду:

pug index.pug

После выполнения в этой же директории должен появиться файл index.html. Если откроем исходный код, то увидим, что весь код идет в одну строку и читать такой код довольно трудно. Чтобы исправить ситуацию запустим компиляцию Html с флагом --pretty (перед командой двойной дефис).

В итоге получим в index.html

<html lang="ru">
  <head>
    <meta charset="utf-8"/>
    <title>Учимся работать с шаблонизатором Pug</title>
  </head>
  <body>
    <h1>Hello, World!</h1>
  </body>
</html>

Можно также указать еще один флаг -w, для слежки за изменениями в файлах *.pug.

pug --pretty -w index.pug

Вообще вы можете запустить команду pug --help, чтобы посмотреть все доступные флаги и их сокращения.

Вообще хотелось бы отметить, что вряд ли кто-то использует данные команды в своей работе. Для того, чтобы комфортно работать с Pug используют таск-менеджеры, например Gulp + плагин gulp-pug. Но это отдельная тема для разговора. А мы давайте по подробнее разберем синтаксис pug.

Синтаксис Pug

Код Pug достаточно прост. Он не имеет угловых скобок и закрывающих тегов. Вложенность элементов определяется отступом — Tab или пробел.

В качестве отступов следует использовать либо Tab, либо пробел! И то, и другое нельзя. Иначе мы получим ошибку интерпретатора.

Все это делает код лаконичным и легкочитаемым. И самое главное — ускоряется скорость написания кода.

Как было уже отмечено, синтаксис Pug чем-то напоминает синтаксис Sass:

  • Вложенность определяется отступом (Tab или пробел)
  • Классы задаются через точку (.)
  • Id задаются через решетку (#)
  • Однострочные комментарии задаются через //

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

Теги, классы, индификаторы

Давайте напишем небольшую разметку, например маркированный список.

ul
    li Значение 1
    li Значение 2
    li Значение 3
    li Значение 4

Html

<ul>
    <li>Значение 1</li>
    <li>Значение 2</li>
    <li>Значение 3</li>
    <li>Значение 4</li>
</ul>

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

ul.list
    li.list__item Значение 1
    li.list__item Значение 2
    li.list__item Значение 3
    li.list__item Значение 4

Html

<ul class="list">
    <li class="list__item">Значение 1</li>
    <li class="list__item">Значение 2</li>
    <li class="list__item">Значение 3</li>
    <li class="list__item">Значение 4</li>
</ul>

Добавим тегу ul еще и индификатор

ul.list#listItems
    li.list__item Значение 1
    li.list__item Значение 2
    li.list__item Значение 3
    li.list__item Значение 4

Html

<ul class="list" id="listItems">
    <li class="list__item">Значение 1</li>
    <li class="list__item">Значение 2</li>
    <li class="list__item">Значение 3</li>
    <li class="list__item">Значение 4</li>
</ul>

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

Атрибуты

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

a(href="#") Ссылка

Html

<a href="#">Ссылка</a>

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

a(href="#", target="_blank") Ссылка
a(href="#" target="_blank") Ссылка

Html

<a href="#" target="_blank">Ссылка</a>

Если атрибутов много, то можно указать их многострочными линиями

input(
  type='checkbox'
  name='agreement'
  checked
)

Если с атрибутами нам необходимо указать класс и/или индификатор, то указываются они до атрибутов.

Неправильно

a(href="#" target="_blank").link#linkHref Ссылка

Правильно

a.link#linkHref(href="#" target="_blank") Ссылка

Класс или Id можно указать также, как обычный атрибут.

a(class="link" id="linkHref" href="#" target="_blank") Ссылка

Текст

Как было уже сказано, текст элементу указывается через пробел.

p Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ex dolorum, assumenda animi, deleniti sunt...

Можно указать и через символ | :

p 
    | Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ex dolorum, assumenda animi, deleniti sunt...
    | Еще строка текста

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

p.
    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ex dolorum, assumenda animi, deleniti sunt tempore quaerat nihil eveniet unde perferendis, possimus est temporibus labore minus amet et? Voluptatem, molestiae tempora. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ex dolorum, assumenda animi, deleniti sunt tempore quaerat nihil eveniet unde perferendis, possimus est temporibus labore minus amet et? Voluptatem, molestiae tempora.Lorem ipsum dolor sit amet, consectetur adipisicing elit. 

Также можно указывать обычные html теги внутри текста.

p Lorem ipsum dolor sit amet, <strong>consectetur</strong> adipisicing elit. Ex dolorum, assumenda animi, deleniti sunt…

Комментарии

Однострочные комментарии начинаются с символов — //

// Это комментарий в коде

Html

<!-- Это комментарий в коде -->

Если не хотите выводить комментарии в итоговом html коде, а в pug-файлах они нужны, то достаточно сразу после слешей добавить дефис.

//- А этот комментарий в html коде не выводится

Также можно выводить и многострочные комментарии.

//-
    А это большой комментарий
    Много много текста комментария и этот 
    многострочный комментарий в html 
    разметке не выводится.

//
    А это большой комментарий.
    Много много текста комментария и этот 
    многострочный комментарий выводится 
    в html разметке.

Html

<!--
  А это большой комментарий.
  Много много текста комментария и этот
  многострочный комментарий выводится
  в html разметке.
-->

Doctype

В Html5 doctype указывается следующим образом:

doctype html

Html

Читайте также:  Firebug - незаменимый инструмент каждого web-разработчика
<!DOCTYPE html>

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

Подключения (include)

Большим достоинством Pug является возможность подключения отдельных модулей кода. То есть можно выносить в отдельные фрагменты кода целые области сайта. Например, можно вынести отдельно header, sidebar, content, footer и все это собрать в одном индексном файле. Такой подход сделает наш код удобочитаемым и в случае правок достаточно изменить в одном месте.

//- index.pug
doctype html
html(lang="ru")
    //- Include head
    include ./components/head.pug  
    body
        //- Include header
        include ./components/header.pug
        h1 Заголовок страницы
        p Абзац, небольшое описание
    
    //- Include footer
    include ./components/footer.pug
//- Head.pug
head
    meta(charset='UTF-8')
    title Заголовок страницы
    script(src="/js/jquery.js")
    script(src="/js/scripts.js")
//- Header.pug
header.header
    .logo Логотип сайта
//- Footer.pug
footer.footer
    p Copyright текст

Html

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>Заголовок страницы</title>
    <script src="/js/jquery.js"></script>
    <script src="/js/scripts.js"></script>
</head>
<body>
    <header class="header">
        <div class="logo">Логотип сайта</div>
    </header>	
    
    <h1>Заголовок страницы</h1>
    <p>Абзац, небольшое описание</p>

    <footer class="footer">
        <p>Copyright текст</p>
    </footer>
</body>
</html>

Как видим код файла index.pug намного удобнее читать и ориентироваться в нем.

Также есть возможность подключать отдельные файлы стилей и скриптов.

//- Include custom styles
style
    include ./css/custom-style.css

//- Include custom scripts
script
    include ./js/custom-script.js

Циклы

Циклы или итерации в Pug позволяют выполнять какие-то множественные операции, написав всего лишь несколько строк кода. Например, можно вывести список пунктов меню, написав код итерации следующим образом:

nav.menu
    ul.menu__list
        each name in ['Главная', 'О компании', 'Услуги', 'Каталог', 'Контакты']
            li
                a(href="#")= name

Html

<nav class="menu">
    <ul class="menu__list">
        <li><a href="#">Главная</a></li>
        <li><a href="#">О компании</a></li>
        <li><a href="#">Услуги</a></li>
        <li><a href="#">Каталог</a></li>
        <li><a href="#">Контакты</a></li>
    </ul>
</nav>

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

nav.menu
    ul.menu__list
        each value, index in {'Главная' : 'home', 'О компании' : 'about', 'Услуги' : 'services', 'Каталог' : 'catalog', 'Контакты' : 'contact'}
            li
                a(href= "/" + value + ".html")= index

Html

<nav class="menu">
    <ul class="menu__list">
        <li><a href="/home.html">Главная</a></li>
        <li><a href="/about.html">О компании</a></li>
        <li><a href="/services.html">Услуги</a></li>
        <li><a href="/catalog.html">Каталог</a></li>
        <li><a href="/contact.html">Контакты</a></li>
    </ul>
</nav>

Вместо each вы можете использовать for в качестве псевдонима.

Как написано в документации, Pug поддерживает 2 основных вида итераций — это each и while. Each мы рассмотрели, теперь давайте посмотрим на while.

- var i = 0;
ul.list
    while i < 4
        li= i++

Html

<ul class="list">
    <li>0</li>
    <li>1</li>
    <li>2</li>
    <li>3</li>
</ul>

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

Миксины

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

Объявление миксина начинается с ключевого слова mixin, затем через пробел название миксина.

//- Mixin declaration
mixin listItems
    ul.list-items
        li One
        li Two
        li Three
        li Four
        li Five

//- Call mixin
+listItems     
<ul class="list-items">
    <li>One</li>
    <li>Two</li>
    <li>Three</li>
    <li>Four</li>
    <li>Five</li>
</ul>

Как видим, чтобы вызвать миксин необходимо поставить символ + и без пробела написать название миксина. Если код миксина выносится в отдельный файл, то в том документе, где он вызывается необходимо его подключить через include в верхней части документа.

Аргументы

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

//- Mixin declaration
mixin listItem(name)    
    li= name
    
//- Call mixin
ul.list-items
    +listItem("One")
    +listItem("Two")
    ...
    +listItem("Five")

У нас есть также возможность установить значения аргументов по умолчанию. Делается это примерно также, как и установка параметров функции по умолчанию в ES6 (ECMAScript 6).

//- Mixin declaration
mixin article(title="Заголовок по умолчанию")
    article.article
        h1= title

//- Call mixin
+article()

Блоки миксинов

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

//- Mixin declaration
mixin article(title)
    article.article
        h1= title
        if block
            block
        else
            p Нет контента для отображения

//- Call mixin
+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: "link-btn"}
    a(class!= attributes.class href= href)= name

+link('/link.html', 'linkName')(class="link-btn")

Обратите внимание, что атрибуты выводятся через символ !=. Дело в том, что спец. символы экранируются автоматически и чтобы избежать повторного экранирования мы используем знак !=. Если вы не хотите экранировать символы, то используйте символ =. Наиболее подробнее об этом можете почитать в документации.

Неизвестное количество аргументов

В миксинах Pug есть возможность передавать неизвестное количество аргументов, используя синтаксис «rest arguments«.

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

+list('myList', 1, 2, 3, 4)
<ul id="myList">
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
</ul>

Наследование шаблонов

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

Читайте также:  7 советов по качественной верстке шаблона сайта

Шаблон Pug

//- layout.pug
block variables

doctype html
html(lang="ru")
    head
        title #{title}        
        block scripts
            script(src='/jquery.js')
    body
        block content    	
    	block footer
            footer.footer
                p Copyright

Страницы Pug

//- index.pug
//- Главная страница
extends ./layout.pug
block variables
    - var title = 'Главная страница'

block content
    h1= title  
    p Главная страница сайта... Lorem ipsum dolor sit amet, consectetur adipisicing elit...
//- about.pug
//- О нас
extends ./layout.pug
block variables
    - var title = 'О нас'

block content
    h1= title  
    p О нашей компании... Lorem ipsum dolor sit amet, consectetur adipisicing elit...

Наследование шаблона происходит через ключевое слово extends, далее через пробел указываем относительный путь до файла шаблона. Расширение файла *.pug указывать не обязательно, Pug подставит его сам.

Области в которых нам необходимо вывести содержимое обозначаются словом block с указанием имени блока через пробел, например, block head. Содержимое блока на страницах заменяется дочерним шаблоном. Этот процесс является рекурсивным.

Из примера выше видим, что страницы «Главная» и «О нас» сделаны по одному шаблону. Ориентироваться в коде на таких страницах намного проще, ведь здесь только основное его содержимое.

Содержимое блока в шаблоне может быть и по умолчанию, но это не обязательно. Например, в шаблоне выше у нас существуют блоки scripts и footer с содержимым по умолчанию. На созданных страницах мы их не выводили, так как их содержимое выведется по умолчанию. Если не нужен контент по умолчанию, то оставляем блок просто пустым, например block footer.

Содержимое блока полностью заменяется дочерним шаблоном, но что, если нам необходимо просто добавить что-либо к содержимому по умолчанию?

Block append / prepend

В примере выше у нас есть блок scriptsв секции head, в котором указано подключение библиотеки jquery. Теперь представьте, что на определенной странице нам необходимо подключить еще один скрипт в блоке scripts. Можно поступить следующим образом:

//- index.pug
extends layout.pug
block variables
    - var title = 'Главная страница'

block scripts
  script(src='/jquery.js')
  script(src='/scripts.js')

block content

То есть указывать везде заново подключение jquery, но можно поступить проще. Добавить в блок scripts через append или prepend.

//- index.pug
extends layout.pug
block variables
    - var title = 'Главная страница'

block append scripts
  script(src='/scripts.js')

block content

block prepend — добавляет в начало списка, block append — в конец списка. Вообще слово block можно опустить, например — append scripts. Он является не обязательным.

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

Условия

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

Фигурные скобки можно опустить, как и символ - (если вы используете 2-ю версию Pug).

nav.menu
    ul.menu__list
        - var i = 1;
        each name in ['Главная', 'О нас', 'Контакты']
            if i == 1
                li.active
                    a(href="#")= name
            else
                li
                    a(href="#")= name

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

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

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

В Pug существует несколько видов вывода переменных. Давайте обратимся к примеру.

- var title = "ООО Рога и копыта";
- var name = "Владимир";
- var state = "старший менеджер";

h1= title
p Компанию "#{title}" представляет #{state} !{name}
<h1>ООО Рога и копыта</h1>
<p>Компанию "ООО Рога и копыта" представляет старший менеджер Владимир</p>

Если нужно вывести переменную в строке (например в тексте) я использую вывод #{название_переменной} или !{название_переменной}, в остальных случаях — =название_переменной.

Более подробнее про вывод переменных можете почитать в документации.

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

Оператор case работает также, как и в JavaScript switch case. Если вы знакомы с этим понятием в JavaScript, то понять вам будет проще. Впрочем, ничего сложного тут нет.

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

Можно записать данный код более компактно.

- var friends = 10
case friends
    when 0: p вы не имеете друзей
    when 1: p вы имеете одного друга
    default: p вы имеете #{friends} друзей

Если не хотим ничего выводить, то добавляем небуферизированный оператор break.

- var friends = 0
case friends
    when 0
        - break
    when 1
        p you have very few friends
    default
        p you have #{friends} friends

Код

Pug позволяет использовать встроенный JavaScript код в ваших шаблонах. Существует 3 вида кода: небуферизированный, буферизированный и неэкранированный буферизированный.

Небуферизированный код

Небуферизированный код ничего не выводит и начинается с символа -.

ul
    - for (var x = 0; x < 3; x++)
        li item

Небуферизированный код можно указать и как блок.

-
    var list = ["One", "Two", "Three"]
        ul
            each item in list
                li= item

Буферизированный код

Буферизированный код вычисляет выражение JavaScript и выводит его результат. Начинается он со знака =. В целях безопасности Html код перед выводом экранируется.

p
    = 'Строка текста с тегом <strong>выделения</strong>.'

Выведет…

<p>Строка текста с тегом &lt;strong&gt;выделения&lt;/strong&gt;.</p>

Неэкранированный буферизированный код

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

p
    != 'Строка текста с тегом <strong>выделения</strong>.'
<p>Строка текста с тегом <strong>выделения</strong>.

Фуф… Не маленькая получилась статья. На этом скорее всего завершу. Пока писал данную документацию сам узнал много чего новенького smile.

На этом все… Все спасибо за терпение (если дочитали до конца smile ). Пишите комменты, с удовольствием отвечу на вопросы. До встречи в других постах! bye

Оцените пост
3 оценок, среднее: 5,00 из 5
Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5
Загрузка...
Заур Магомедов
Заур Магомедов
Занимаюсь созданием сайтов с 2009 года. Постоянно обучаюсь и совершенствуюсь, шагая в ногу со временем. Владею такими навыками, как: Html5, Css3, jQuery, JavaScript, Git, БЭМ, Gulp.
Другие материалы той же категории
Что такое Pixel Perfect в верстке