Статьи

Интеграция шаблонов Jade в Rails для более чистых шаблонов

нефрит

Рендеринг динамического контента в веб-приложении может быть выполнен с использованием множества инструментов, один из которых использует 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, его простота использования и плавная интеграция, безусловно, перевешивают его ограничения.