Статьи

Нефритовое руководство для начинающих

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 для написания модульного кода, чтобы сделать следующее:

  1. Создать миксин для видеокарты
    • Переберите список актеров и покажите актеров. Мы сделаем то же самое с жанрами.
    • Проверьте рейтинг и решите, показывать ли большие или большие пальцы вниз.
  2. Перебирайте список фильмов и используйте миксин, чтобы создать одну карту на фильм.

Итак, давайте сначала создадим миксин.

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