Прекомпиляция шаблонов Handlebars
Инструменты

Прекомпиляция шаблонов Handlebars

В прошлой статье мы рассмотрели способ хранения шаблонов Handlebars в отдельных файлах. При этом для загрузки шаблона использовался AJAX-запрос, а после получения файла шаблона он компилировался. Запрос файла шаблона создает хоть и небольшую, но все же задержку. Чтобы ее избежать, можно заранее скомпилировать шаблоны и при отображении использовать готовые функции, в которые всего лишь нужно будет подставить данные. Давайте рассмотрим пример прекомпиляции шаблонов Handlebars.js с помощью gulp.

Файловая структура

Я буду использовать следующую файловую структуру в своем примере:

js/templates/
js/templates/common.layout.html
js/templates/common.menu.html
js/templates/users.list.html
js/templates/users.pager.html
...

Вы можете использовать любую другую организацию файлов, которая вам нравится. В таске для gulp, которая будет компилировать шаблоны, нужно будет указать актуальный путь к файлам шаблонов.

Используемые плагины

Для компиляции шаблонов будем использовать плагин gulp-handlebars. Если вы плохо знакомы с gulp, основы работы описаны в статье. Еще нам потребуется плагин gulp-wrap — он позволяет обернуть содержимое потока в некоторую строку (в нашем случае это Handlebars.template()) и плагин gulp-declare для создания пространства имен для шаблонов.

Перечисленные плагины в нашем случае должны делать следующее.

  • Плагин gulp-handlebars принимает файл шаблона и компилирует его в специальный объект, содержащий как сам шаблон, так и некоторую служебную информацию.
  • Плагин gulp-wrap оборачивает этот объект в вызов функции Handlebars.template(), которая возвращает новую функцию. Эта функция уже может использоваться как шаблон, она принимает объект с данными, которые необходимо подставить в шаблон и возвращает строку — результат подстановки.
  • Плагин gulp-declare создает указанное пространство имен и каждую функция из предыдущего шага добавляет в это пространство имен.

Далее мы просто используем gulp-concat, чтобы объединить все шаблоны в один файл.

Задача для gulp

Соберем все вместе в задачу для gulp.


var handlebars = require('gulp-handlebars');
var wrap       = require('gulp-wrap');
var declare    = require('gulp-declare');
var concat     = require('gulp-concat');

gulp.task('templates', function(){
    gulp.src('js/templates/*.html')
        .pipe(handlebars())
        .pipe(wrap('Handlebars.template(<%= contents %>)'))
        .pipe(declare({
            namespace: 'App.templates',
            noRedeclare: true
        }))
        .pipe(concat('templates.js'))
        .pipe(gulp.dest('assets'));
});

В этом таске мы сначала компилируем все шаблоны *.html из директории js/templates/, затем оборачиваем каждый в вызов функции Handlebars.template(), добавляем результирующую функцию в пространство имен App.templates, объединяем с помощью gulp-concat в файл templates.js и кладем его в директорию assets.

Использование прекомпилированных шаблонов

Использовать прекомпилированные шаблоны очень просто. Для этого необходимо вызвать соответствующую функцию из пространства имен App.templates. Рассмотрим пример.

Допустим у нас есть шаблон js/templates/common.menu.html следующего содержимого:


<div class="main-menu">
    <ul class="main-menu__items">
        {{#each items}}
            <li class="main-menu__item {{#if active}} main-menu__item_type-active {{/if}}">
                <a href="#{{code}}">{{label}}</a>
            </li>
        {{/each}}
    </ul>
</div>

Этот шаблон принимает список элементов меню items и отображает их. После прекомпиляции это шаблон будет доступен в виду функции App.templates.common.menu().

Чтобы отобразить меню, необходимо вызвать эту функцию, передав ей список элементов меню:


var menuItems = [
    { code: 'main', label: 'Main page', active: true },
    { code: 'products', label: 'Products', active: false },
    { code: 'users', label: 'Users', active: false }
];
$('.menu-container').html(App.templates.common.menu());

Заключение

Прекомпиляция шаблонов Handlebars - это отличный вариант для средних и крупных проектов. Такой способ позволяет одновременно хранить шаблоны в отдельных файлах и не делать лишний AJAX-запрос для получения шаблона.

Рассылка
Подпишитесь на рассылку и получайте дайджест новостей и статей.
Никакого спама!
Подписаться