Подключение файлов
В Pug можно вставлять содержимое одного файла в другой. Это позволяет выносить в отдельные файлы разметку повторяющихся блоков или миксины. Возьмём два файла, один из которых содержит разметку для head, а второй разметку для footer
//- includes/head.pug
head
title My Site
script(src='/javascripts/jquery.js')
script(src='/javascripts/app.js')
//- includes/foot.pug
footer#footer
p Copyright (c) foobar
Теперь не нужно на каждой странице писать разметку для этих блоков. Достаточно подключить их через include
//- index.pug
doctype html
html
include includes/head.pug
body
h1 My Site
p Welcome to my super lame site.
include includes/foot.pug
По итогу получим такой HTML
<!DOCTYPE html>
<html>
<head>
<title>My Site</title>
<script src="/javascripts/jquery.js"></script>
<script src="/javascripts/app.js"></script>
</head>
<body>
<h1>My Site</h1>
<p>Welcome to my super lame site.</p>
<footer id="footer">
<p>Copyright (c) foobar</p>
</footer>
</body>
</html>
Если в include указан абсолютный путь (include /root.pug), то корневой каталог должен быть определён в options.basedir. Для относительных путей адрес определяется относительно файла в котором идёт подключение. Если расширение файла не указано, то по умолчанию подставляется .pug
Не Pug файлы подключаются как текст
/* style.css */
h1 {
color: red;
}
// script.js
console.log('You are awesome');
Подключим css и js файлы в Pug
//- index.pug
doctype html
html
head
style
include style.css
body
h1 My Site
p Welcome to my super lame site.
script
include script.js
В итоге получим таrой HTML
<!DOCTYPE html>
<html>
<head>
<style>
/* style.css */
h1 {
color: red;
}
</style>
</head>
<body>
<h1>My Site</h1>
<p>Welcome to my super lame site.</p>
<script>
// script.js
console.log('You are awesome');
</script>
</body>
</html>
Можно комбинировать фильтры с include, позволяя фильтровать содержимое файлов по мере их включения. Попробуем вставить файл с markdown разметкой
# article.md
This is an article written in markdown.
//- index.pug
doctype html
html
head
title An Article
body
include:markdown-it article.md
<!DOCTYPE html>
<html>
<head>
<title>An Article</title>
</head>
<body>
<h1>article.md</h1>
<p>This is an article written in markdown.</p>
</body>
</html>
Шаблоны блоки расширения
Pug поддерживает наследование шаблонов. Для этого используют ключевые слова block и extends. Блоки шаблона могут быть заменены в дочернем шаблоне. Блоки в Pug могут содержать контент по умолчанию. В приведенном ниже примере, в макете, определяются block scripts, block content и block foot.
//- layout.pug
html
head
title My Site - #{title}
block scripts
script(src='/jquery.js')
body
block content
block foot
#footer
p some footer content
Чтобы применить этот макет в другом файле используем extends и укажем путь к шаблону(если не указать расширение файла, .pug будет добавлен автоматически). Подключив шаблон можно переопределить некоторые блоки. В примере ниже блок foot не переопределяется, поэтому его содержимое останется как в родительском шаблоне.
//- page-a.pug
extends layout.pug
block scripts
script(src='/jquery.js')
script(src='/pets.js')
block content
h1= title
- let pets = ['cat', 'dog']
each petName in pets
include pet.pug
//- pet.pug
p= petName
Результат
<!DOCTYPE html>
<html>
<head>
<title>My Site - </title>
<script src="/jquery.js"></script>
<script src="/pets.js"></script>
</head>
<body>
<h1></h1>
<p>cat</p>
<p>dog</p>
<div id="footer">
<p>some footer content</p>
</div>
</body>
</html>
Переопределяя блок можно поместить в него другие блоки. В следующем примере, при переопределении блока content в него были добавлены блоки sidebar и primary
//- sub-layout.pug
extends layout.pug
block content
.sidebar
block sidebar
p nothing
.primary
block primary
p nothing
append/prepend
В Pug можно переопределять блоки добавляя в них контент и не удаляя содержимое. Предположим есть скрипты которые должны подключаться на каждой странице. Тогда шаблон будет выглядеть следующим образом
//- layout.pug
html
head
block head
script(src='/vendor/jquery.js')
script(src='/vendor/caustic.js')
body
block content
У нас есть страница с Javascript игрой и для неё нужны свои скрипты. С помощью append/prepend можно добавить их не удаляя скрипты из родительского шаблона.
//- page.pug
extends layout
append head
script(src='/vendor/three.js')
script(src='/game.js')
Когда используем append/prepend можно не писать слово block. Вместо block append head достаточно append head.
Частые ошибки в использовании шаблонов
Наследование шаблонов Pug - это мощная функция, которая позволяет разбивать сложные структуры шаблонов страниц на более мелкие и простые файлы, но не стоит объединять слишком много шаблонов вместе.
Обратите внимание, что только блоки и определения миксинов могут отображаться на верхнем уровне(без отступа) дочернего шаблона. Это важно! Родительские шаблоны определяют общую структуру данных, а дочерние шаблоны могут только изменять определённые блоки в разметке и логику. Если дочерний шаблон попытается добавить контент вне блока, Pug не будет знать куда поместить его на странице.
Небуферизованный код, который может содержаться в разметке. Если вам нужно определить переменные для использования в дочернем шаблоне, вы можете сделать это несколькими различными способами:
- Добавьте переменные в объект параметров Pug или определите их в небуферизованном коде в родительском шаблоне. Дочерний шаблон наследует эти переменные.
- Определите переменные в блоке в дочернем шаблоне. Расширяемые шаблоны должны иметь хотя бы один блок, иначе он будет пустым - определите свои переменные там.
Буферизованные комментарии Pug не могут отображаться на верхнем уровне расширяемого шаблона: они создают комментарии HTML, которые не будут помещаться в получившийся HTML. (Небуферизованные комментарии Pug могут располагаться где угодно.)
Миксины
С помощью миксинов можно создавать переиспользуемые блоки
//- Declaration
mixin list
ul
li foo
li bar
li baz
//- Use
+list
+list
ul>
<li>foo</li>
<li>bar</li>
<li>baz</li>
</ul>
<ul>
<li>foo</li>
<li>bar</li>
<li>baz</li>
</ul>
Миксины могут принимать аргументы
mixin pet(name)
li.pet= name
ul
+pet('cat')
+pet('dog')
+pet('pig')
<ul>
<li class="pet">cat</li>
<li class="pet">dog</li>
<li class="pet">pig</li>
</ul>
Миксин может принимать блок Pug и действовать в зависимости от содержания
mixin article(title)
.article
.article-wrapper
h1= title
if block
block
else
p No content provided
+article('Hello world')
+article('Hello world')
p This is my
p Amazing article
<div class="article">
<div class="article-wrapper">
<h1>Hello world</h1>
<p>No content provided</p>
</div>
</div>
<div class="article">
<div class="article-wrapper">
<h1>Hello world</h1>
<p>This is my</p>
<p>Amazing article</p>
</div>
</div>
Миксины могут получать не явные attributes аргументы, которые берутся из атрибутов, переданных в миксин.
mixin link(href, name)
//- attributes == {class: "btn"}
a(class!=attributes.class href=href)= name
+link('/foo', 'foo')(class="btn")
<a class="btn" href="/foo">foo</a>
Значения в атрибутах, по умолчанию уже экранированы! Используйте ! =, чтобы избежать их повторного экранирования.
Можно использовать миксин с &atributes
mixin link(href, name)
a(href=href)&attributes(attributes)= name
+link('/foo', 'foo')(class="btn")
<a class="btn" href="/foo">foo</a>
Синтаксис +link(class = "btn") допустим и эквивалентен + link()(class = "btn"), поскольку Pug пытается определить, является ли содержимое скобок атрибутами или аргументами. Тем не менее рекомендуется использовать второй синтаксис, так как вы явно не передаете аргументы и подтверждаете, что первая скобка - это список аргументов.
В миксине можно устанавливать аргументы по умолчанию
//- Declaration
mixin article(title='Default Title')
.article
.article-wrapper
h1= title
//- Use
+article()
+article('Hello world')
<div class="article">
<div class="article-wrapper">
<h1>Default Title</h1>
</div>
</div>
<div class="article">
<div class="article-wrapper">
<h1>Hello world</h1>
</div>
</div>
Вы можете написать миксины, которые принимают неизвестное количество аргументов, используя синтаксис «rest arguments».
mixin list(id, ...items)
ul(id=id)
each item in items
li= item
+list('my-list', 1, 2, 3, 4)
<ul id="my-list">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
- Войдите, чтобы оставлять комментарии