[Перевод] Туториал по Jade для начинающих
Jade — это препроцессор HTML и шаблонизатор, который был написан на JavaScript для Node.js. Проще говоря, Jade — это именно то средство, которое предоставляет вам возможность написания разметки совершенно по новому, с целым рядом преимуществ по сравнению с обычным HTML.
К примеру, взгляните на код ниже в формате HTML:
Ocean's Eleven
- Comedy
- Thriller
Danny Ocean and his eleven accomplices plan to rob
three Las Vegas casinos simultaneously.
А так эта разметка выглядит в формате Jade:
div
h1 Ocean's Eleven
ul
li Comedy
li Thriller
p.
Danny Ocean and his eleven accomplices plan to rob
three Las Vegas casinos simultaneously.
Второй вариант кажется более коротким и элегантным. Но Jade — это не только симпатичная разметка. Jade имеет некоторые действительно полезные функции, позволяющие писать модульный многоразовый (с возможностью многоразового использования) код. Но перед тем, как углубиться, давайте сделаем обзор основ.
Основы
Я собираюсь выделить три основные черты Jade:
- Простые теги;
- Добавление атрибутов в теги;
- Блоки текста.
Если вы хотите входе прочтения статьи пробывать примеры кода приведённые ниже, вы можете воспользоваться CodePen и выбрать Jade как препроцесор для вашего HTML, или воспользуйтесь онлайн компилятором на официальном сайте Jade.Теги
Как вы могли заметить ранее, в Jade нет закрывающих тегов. Вместо этого Jade использует табуляцию для определения вложености тегов.
div
p Hello!
p World!
В приведенном выше примере, теги параграфов согласно их табуляции при компиляции в конечном итоге окажутся внутри тега div. Как просто!
Hello!
World!
Jade компилирует это точно, рассматривая первое слово в каждой строке в качестве тега, в то время как последующие слова на этой строке обрабатываются как текст внутри тега.
Посмотреть этот пример на CodePen
Атрибуты
Всё это, конечно, хорошо, но как добавлять атрибуты нашим тегам? На самом деле довольно просто.
Давайте вернёмся к нашему первому примеру и добавим туда пару классов и некую картинку-постер.
div(class="movie-card", id="oceans-11")
h1(class="movie-title") Ocean's 11
img(src="/img/oceans-11.png", class="movie-poster")
ul(class="genre-list")
li Comedy
li Thriller
Как чудестно, не так ли?
Ocean's 11
- Comedy
- Thriller
Посмотреть этот пример на CodePen
Но зачем останавливаться на достигнутом?! Jade предоставляет специальную стенографию для индификаторов и классов, что ещё больше упрощает нашу разметку, используя знакомые всем обозначения:
div.movie-card#oceans-11
h1.movie-title Ocean's 11
img.movie-poster(src="/img/oceans-11.png")
ul.genre-list
li Comedy
li Thriller
Посмотреть этот пример на CodePen
Как вы можете заметить, Jade использует синтаксис анологичный тому, который вы используете при написании CSS-селекторов.
Блоки текста
Давайте представим такую ситуацию: у вас есть тег и вы хотите добавить в него довольно таки большой объём текста. Но стоп, ведь Jade рассматривает первое слово каждой строки как новый HTML-тег — и как тут быть?
В самом первом примере вы уже могли заметить невзрачную точку после тега параграфа. Добавление точки после вашего тега даёт понять компилятору Jade, что всё внутри данного тега является текстом.
div
p How are you?
p.
I'm fine thank you.
And you? I heard you fell into a lake?
That's rather unfortunate. I hate it when my shoes get wet.
Посмотреть этот пример на CodePen
Для полной ясности: в случае, если я не поставил бы точку после тега <р> в примере, то скомпилированный HTML имел бы в себе открытый тег <і>, разорвав словосочетание «I«m» в начале строки.
Полезные функции
Теперь, когда мы разобрались с основами, давайте рассмотрим некоторые в действительности полезные функции, которые сделают нашу разметку умнее. Среди них:
- JavaScript;
- Циклы;
- Интерполирование;
- Миксины.
JavaScript в Jade
Jade реализован на JavaScript, по этому использовать JavaScript в Jade довольно просто. Вот пример:
- var x = 5;
div
ul
- for (var i=1; i<=x; i++) {
li Hello
- }
Что же мы тут сделали?! Начав строку с дефиса, мы указали компилятору Jade, что мыхотим использовать JavaScript, и всё, оно работает! И вот что мы получим, когда скомпилируем этот код в HTML:
- Hello
- Hello
- Hello
- Hello
- Hello
Посмотреть этот пример на CodePen
Мы используем дефис, когда код не должен напрямую попадать в поток вывода. В случае, ежели мы хотим использовать JavaScript для вывода чего-либо в Jade, мы используем =. Давайте подправим код выше, чтобы указать нумерацию элементов в списке:
- var x = 5;
div
ul
- for (var i=1; i<=x; i++) {
li= i + ". Hello"
- }
И вуаля, у нас имеется нумерация:
- 1. Hello
- 2. Hello
- 3. Hello
- 4. Hello
- 5. Hello
Посмотреть этот пример на CodePen
Конечно, в данном случае нумерованный список был бы гораздо уместнее, но идею то вы уловили? Для более детальной информации ознакомтесь с документацией.
Циклы
Jade использует прекрасный синтаксис для написания циклов, так что вам не придётся прибегать к JavaScript. Давайте пройдёмся по элементам массива в цикле:
- var droids = ["R2D2", "C3PO", "BB8"];
div
h1 Famous Droids from Star Wars
for name in droids
div.card
h2= name
И это будет скомпилировано следующим образом:
Famous Droids from Star Wars
R2D2
C3PO
BB8
Посмотреть этот пример на CodePen
Вы можете перемещаться по объектам массива, а также исспользовать цикл while. Узнайте больше прочитав документацию.
Интерполирование
Совмещать текст и JavaScript таким образом
p= «Hi there,» + profileName + ». How are you doing?»
может начать мусолить вам глаз. Разве Jade не имеет более элегантного решения данной задачи? Поспорим?
- var profileName = "Danny Ocean";
div
p Hi there, #{profileName}. How are you doing?
Посмотреть этот пример на CodePen
Разве так не аккуратней?
Миксины
Миксины, они как функции, они принимают параметры в качестве входных данных и генерируют соответствующию разметку. Миксины оглашаются с помощью ключевого слова mixin.
mixin thumbnail(imageName, caption)
div.thumbnail
img(src="/img/#{imageName}.jpg")
h4.image-caption= caption
После того, как миксин был оглашён, вы можете его вызвать с помощью символа +.
+thumbnail("oceans-eleven", "Danny Ocean makes an elevator pitch.")
+thumbnail("pirates", "Introducing Captain Jack Sparrow!")
Что будет скомпилировано как:
Danny Ocean makes an elevator pitch.
Introducing Captain Jack Sparrow!
Собираем все вместе
Давайте соберём всё, что мы успели выучить, в один пример. Скажем, у нас есть массив фильмов, каждый объект которого содержит название фильма, актёрский состав (под-массив), рейтинг, жанр, ссылку на IMDB-страницу и путь к картинке (которая будет использована в качестве постера фильма). Массив будет иметь примерно такой выгляд:
- var movieList = [
{
title: "Ocean's Eleven",
cast: ["Julia Roberts", "George Clooney", "Brad Pitt", "Andy Garcia"],
genres: ["Comedy", "Thriller"],
posterImage: "/img/oceans-eleven",
imdbURL: "http://www.imdb.com/title/tt0240772/",
rating: 7
}
// etc...
];
У нас есть 10 фильмов и мы хотим сделать симпатичную разметку для каждого из них. Изначально, мы не предусмотрели использование ссылки на IMDB-страницу фильма. Если рейтинг фильма выше 5, мы даём ему иконку с поднятым большим пальцем руки вверх, в ином случае, большой палец — вниз. Мы используем все выше перечисленные полезные функции Jade для написания данного модульного кода, который выполнит следующие задачи:
- Создать миксин под названием movie-card
- Перебрать массив и вывести актёрский состав.
- Перебрать массив и вывести жанры.
- Проверить рейтинг фильма и присвоить ему соответсвующею иконку.
- Пребрать массив фильмов и использовать миксин для создания разметки.
И так, создадим миксин:
mixin movie-card(movie)
div.movie-card
h2.movie-title= movie.title
img.movie-poster(src=movie.posterImage)
h3 Cast
ul.cast
each actor in movie.cast
li= actor
div.rating
if movie.rating > 5
img(src="img/thumbs-up")
else
img(src="img/thumbs-down")
ul.genre
each genre in movie.genres
li= genre
В данном коде много чего происходит, но я уверен, что он вам понятен, так как мы это уже прошли. Теперь, всё, что нам нужно, — это вызвать данный миксин в цикле:
for movie in movieList
+movie-card(movie)
И всё! Разве это не классно?! Вот окончательный код:
- var movieList = [
{
title: "Ocean's Eleven",
cast: ["Julia Roberts", "George Clooney", "Brad Pitt", "Andy Garcia"],
genres: ["Comedy", "Thriller"],
posterImage: "/img/oceans-eleven",
imdbURL: "http://www.imdb.com/title/tt0240772/",
rating: 9.2
},
{
title: "Pirates of the Caribbean",
cast: ["Johnny Depp", "Keira Knightley", "Orlando Bloom"],
genres: ["Adventure", "Comedy"],
posterImage: "/img/pirates-caribbean",
imdbURL: "http://www.imdb.com/title/tt0325980/",
rating: 9.7
}
];
mixin movie-card(movie)
div.movie-card
h2.movie-title= movie.title
img.movie-poster(src=movie.posterImage)
h3 Cast
ul.cast
each actor in movie.cast
li= actor
div.rating
if movie.rating > 5
img(src="img/thumbs-up")
else
img(src="img/thumbs-down")
ul.genre
each genre in movie.genres
li= genre
for movie in movieList
+movie-card(movie)
А так код будет выглядеть после компиляции:
Ocean's Eleven
Cast
- Julia Roberts
- George Clooney
- Brad Pitt
- Andy Garcia
- Comedy
- Thriller
Pirates of the Carribean
Cast
- Johnny Depp
- Keira Knightley
- Orlando Bloom
- Adventure
- Comedy
Но стоп, погодите минутку! А что, если теперь нам нужна возвожность переходить на IMDB-страницу фильма при нажатии на его название? Нам всего лишь потребуется добавить одну строку
a (href=movie.imdbURL)
в наш миксин.
mixin movie-card(movie)
div.movie-card
a(href=movie.imdbURL)
h2.movie-title= movie.title
img.movie-poster(src=movie.posterImage)
h3 Cast
ul.cast
each actor in movie.cast
li= actor
div.rating
if movie.rating > 5
img(src="img/thumbs-up")
else
img(src="img/thumbs-down")
ul.genre
each genre in movie.genres
li= genre
Посмотреть этот пример на CodePen
Вывод
Сегодня мы с вами прошли путь от полного незнания препроцессора Jade к написанию, с его помощью, прекрасной модульной разметки. Это не всё, что может Jade, но я надеюсь, что данная статья задела ваше любопытство, и вы захотели узнать больше.
Важное примечание: как некоторые из вас, возможно, уже знают, Jade был переименован в Pug. В будущем, статьи о Jade будут использовать новое название «Pug» или «Pug.js».