# Разделение документа на части
При создании проектов, часто возникает необходимость дублировать те или иные элементы страницы, тем самым растет и разметка страницы, в таких случаях, лучше всего выносить дублирующие элементы в отдельные файлы и включать их по мере необходимости.
Основные привилегии разделения файла на части: - Избежание повторного копирования компонентов - Быстрое изменение одного компонента вместо десятка повторяющихся - Для автоматического назначения атрибутов у повторяющихся элементов, например для привязки input к label путем добавления уникального идентификатора при каждом включении и тд. - Для отделения данных от HTML разметки, например вынести текст в отдельные файлы
Приведем несколько примеров.
В проекте имеются несколько HTML страниц, и каждая страница состоит из трех основных частей:
- Head
- Body
- Footer
body является динамическим элементом и зависит от страницы, head и footer - глобальные, то есть, они повторяются на каждой странице. Создадим проект исходя из наших требований:
.
└─ source
└─ html
├─ index.html
├─ contact_us.html
└─ global
|─ head.html
└─ footer.html
head.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>My page</title>
</head>
<body>
footer.html
<footer>
<p class="copyright">Lorem ipsum dolor sit.</p>
</footer>
<script src="/jquery.js"></script>
</body>
</html>
index.html, contact_us.html
{{{include "global/head.html"}}}
<div class="app">
<!-- ... -->
</div>
{{{include "global/footer.html"}}}
Выше продемонстрирован классический подход разделения html страницы на части, который позволяет в будущем изменять глобальные части в одном месте, а не в каждом файле по отдельности. В данном примере мы использовали include handlebars helper, о нем поговорим позже.
Разделение страницы на статические части, не позволяют использовать их с разными входными параметрами, для этого существуют шаблоны.
# HTML страницы и части
Начнем с того, что HTML плагин видит два типа .html файлов:
- Страница
- HTML часть
не важно, где они располагаются в проекте, плагин подхватит их и обработает соответствующим образом. Отличия страниц от частей:
- Страницы - являются корневым документом, и не могут быть включены в другие страницы!
- Части - отдельно вынесенная часть html разметки, которая может быть включена в другие части или в страницы!
Распознавание осуществляется автоматически по следующим критериям:
- Страницы имеют
<html></html>
элемент
однако, этим поведением можно управлять путем добавление в документ комментария UNGIC:PART
или UNGIC:PAGE
:
<!-- UNGIC:PART -->
<html lang="en">
<!-- Преобразовали страницу в часть -->
</html>
или
<!-- UNGIC:PAGE -->
<body>
<!-- Преобразуем часть в страницу -->
</body>
TIP
- HTML страницы не могут быть включены друг в друга!
- HTML части могут включать в себя другие части и быть включены в HTML страницы!
TIP
Части и страницы могут включать в себя любой поддерживаемый тип файлов HTML плагина с помощью include инструмента.
Стоит отметить, что html части и страницы обрабатываются handlebars шаблонизатором (opens new window) и имеют глобальный объект данных, но не имеют возможность принимать динамические данные!.
# Глобальный объект данных
При включении частей или шаблонов с помощью include инструмента, передаются глобальные данные ungic проекта, а также, информация о текущем корневом документе и включаемом шаблоне:
{
"ungic": {
"fs": {
"dirs": {
"source": "source",
"dist": "dist",
"temp": "temp"
},
"dist": {
"css": "css",
"fonts": "fonts",
"img": "img",
"js": "js"
},
"source": {
"scss": "scss",
"html": "html",
"icons": "icons",
"assets": "assets"
}
},
// Информация о проекте
"project": {
"name": "app",
"version": "1.0.0",
"author": "unbywyd",
"address": "http://127.0.0.1:2020"
},
// Текущая модель шаблона
"model": {
"id": "dGVtcGxhdGVcdGVzdC5oYnM=",
"path": "template\\test.hbs"
},
// Информация о корневой странице
"page": {
"id": "dGVzdC5odG1s",
"path": "test.html"
},
"UID": "_drvazpg3t"
}
}
# Поддерживаемые типы файлов для включения
Простые типы:
- .html - html части, обрабатываются с помощью handlebars шаблонизатора
- .text - текстовые файлы включаются в виде текста
- .md - markdown документы включаются в виде HTML
Шаблоны:
- .hbs - handlebars шаблоны
типы файлов, которые могут быть использованы в виде данных:
- .json - файл с данными в JSON формате
- .yaml - файл с данными в YAML формате
Включение выше перечисленных типов файлов осуществляется непосредственно с помощью include инструмента.
Кроме того, HTML плагин позволяет расширять список поддерживаемых файлов, путем добавления пользовательский обработчиков!
TIP
HTML плагин позволяет зарегистрировать любой пользовательский тип файлов и создать для них обработчики!
# Шаблоны
В примере выше, мы использовали статические файлы для включения head.html и footer.html часть в нашу страницу, улучшим наш пример с использованием шаблонов:
Для того, чтобы наша "шапка" сайта принимала динамический заголовок, переименуем наш head.html файл в head.hbs, теперь наш файл обрабатывается handlebars шаблонизатором и готов принимать данные!
Изменим включение head.html файла на head.hbs и передадим данные в виде queryString, а точнее заголовок страницы:
index.html
{{{include "global/head.hbs" data="title=Home page"}}}
<div class="app">
<!-- ... -->
</div>
{{{include "global/footer.html"}}}
включим наши данные в сам шаблон:
head.hbs
теперь, наша "шапка" страницы может получать динамический заголовок в зависимости от страницы проекта:
contact_us.html
{{{include "global/head.hbs" data="title=Contact us"}}}
<div class="app">
<!-- ... -->
</div>
{{{include "global/footer.html"}}}
TIP
Шаблоны могут включаться в любые сущности которые обрабатываются handlebars шаблонизатором! По умолчанию, это .html страницы, .html части и сами .hbs шаблоны!
TIP
Для включения шаблонов используется include инструмент, а для передачи данных используется аргумент data.
# Данные для шаблонов
Данные которые можно передать для генерации шаблонов:
- ссылку на .json файл с данными
- ссылку на .yaml файл с данными
- инлайн в queryString формате
- идентификаторы экспортируемых данных из SASS фреймворка
- icons идентификатор для включения экспортируемых данных из Icons плагина (Устарело, следует использовать параметр icons)
# data
С помощью data аргумента осуществляется передача данных к шаблону! Значением data аргумента может быть:
Относительный путь к .JSON / .YAML файлам
queryString значение
объект данных (можно передавать данные от шаблона к шаблону)
icons значение для включения данных об иконках
# icons данные
Для того, чтобы передать включаемому шаблону данные об иконках проекта из Icons плагина, следует воспользоваться параметром icons
./templates/head.hbs
# Данные из SASS framework
SASS framework экспортирует данные о текущем sass проекте, кроме того, все компоненты sass фреймворка могут экспортировать данные в JSON формате. Все экспортируемые данные попадают в dist/exports/sass-options.json файл текущего проекта, кроме этого, все экспортируемые данные доступны HTML плагину и могут быть использованы при генерации шаблонов.
Для того, чтобы включить данные из SASS фреймворка, следует воспользоваться sass аргументом include инструмента:
Экспортируем данные из app компонента
// components/app/once.scss
$export: this.export('author', (nickname: "Unbywyd"));
Использование:
# cwd
С помощью cwd аргумента, можно назначать базовый путь к файлам относительно source/html
директории:
# move
Данный аргумент является дополнением к data параметру, позволяет передавать входные данные в включаемый шаблон, пример:
# Отслеживание входных данных
Для того, чтобы узнать какие данные пришли к шаблону, следует воспользоваться debug инструментом:
head.hbs
Можно передать путь вложения объекта для отслеживания:
Обратите внимание! Данный инструмент выводит на экран иерархическое дерево с входными данными в JSON формате, данный элемент является частью HTML, именно поэтому debug нужно использовать в валидном HTML месте, а точнее, должен находиться в видимом элементе (не скрытом посредством css), который располагается непосредственно в body элементе.
WARNING
Место использования debug
инструмента влияет на его отображение в браузере! Используйте данный инструмент в валидном html месте документа.
# Пользовательский тип файлов
В первых версиях ungic, кроме handelbars была поддержка pug, underscore и mustache шаблонизаторов, начиная с 3.+ версии, базовым и единственным шаблонизатором остался handebars. Однако, был разработал API для добавления пользовательских типов файлов! Для того, чтобы добавить пользовательский тип файлов, необходимо зарегистрировать его в конфигурации проекта:
"html": {
"beautify": {},
"minifier": {},
...
"customTypeHandlers": {
"mustache": {
"transformer": "./mustache/transformer",
"includeHandler": "./mustache/includeHandler",
"dev": false
}
},
...
Для регистрации пользовательского типа файла необходимо:
- использовать customTypeHandlers параметр в конфигурации проекта в секции html плагина
- в роли ключа данного объекта указать новый тип расширения файла
- зарегистрировать асинхронный обработчик (transformer) для трансформации содержимого файла при каждом его изменении
- зарегистрировать обработчик (includeHandler), который используется при включении include инструментом данного типа файла
# transformer
- Arguments
- content - содержимое файла которое нужно обработать и вернуть!
- attrs - параметры файла
Функция трансформер, может быть асинхронной, должна возвращать обработанный входной content параметр. Данная функция будет вызываться каждый раз, когда содержимое файла будет изменено.
module.exports = async function(content, attrs) {
return content
}
# includeHandler
- Arguments
- content - содержимое файла которое нужно обработать и вернуть!
- attrs - все возможные данные включая входные параметры
- compile - handlebars.compile метод
Синхронная функция, цель которой возвращать обработанный входной content параметр. Данная функция вызывается при каждом включении файлов зарегистрированного типа, имеет входные данные которые передаются include инструментом. С помощью третьего параметра можно сгенерировать шаблон посредством handlebars шаблонизатора:
module.exports = function(content, attrs, compile) {
return compile(content)(attrs);
}
Пример с Mustache:
// ./mustache/includeHandler
const Mustache = require('mustache');
module.exports = function(content, attrs, compile) {
return Mustache.render(content, attrs);
}