Jade — элегантный движок шаблонов, в основном используемый для серверных шаблонов в NodeJS. Проще говоря, Jade дает вам новый мощный способ написания разметки с рядом преимуществ по сравнению с обычным HTML .
Например, посмотрите на эту карту фильма в HTML:
<div> <h1>Ocean's Eleven</h1> <ul> <li>Comedy</li> <li>Thriller</li> </ul> <p>Danny Ocean and his eleven accomplices plan to rob three Las Vegas casinos simultaneously.</p> </div>
Вот как выглядит та же самая разметка в 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
- Простые теги
- Добавление атрибутов в теги
- Блоки текста
Если вы хотите попробовать это по ходу дела, вы можете использовать CodePen и выбрать Jade в качестве HTML-препроцессора или использовать онлайн-компилятор на официальной странице Jade для компиляции вашего Jade в HTML.
Простые теги
Как вы могли заметить ранее, в Jade нет закрывающих тегов. Вместо этого Jade использует отступ (т. Е. Пробел), чтобы определить, как вкладываются теги.
div p Hello! p World!
В приведенном выше примере, поскольку теги абзаца имеют отступ, они окажутся внутри тега div
. Просто!
<div> <p>Hello!</p> <p>World!</p> </div>
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
Довольно аккуратно, верно?
<div class="movie-card" id="oceans-11"> <h1 class="movie-title">Ocean's 11</h1> <img src="/img/oceans-11.png" class="movie-poster"> <ul class="genre-list"> <li>Comedy</li> <li>Thriller</li> </ul> </div>
Посмотреть этот пример на 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 прекращает обрабатывать первое слово в каждой строке как тег HTML.
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
И просто для понимания, если бы я убрал точку после тэга p
в этом примере, скомпилированный HTML будет рассматривать «I» в слове «I’m» как открывающий тэг (в данном случае это будет тегом <i>
).
Мощные функции
Теперь, когда мы рассмотрели основы, давайте взглянем на некоторые мощные функции, которые сделают вашу разметку умнее. Мы рассмотрим следующие функции в оставшейся части этого урока:
- Loops
- JavaScript
- интерполирование
- Примеси
Использование JavaScript в Jade
Jade реализован с использованием JavaScript, поэтому в Jade очень просто использовать JavaScript. Вот пример.
- var x = 5; div ul - for (var i=1; i<=x; i++) { li Hello - }
Что мы здесь только что сделали ?! Начиная строку с дефиса, мы указываем компилятору Jade, что мы хотим начать использовать JavaScript, и он просто работает так, как мы ожидали. Вот что вы получите, скомпилировав код Jade выше в HTML:
<div> <ul> <li>Hello</li> <li>Hello</li> <li>Hello</li> <li>Hello</li> <li>Hello</li> </ul> </div>
Посмотреть этот пример на CodePen
Мы используем дефис, когда код напрямую не добавляет вывод. Если мы хотим использовать JavaScript для вывода чего-либо в Jade, мы используем =
. Давайте настроим код выше, чтобы показать серийный номер.
- var x = 5; div ul - for (var i=1; i<=x; i++) { li= i + ". Hello" - }
И вуаля, теперь у нас есть серийные номера:
<div> <ul> <li>1. Hello</li> <li>2. Hello</li> <li>3. Hello</li> <li>4. Hello</li> <li>5. Hello</li> </ul> </div>
Посмотреть этот пример на CodePen
Конечно, в этом случае упорядоченный список будет гораздо более уместным, но вы получите точку. Теперь, если вы беспокоитесь о выходе из XSS и HTML, прочтите документацию для получения дополнительной информации .
Loops
Jade предоставляет отличный синтаксис зацикливания, так что вам не нужно прибегать к JavaScript. Давайте зациклим массив:
- var droids = ["R2D2", "C3PO", "BB8"]; div h1 Famous Droids from Star Wars for name in droids div.card h2= name
И это будет скомпилировано следующим образом:
<div> <h1>Famous Droids from Star Wars</h1> <div class="card"> <h2>R2D2</h2> </div> <div class="card"> <h2>C3PO</h2> </div> <div class="card"> <h2>BB8</h2> </div> </div>
Посмотреть этот пример на CodePen
Вы можете перебирать объекты и использовать циклы while
. Проверьте документы для больше .
интерполирование
p= "Hi there, " + profileName + ". How are you doing?"
JavaScript в текст, например, можно так: p= "Hi there, " + profileName + ". How are you doing?"
, Есть ли у Джейд элегантное решение для этого? Вы ставите.
- var profileName = "Danny Ocean"; div p Hi there, #{profileName}. How are you doing?
Посмотреть этот пример на CodePen
Разве это не аккуратно?
Примеси
Mixins — это как функции. Они принимают параметры в качестве входных данных и дают разметку в качестве выходных данных. Миксины определяются с помощью ключевого слова 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!")
Который будет выводить HTML так:
<div class="thumbnail"> <img src="/img/oceans-eleven.jpg"> <h4 class="image-caption"> Danny Ocean makes an elevator pitch. </h4> </div> <div class="thumbnail"> <img src="/img/pirates.jpg"> <h4 class="image-caption"> Introducing Captain Jack Sparrow! </h4> </div>
Собираем все вместе
Давайте соединим все, что мы узнали до сих пор. Скажем, у нас есть хороший набор фильмов, каждый из которых содержит название фильма, актерский состав (подмассив), рейтинг, жанр, ссылку на страницу 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 для написания модульного кода, чтобы сделать следующее:
- Создать миксин для видеокарты
- Переберите список актеров и покажите актеров. Мы сделаем то же самое с жанрами.
- Проверьте рейтинг и решите, показывать ли большие или большие пальцы вниз.
- Перебирайте список фильмов и используйте миксин, чтобы создать одну карту на фильм.
Итак, давайте сначала создадим миксин.
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)
И вот скомпилированный HTML:
<div class="movie-card"> <h2 class="movie-title">Ocean's Eleven</h2> <img src="/img/oceans-eleven" class="movie-poster"/> <h3>Cast</h3> <ul class="cast"> <li>Julia Roberts</li> <li>George Clooney</li> <li>Brad Pitt</li> <li>Andy Garcia</li> </ul> <div class="rating"> <img src="img/thumbs-up"/> </div> <ul class="genre"> <li>Comedy</li> <li>Thriller</li> </ul> </div> <div class="movie-card"> <h2 class="movie-title">Pirates of the Carribean</h2> <img src="/img/pirates-caribbean" class="movie-poster"/> <h3>Cast</h3> <ul class="cast"> <li>Johnny Depp</li> <li>Keira Knightley</li> <li>Orlando Bloom</li> </ul> <div class="rating"> <img src="img/thumbs-up"/> </div> <ul class="genre"> <li>Adventure</li> <li>Comedy</li> </ul> </div>
В<div class="movie-card"> <h2 class="movie-title">Ocean's Eleven</h2> <img src="/img/oceans-eleven" class="movie-poster"/> <h3>Cast</h3> <ul class="cast"> <li>Julia Roberts</li> <li>George Clooney</li> <li>Brad Pitt</li> <li>Andy Garcia</li> </ul> <div class="rating"> <img src="img/thumbs-up"/> </div> <ul class="genre"> <li>Comedy</li> <li>Thriller</li> </ul> </div> <div class="movie-card"> <h2 class="movie-title">Pirates of the Carribean</h2> <img src="/img/pirates-caribbean" class="movie-poster"/> <h3>Cast</h3> <ul class="cast"> <li>Johnny Depp</li> <li>Keira Knightley</li> <li>Orlando Bloom</li> </ul> <div class="rating"> <img src="img/thumbs-up"/> </div> <ul class="genre"> <li>Adventure</li> <li>Comedy</li> </ul> </div>
В<div class="movie-card"> <h2 class="movie-title">Ocean's Eleven</h2> <img src="/img/oceans-eleven" class="movie-poster"/> <h3>Cast</h3> <ul class="cast"> <li>Julia Roberts</li> <li>George Clooney</li> <li>Brad Pitt</li> <li>Andy Garcia</li> </ul> <div class="rating"> <img src="img/thumbs-up"/> </div> <ul class="genre"> <li>Comedy</li> <li>Thriller</li> </ul> </div> <div class="movie-card"> <h2 class="movie-title">Pirates of the Carribean</h2> <img src="/img/pirates-caribbean" class="movie-poster"/> <h3>Cast</h3> <ul class="cast"> <li>Johnny Depp</li> <li>Keira Knightley</li> <li>Orlando Bloom</li> </ul> <div class="rating"> <img src="img/thumbs-up"/> </div> <ul class="genre"> <li>Adventure</li> <li>Comedy</li> </ul> </div>
Но подожди минутку. Что, если мы теперь хотим перейти на страницу 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 был переименован в Pug из-за претензии на торговую марку программного обеспечения. В будущем в статьях о Jade будет использоваться новое имя «Pug» или «PugJS».