Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Туториал по HTML препроцессору Pug (Jade)

Препроцессор Pug(Jade)

Pug - это препроцессор HTML и шаблонизатор, который был написан на JavaScript для Node.js.

Содержание:

  1. Теги
  2. Текст
  3. Атрибуты
  4. Констуркция Switch Case
  5. Циклы
  6. Вставка JavaScript кода
  7. Комментарии
  8. Условия
  9. Тип документа
  10. Инклюды (Includes)
  11. Наследование шаблонов
  12. Интерполяция переменных
  13. Миксины
  14. Многострочный ассоциативный массив

Официальная документация по Pug

Теги

В Pug нет закрывающих тегов, вместо этого он использует строгую табуляцию (или отступы) для определения вложености тегов. Для закрытия тегов в конце необходимо добавить символ /: foo(bar='baz')/

Pug

ul
  li Item A
  li Item B
  li Item C

HTML

<ul>
  <li>Item A</li>
  <li>Item B</li>
  <li>Item C</li>
</ul>

Текст

Непосредственно в Pug можно вставлять элементы в HTML синтаксисе

Pug

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

HTML

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

Pug

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

HTML

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

Атрибуты

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

Pug

a(href='google.com') Google
|
|
a(class='button' href='google.com') Google
|
|
a(class='button', href='google.com') Google

HTML

<a href="google.com">Google</a>
<a class="button" href="google.com">Google</a>
<a class="button" href="google.com">Google</a>

Pug

- var authenticated = true
body(class=authenticated ? 'authed' : 'anon')

HTML

<body class="authed"></body>

Pug

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

HTML

<input type="checkbox" name="agreement" checked="checked" />

Pug

- var url = 'pug-test.html';
a(href='/' + url) Link
|
|
- url = 'https://example.com/'
a(href=url) Another link

HTML

<a href="/pug-test.html">Link</a>
<a href="https://example.com/">Another link</a>

Pug

- var classes = ['foo', 'bar', 'baz']
a(class=classes)
|
|
//- the class attribute may also be repeated to merge arrays
a.bang(class=classes class=['bing'])

HTML

<a class="foo bar baz"></a>
<a class="bang foo bar baz bing"></a>

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

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

Pug

- var friends = 10
case friends
  when 0
    p you have no friends
  when 1
    p you have a friend
  default
    p you have #{friends} friends

HTML

<p>you have 10 friends</p>

Циклы

Pug

ul
  each val, index in ['zero', 'one', 'two']
    li= index + ': ' + val

HTML

<ul>
  <li>0: zero</li>
  <li>1: one</li>
  <li>2: two</li>
</ul>

Pug

- var values = [];
ul
  each val in values
    li= val
  else
    li There are no values

HTML

<ul>
  <li>There are no values</li>
</ul>

Pug

- var n = 0;
ul
  while n < 4
    li= n++

HTML

<ul>
  <li>0</li>
  <li>1</li>
  <li>2</li>
  <li>3</li>
</ul>

Вставка JavaScript кода

Pug поддерживает вставку частей JavaScript кода в шаблоны.

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

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

HTML

<li>item</li>
<li>item</li>
<li>item</li>

Буфферизированный код начинается с символа =
Pug

p
  = 'This code is <escaped>!'

HTML

<p>This code is &lt;escaped&gt;!</p>

Комментарии

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

Pug

// just some paragraphs
//- will not output within markup
p foo
p bar

HTML

<!-- just some paragraphs-->
<p>foo</p>
<p>bar</p>

Pug

body
  //-
    Comments for your template writers.
    Use as much text as you want.
  //
    Comments for your HTML readers.
    Use as much text as you want.

HTML

<body>
  <!--Comments for your HTML readers.
Use as much text as you want.-->
</body>

Условия

Pug

- var user = { description: 'foo bar baz' }
- var authorised = false
#user
  if user.description
    h2.green Description
    p.description= user.description
  else if authorised
    h2.blue Description
    p.description.
      User has no description,
      why not add one...
  else
    h2.red Description
    p.description User has no description

HTML

<div id="user">
  <h2 class="green">Description</h2>
  <p class="description">foo bar baz</p>
</div>

Тип документа

Pug

doctype html

HTML

<!DOCTYPE html>

Инклюды (Includes)

Pug имеет возможность вставки содержимого одного файла в другой файл Pug.

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

