Шаблонизация
Last updated
Last updated
Шаблонизация (templating) — метод связывания данных и разметки. Удобный способ генерации HTML по шаблону и данным. Используется на клиенте и сервере.
Суть шаблонизации заключается в том, чтобы отделить описание HTML от логики. Разметка помещается в отдельные файлы (шаблоны), а в местах, где необходимо вывести данные, размещаются специальные псевдопеременные. JS-код загружает нужный шаблон и заменяет в нем псевдопеременные на соответствующие данные.
На обычных сайтах, где HTML и CSS уже есть, элементы интерфейса получают готовый DOM и используя JavaScript вешают обработчики, оживляя его. Но в сложных интерфейсах разметка изначально отсутствует на странице. DOM создается с помощью JavaScript-кода динамически на основе данных, полученных с сервера или из других источников.
Представьте список постов на веб-странице, а так же любые другие ситуации, которые требуют отображения коллекции однотипных элементов, но с разными данными.
Данные для постов приходят от сервера как массив объектов, у нас есть шаблон одного поста. Используя цикл, мы можем пройтись по массиву объектов и вызвать функцию-шаблон для каждого объекта, результатом будет строка с подставленными данными. После чего мы в контейнер для постов просто повесим строку и браузер создаст разметку.
Это - стандартный подход написания динамических элементов интерфейса, данные для которых изменяются со временем.
Весь процесс требует нескольких простых шагов:
Наличие данных, которыми будет наполнятся элемент интерфейса
Шаблон, по которому будет составлена разметка элемента
Библиотека, которая предоставляет средства шаблонизации
Мы подробно рассмотрим это на примерах, но по сути это очень просто:
Подключить в проект выбранную библиотеку для шаблонизации
Составить HTML-шаблон необходимого вида
Сделать выборку шаблона в JS-файле
Произвести рендеринг шаблона вместе с данными
Шаблон — это строка в специальном формате, которая путём подстановки значений и выполнения встроенных фрагментов кода превращается в HTML.
Шаблон - это строка со специальными разделителями, которых в Handlebars всего три:
То есть синтаксис Handlebars
- это обычный HTML, с вставками вида {{...}}
. Именно в те места, где указаны вставки, будут помещены данные.
Шаблон - это просто многострочный HTML-текст, ему не место в файле скриптов. Один из способов — записать его в HTML-файле в тег template
.
Внешние шаблоны имеют много преимуществ, главным образом в том, что шаблоны никогда не будут загружаться клиенту, если они не нужны на странице. Для усвоения ключевых концепций будем пользоваться встроенными шаблонами.
Давайте обернем шаблон в тег template
и дадим ему уникальный идентификатор, чтобы можно было выбрать в JS-файле по селектору.
Вернемся к перечисленным шагам, где мы описали последовательность действий, необходимых для использования шаблонизации, и разберем по пунктам.
Подключение библиотеки в проект происходит очень просто. Есть несколько вариантов.
Скачать файл библиотеки и подключить его в index.html
Использовать CDN-сервис для получения ссылки на файл библиотеки
Если используется инструмент вроде Webpack
, можно ставить библиотеку как npm-пакет
Этот шаг мы выполнили выше и у нас уже есть полностью готовый шаблон для меню. Добавим его перед всеми скриптами в документе.
template
- это тег, значит мы можем выбрать его по селектору тега/класса/идентификатора. Хорошей практикой считается давать тегам template
, содержащим шаблон, идентификаторы, так как они уникальны.
Теперь в JS-файле мы можем по id
выбрать сам тег template
и его контент в виде строки, для этого используем свойство innerHTML
.
У нас уже есть библиотека и шаблон из которого мы изъяли текстовый контент. Для работы с шаблоном в библиотеке Handlebars
есть функция compile
. Эта функция запускает компиляцию шаблона source
и возвращает результат в виде функции, которую далее можно запустить с данными и получить строку-результат.
Вызов Handlebars.compile(source)
разбивает HTML-строку по разделителям и при помощи new Function
создаёт на её основе функцию. Тело этой функции создаётся таким образом, что код, который в шаблоне оформлен как {{...}}
, попадает в неё как есть, а переменные и текст прибавляются к специальному временному буферу, который в итоге возвращается.
Теперь используя функцию-шаблон template
можем передать ей данные как аргумент и она вернет HTML-строку.
Для начала добавим данные для списка. В шаблоне указаны какие-то переменные title
и items
.
В реальных задачах сначала создаются форматы для данных, а потом под них пишутся шаблоны, но для наглядности мы для шаблона напишем данные.
Данные для шаблона - это что угодно, строка, объект, массив и т.д., зависит от задачи, чаще всего - объект или массив объектов. Так как у нас список с заголовком и набором пунктов, нам удобно использовать объект такого вида.
Следующим шагом будет вызвать функцию-шаблон и передать ей menuData
как аргумент. В результате получим строку с подставленными значениями, поместим ее в тег и браузер, распарсив ее, создаст HTML-разметку.
Когда используем сборщик модулей, очень удобно работать со внешними шаблонами.
Добавляем библиотеку.
Обновляем конфигурацию Webpack, добавляя настройки загрузчика.
В папке src
создаем папку templates
, в которой добавляем файлы шаблонов с расширением .hbs
. Для нашего меню это будет menu.hbs
. Помещаем разметку шаблона в файл, без тега template
.
Там, где хотим использовать шаблон, импортируем файл с шаблоном. Особенность в том, что при импорте, handlebars-loader
обработает файл шаблона и в menuTemplate
уже будет лежать скомпилированная функция-шаблон готовая к использованию.
Синтаксис шаблона зависит от библиотеки, самое важное - это понимать принцип работы шаблонизаторов. Мы будем использовать библиотеку .
Более современный способ, например при использовании Webpack
, хранить шаблон в отдельном файле и импортировать его. Для этого в конфигурацию Webpack
нужно добавить .
Пока что используем CDN. В разделе библиотеки есть ссылка на CDN-сервис на котором можно скопировать необходимый URL. Это - минифицированая версия библиотеки. Все что нужно сделать — это добавить еще один тег script
перед нашим файлом скриптов и перед закрывающим тегом body
в index.html
.
Добавляем загрузчик .