Рендеринг динамического контента в веб-приложении может быть выполнен с использованием множества инструментов, один из которых использует Javascript Template Engine . Он использует язык со специальной разметкой, предназначенной для визуализации динамического содержимого в объектную модель документа .
Большая часть разметки, используемой механизмами шаблонов javascript, напоминает HTML, но некоторые идут дальше, представляя новую разметку, разработанную с конкретной целью. Jade обладает уникальной характеристикой по сравнению с другими языками шаблонов JavaScript. Это упрощает разметку, устраняя использование угловых скобок и закрывающих тегов.
В этой статье я покажу, как интегрировать Jade в приложение Ruby on Rails . Например, приложение будет похоже на твиттер , включая функции временной шкалы и профиля пользователя, чтобы продемонстрировать интеграцию.
Некоторые примеры кода в этой статье взяты из примера приложения, а некоторые являются упрощенным кодом, взятым из примера кода. Законченная версия доступна на Github , а также есть онлайн- версия, демонстрирующая его внешний вид.
Введение в Джейд
Позвольте мне начать с знакомства с основами Джейд. Прочитав этот раздел, вы сможете понять основную конструкцию Jade. Это, однако, не пытается копировать документацию Jade. Вместо этого я выделю наиболее часто используемые функции в Jade, чтобы вы могли быстро начать работу.
Всегда хорошо начать с того, что ты знаешь. Вот сравнение между ERB (Embedded Ruby) , Jade и сгенерированным HTML. Следующий код взят из законченной версии моей реализации шаблона твита. Беглый взгляд на следующий код должен дать вам представление о том, чем Jade отличается от ERB:
Еврорадио
<li class="tweet">
<%= link_to tweet.user do %>
<img src="<%= tweet.user.thumbnail %>" class="tweet__photo" />
<% end %>
<div class="tweet__body">
<div class="tweet__info">
<%= link_to tweet.user.name, tweet.user, class: "tweet__name" %>
<%= link_to "@#{tweet.user.username}", tweet.user, class: "tweet__username" %>
<span class="tweet__date timeago" title="<%= tweet.created_at.iso8601 %>"></span>
</div>
<div class="tweet__text"><%= tweet.text %></div>
</div>
</li>
нефрит
li.tweet
a(href=tweet.user.links.self)
img.tweet__photo(src=tweet.user.thumbnail)
.tweet__body
.tweet__info
a.tweet__name(href=tweet.user.links.self)=tweet.user.name
a.tweet__username(href=tweet.user.links.self) @#{tweet.user.username}
span.tweet__date.timeago(title=tweet.created_at)
.tweet__text=tweet.text
Сгенерированный HTML
<li class="tweet">
<a href="/@johnappleseed">
<img class="tweet__photo" src="/path/to/image.jpg">
</a>
<div class="tweet__body">
<div class="tweet__info">
<a class="tweet__name" href="/@johnappleseed">John Appleseed</a>
<a class="tweet__username" href="/@johnappleseed">@johnappleseed</a>
<span class="tweet__date timeago" title="2015-11-30t01:30:10z"></span>
</div>
<div class="tweet__text">The quick brown fox jumps over the lazy dog</div>
</div>
</li>
Взгляд на приведенный выше код показывает четкую разницу между Jade и ERB. Джейд выглядит проще и чище, чем ERB. Это связано с отсутствием закрывающих тегов и угловых скобок в Jade.
Имя тега, идентификатор, класс и атрибуты
Из предыдущего примера шаблона видно, что Jade использует имя тега, идентификатор и литералы CSS для создания структуры DOM. Атрибуты похожи на те, что в HTML, но их значения — просто обычный javascript. А поскольку теги div
Следующий код:
li.tweet#tweet(title="tweet")
.tweet__body
Будет оказывать:
<li id="tweet" class="tweet" title="tweet">
<div class="tweet__body"></div>
</li>
Буферизация и интерполяция
Внутри шаблона вы можете выполнять все виды операций JavaScript, таких как буферизация кода для записи в шаблон и интерполяция строк. Рассмотрим следующий пример. Предположим, вы передаете объект tweet
var tweet = {
text: "The quick brown fox jumps over the lazy dog",
user: {
name: "John Appleseed",
username: "johnappleseed",
thumbnail: "/path/to/image.jpg",
links: {
self: "/@johnappleseed"
}
}
};
Вы можете создать ссылку на пользователя следующим образом:
a.tweet__name(href=tweet.user.links.self)=tweet.user.name
Выше будет генерировать следующий HTML:
<a class="tweet__name" href="/@johnappleseed">John Appleseed</a>
Если вы хотите интерполировать строку, вы можете использовать знакомый оператор #{}
a.tweet__username(href=tweet.user.links.self) @#{tweet.user.username}
И это сделает следующий HTML.
<a class="tweet__username" href="/@johnappleseed">@johnappleseed</a>
Интеграция
Интеграция Jade в Rails требует нескольких шагов. Этапы установки довольно просты, но на момент написания этой статьи существует проблема совместимости с последней версией Rails. Для решения этой проблемы есть обходной путь, см. Инструкции по установке для получения более подробной информации.
Установка
Чтобы иметь работающую установку Jade в приложении Rails, поместите в свой Gemfile следующие гемы:
# Gemfile
gem 'ejs'
gem 'jade-rails', '1.9.2'
И требуется Jade Runtime для вашего application.js :
# app/views/assets/javascripts/application.js
//= require jade/runtime
Как отмечалось ранее, на момент написания этой статьи существует проблема компиляции шаблонов для Rails версии 4.2.5. Пожалуйста, замените камень jade-rails
# Gemfile
gem 'jade-rails', github: 'hendrauzia/jade-rails', branch: 'rails-4-2-5'
Как примечание, вышеупомянутый источник на момент написания этой статьи не был объединен с жемчужиной jade-rails
Пожалуйста, ознакомьтесь с выпусками Jade-Rails, чтобы увидеть, было ли применено исправление.
Шаблоны
Шаблоны должны быть размещены в определенном месте в вашем приложении. Вам нужно поместить их в app / assets / javascripts / templates и дать им расширение .jst.jade
Вы также можете добавить другой препроцессор к своим шаблонам, например: .erb
Смотрите следующий пример:
# app/assets/javascripts/templates/tweet.jst.jade
li.tweet
...
Вот небольшой совет, если вам нужно поместить ресурсы изображения в шаблон: добавьте ERB к вашему препроцессору шаблона и добавьте расширение .erb
Таким образом, активы могут быть обработаны с использованием соответствующего дайджеста. Например, вы можете захотеть предоставить изображение по умолчанию, когда у пользователя нет изображения:
# app/assets/javascripts/templates/tweet.jst.jade.erb
li.tweet
a(href=tweet.user.links.self)
if tweet.user.thumbnail
img.tweet__photo(src=tweet.user.thumbnail)
else
<%= image_tag "users/default.jpg", class: "tweet__photo" %>
И не забудьте указать свой шаблон в application.js :
# app/assets/javascripts/application.js
//= require templates/tweet
Остальные функции шаблона можно найти в документации Jade. Но прежде чем вы решите заняться какими-нибудь модными делами, пожалуйста, прочитайте оставшуюся часть моего вступления
оказание
Возможность рендеринга шаблонов в Jade предоставляется ejs
Чтобы отобразить шаблон, используйте следующую инструкцию и поместите ее в свой файл JavaScript. Используя наш предыдущий пример, если мы хотим визуализировать шаблон, нам нужен объект tweet
var tweet = {
text: "The quick brown fox jumps over the lazy dog",
user: {
name: "John Appleseed",
username: "johnappleseed",
thumbnail: "/path/to/image.jpg",
links: {
self: "/@johnappleseed"
}
}
};
var htmlString = JST['templates/tweet']({ tweet: tweet });
Приведенный выше код сгенерирует следующий HTML-код:
<li class="tweet">
<a href="/@johnappleseed">
<img src="/path/to/image.jpg" class="tweet__photo">
</a>
<div class="tweet__body">
<div class="tweet__info">
<a class="tweet__name" href="/@johnappleseed">john appleseed</a>
<a class="tweet__username" href="/@johnappleseed">@johnappleseed</a>
<span class="tweet__date timeago" title="2015-11-30t01:30:10z"></span>
</div>
<div class="tweet__text">the quick brown fox jumps over the lazy dog</div>
</div>
</li>
Если вам нужна дополнительная настройка, например, присоединение прослушивателей событий к DOM или иное связывание с DOM до добавления в контейнер, вы можете создать объект JQuery из DOM и предварительно обработать его.
Например, здесь мы пытаемся прикрепить timeago к дате твита:
var htmlDOM = $(JST['templates/tweet']({ tweet: tweet }));
htmlDOM.find(".timeago").timeago();
После того, как все установлено и сделано, вы можете добавить отображаемый HTML-код в любой контейнер, который вы хотите. В этом случае, скажем, мы хотим поставить в конце временной шкалы:
$('.timeline').append(htmlDOM);
Ограничения
Интеграция Jade в Rails не лишена ограничений. В Jade есть функции, которые недоступны в клиенте. Например, includes
и extends
недоступны в текущем стабильном геме jade-rails. В качестве обходного пути вы можете вручную добавить сгенерированный HTML к другому сгенерированному HTML, используя JavaScript.
Вывод
Jade — это простой и чистый движок шаблонов JavaScript. Он может быть легко интегрирован в приложение Rails и прекрасно работает с конвейером ресурсов. Рендеринг шаблонов очень прост и не требует много настроек, но все же он не без ограничений. Jade должен удовлетворять общие потребности в рендеринге шаблонов javascript, его простота использования и плавная интеграция, безусловно, перевешивают его ограничения.