CSS

/* style.css */
h1 {
  color: red;
}

JavaScript

// script.js
console.log('You are awesome');

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>

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

Pug поддерживает наследование шаблонов. Наследование шаблонов работает через ключевые слова block и extend. В шаблоне block - обычный блок Pug, который может заменить дочерний шаблон. Этот процесс является рекурсивным.

Pug

//- base.pug
html
  head
    title My Site 
    block scripts
      script(src='/jquery.js')
  body
    block content
    block foot
      #footer
        p some footer content
        
//- home.pug
extends base.pug
- var title = 'Animals'
- var pets = ['cat', 'dog']
block content
  h1= title // - or #{title} without =
  each petName in pets
    p= petName // -or #{petName} without =

HTML

<!DOCTYPE html>
<html>
<head>
  <title>My site</title>
  <script src='/jquery.js'></script>
</head>
<body>
  <h1>Animals</h1>
  <p>cat</p>
  <p>dog</p>
  <div id='footer'>
    <p>some footer content</p>
  </div>
</body>
</html>

Интерполяция переменных

Pug предоставляет различные способы вывода переменных.

Pug

- 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}

HTML

<h1>On Dogs: Man's Best Friend</h1>
<p>Written with love by enlore</p>
<p>This will be safe: <span>escape!</span></p>

Миксины

Поддержка миксинов позволяет создавать переиспользуемые блоки.

Pug

//- Declaration
mixin pet(name)
  li.pet= name
//- use
ul
  +pet('cat')
  +pet('dog')
  +pet('pig')

HTML

<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

HTML

<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>

Pug

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

+link('/foo', 'foo')(class="btn")

HTML

<a class="btn" href="/foo">foo</a>

Многострочный ассоциативный массив

Pug

-
  var priceItem = [
    {include: filterInc, parameter : "Розовый фильтр"},
    {include: smileInc, parameter : "Смайлики"},
    {include: commentInc, parameter : "Комментарии"}
  ]
@R0NS0N
Copy link

R0NS0N commented Oct 2, 2018

Дякую... коротко і те що потрібно.

@nerlihmax
Copy link

nerlihmax commented Oct 8, 2018

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

@AlexeyRomanchenko
Copy link

AlexeyRomanchenko commented Oct 20, 2018

Ребятки, подскажите пожалуйста , можно ли сделать в pug конструкцию типа
if username
li
a(href="/logout") logout
else
li
a(href="/login") login
// как показать ,что if условие закончено? чтото типа endif ?
li
a(href='http:#') main
li
a(href='http:#') about me

А за туториал на русском - большое спасибо!

@neretin-trike
Copy link
Author

neretin-trike commented Oct 28, 2018

Ребятки, подскажите пожалуйста , можно ли сделать в pug конструкцию типа
if username
li
a(href="/logout") logout
else
li
a(href="/login") login
// как показать ,что if условие закончено? чтото типа endif ?
li
a(href='http:#') main
li
a(href='http:#') about me

А за туториал на русском - большое спасибо!

Если я правильно тебя понял, то может быть такое решение:

- var username = { authorised: true }
if username.authorised == true
  li
  a(href="/logout") logout
else if username.authorised == false
  li
  a(href="/login") login
else
  li
  a(href='http:#') main
  li
  a(href='http:#') about me

@Mikkou
Copy link

Mikkou commented Nov 8, 2018

спасибо, коротко и ясно)

@warezorwar
Copy link

warezorwar commented Feb 28, 2019

((( Не буфферизированный код начинается с символа -
Буфферизированный код начинается с символа = )))
не могу понять разницу, подскажите пожалуйста

@sh4rov
Copy link

sh4rov commented Jun 21, 2019

Полезно. Спасибо :)

@Petrivah
Copy link

Petrivah commented Aug 5, 2019

((( Не буфферизированный код начинается с символа -
Буфферизированный код начинается с символа = )))
не могу понять разницу, подскажите пожалуйста

Буфферизированный- тот который выводится
Не Буфферизированный- тот который Не выводится

= "a" //- Выведет "а"
- "a" //- Ничего не выведет

@webitall2019
Copy link

webitall2019 commented Sep 24, 2019

Хороший туториал! спс

@Mike2142
Copy link

Mike2142 commented Nov 4, 2019

Очень полезная статья, спасибо!

