Естественно, части хранятся в папке part
. Пусть имеется некий код аутентификации пользователя, который можно использовать повторно. Тогда дерево частей приложения могло бы выглядеть так:
<app_root>/part/users
<app_root>/part/users.rb
<app_root>/part/users/public/
<app_root>/part/users/controller.rb
<app_root>/part/users/model/user.rb
<app_root>/part/users/model/acl.rb
<app_root>/part/users/template/login.xhtml
<app_root>/part/users/template/form.xinc
<app_root>/part/users/run.rb
Главный файл run.rb
мог бы включить такую часть с помощью одной директивы require
:
require 'part/users'
Теперь Nitro будет рассматривать весь код в каталоге part/users
, как если бы он находился в дереве исходных текстов главного приложения. Поиск шаблонов начинается в папке template приложения и продолжается в подкаталогах каталога part
. Если вы хотите переопределить шаблон, поставляемый вместе с частью, то нужно просто поместить замещающий вариант в соответствующий подкаталог папки template
.
Часто приложение должно отображать повторяющиеся данные; обычно они оформлены в виде HTML-таблицы в шаблоне. Если число строк заранее не известно, то придется обойти какой-то набор.
Можно встроить код Ruby непосредственно в шаблон, но Nitro предлагает специальный механизм конвейерной компиляции, чтобы упростить программирование типичных логических конструкций.
Morphing
исследует разметку в шаблоне и ищет специальные атрибуты, которые обозначают различные преобразования.
В нашем демонстрационном приложении данных мало, но если представить себе много авторов, каждый из которых написал несколько книг, то можно было бы показать список книг данного автора. Метод контроллера поместил бы в переменную @books
список книг, а часть шаблона для обхода этого цикла могла бы выглядеть так:
<h4>Books by #{@author}</h4>
<ul>
<li each='book in @books' > #{book.title}</li>
</ul>
Класс Morphing
находит атрибут each элемента li и преобразует его в следующий код:
<?r for book in @books ?>
<li>#{book.title} </li>
<?r end ?>
Порожденная таким образом разметка передается следующему этапу конвейера.
Точно так же для повтора элемента можно использовать атрибут times
. Например, фрагмент
<img src='/img/ruby.png' alt='*' times='@book.rating' />
будет преобразован в следующий код:
<?r 3.times do ?>
<img src='/img/ruby.png' alt='*' />
<?r end ?>
19.4.5. Прочие детали
В Nitro слишком много различных механизмов, чтобы все их можно было рассмотреть здесь. Но в этом разделе мы упомянем некоторые особенно приятные «вкусности».
В состав Nitro входит вспомогательный код, позволяющий использовать многочисленные библиотеки JavaScript, которые поддерживают различные формы DHTML и Ajax. Для облегчения интеграции в Nitro применяется высокоуровневый синтаксис. Например, в дистрибутиве Nitro есть пример поиска по сайту Flickr и вывода уменьшенных изображений. Текстовое поле для ввода тегов поиска поддерживает технологию Ajax, что достигается следующей разметкой:
<input type='text' id='tags' name='tags' auto_complete='true' />
Контроллер реализует метод tags_auto_complete
, который возвращает строку в формате XML, зависящую от содержимого поля.
Nitro позволяет кэшировать действия (то есть отрисованные страницы целиком), результаты вызова методов и сгенерированные фрагменты текста. Например, чтобы поместить в кэш результат отрисовки страницы index, контроллер должен вызвать следующий метод:
cache_output :index
Кэширование можно добавить и в сегменты кода:
<?r cache(:book_list_cache_key) do ?>
<ul>
<li each='book in Books.all'>#{book.title}</li>
</ul>
<?r end ?>
В Nitro встроен класс преобразования для локализации, позволяющий автоматически подставлять в шаблон то или иное содержимое. Он не является стандартным этапом конвейерной компиляции, вы сами должны добавить его в файл run.rb
:
require 'nitro/compiler/localization'
include Nitro
Compiler.transformation_pipeline = [
StaticInclude,
Elements,
Morphing,
Markup,
Localization,
Cleanup
]
Отметим, что конвейер можно переконфигурировать, выбросив стандартные преобразования и добавив собственные. Далее определяются локали:
Localization.locales = {
:en => 'conf/locales/en.yml',
:de => 'conf/locales/de.yml'
}
---
:author: Autor