@badunius
Copy link

badunius commented Nov 12, 2019

ситуация, нужно закомментировать один из элементов, находящийся на одном уровне с другими

  div 1
  div 2
  div 3

комментируем раз

  div 1
  //-
  div 2
  div 3

не работает

  div 1
//-
  div 2
  div 3

комментирует 2 и 3

  div 1
  //-
    div 2
  div 3

не работает

в человечьем HTML это делается так: <!-- <div>2</div> -->, но я вынужден использовать pug

@ImLoaD
Copy link

ImLoaD commented Nov 27, 2019

@badunius

в человечьем HTML это делается так: <!-- <div>2</div> -->, но я вынужден использовать pug

В человечьем PUG это делается вроде вот так

  div 1
  //- div 2
  div 3

@Warlock-9000
Copy link

Warlock-9000 commented Dec 27, 2019

Добрый день, как написать подобную конструкцию на PUG ?
<li v-for="item in transactions" :key="item.id" v-bind:class="{ error : item.status === 'error' }">

@zzaq17
Copy link

zzaq17 commented Feb 9, 2020

Благодарю) всё понятно и с примерами

Появился вопрос с meta блоками в head. Кто-нибудь сталкивался?
Ошибка в gulp:
Message: Unexpected token (8:8) Details: pos: 558 loc: [object Object] raisedAt: 559 domainThrown: true

Часть кода шаблона:

doctype html

block variables

html(lang="ru")
	head
		//- SEO PART
		title #{title}
		meta(name="description", content= `${metaDescr}`)
		link(rel="canonical" href= `${page-url}`)

Часть кода для страницы:

extends templates/_template-main

block variables
	- var title = "Тайтл этой страницы"
	- var page-url = ""
	- var metaDescr = "Дескрипшн"
	- var og-image = "http://sample.com/sample-1.png"

block content
	main

Пробовал и #{}, и всё что нашёл в туториал, и просто название переменной. Но ничего не помогает. Как всё-таки добавить интерполяцию?

@190968
Copy link

190968 commented Feb 21, 2020

Есть ли в Pug onenter='function()' и onleave='function()'

@xymerone
Copy link

xymerone commented Apr 18, 2020

Дякую, так тримати - автор!

@Ruslan101
Copy link

Ruslan101 commented May 10, 2020

Неплохо, хотя наверное лучше такие статьй писать в habr'е

@purpl3mint
Copy link

purpl3mint commented Jun 29, 2020

В закладки. Автору огромное спасибо!

@doyouhave
Copy link

doyouhave commented May 3, 2021

нихрена не понятно!

@EleonoraPavlova
Copy link

EleonoraPavlova commented Oct 1, 2021

спасибо)

@webshot
Copy link

webshot commented Oct 5, 2021

Конечно извиняюсь за тупой вопрос, но как его подключить к самому HTML?

@Sundwell
Copy link

Sundwell commented Dec 27, 2021

Спасибо, сел на проект где юзают pug - понял основные принципы за 5 минут чтения этого туторила

Автору респект за понятное объяснение

@L063n-9F
Copy link

L063n-9F commented Feb 15, 2022

@zzaq17

Интерполяция таким образом ${} работает только для текста. Чтобы передавать переменную как атрибут тега можно сделать так:

-
  var title = ["Заголовок"];
  var metaDescr = ["Описание"];
  var page-url = ["page-url"];

doctype html
html(lang="ru")
  head
    title= "" +title
    meta(name="description", content= "" +metaDescr)
    link(rel="canonical" href= "" +page-url)

Либо использовать обратные кавычки:

    title= `${title}`
    meta(name="description", content= `${metaDescr}`)
    link(rel="canonical" href= `${page-url}`)

@Streammer
Copy link

Streammer commented Jul 14, 2022

Скажете, если я рендерю разметку в отдельном javaScript файле (index.js) через querySelector и innerHTML. Могу ли я этот файл index.js импортировать в pug файл и отрендерить его и получить статику. Т.е. мне не нужно создать теги script и туда вставить js, который будет исполняться браузером. Мне нужно получить на выходе уже готовую статику. Что-то типа SSR. Умеет ли pug так делать?

@Leo5878
Copy link

Leo5878 commented Jul 17, 2022

Можно. Но сами теги script нужно будет создавать непосредственно средвами pug, иначе никак

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment