Не так давно я написал статью, в которой рассматривался один из возможных вариантов организации кода для CSS-препроцессоров. На этот раз мы будем рассматривать вариант организации кода для HTML-препроцессоров.
Введение
Пару лет назад я ушёл с чистого CSS на CSS-препроцессоры, немногим позже то же самое случилось и с HTML — привет, HTML-препроцессоры. Как и в случае первых, вторые также привносят в HTML новые возможности, например, тот же include
(аналог import
в CSS). И, как говорится, понеслась — нужна структура, которая позволит разделять HTML-страницы на несколько частей, чтобы облегчить восприятие кода и попытаться структурировать его. Теперь давайте посмотрим на то, что у меня получилось.
Структура
Посмотрите на представленную ниже структуру и попытайтесь провести параллель с той структурой, что была представлена в статье про CSS-препроцессоры.
- components/
- _navbar.jade
- data/
- _menu.json
- layouts/
- _default.jade
- mixins/
- _svg.jade
- pages/
- index/_main.jade
- about/_main.jade
- partials/
- _footer.jade
- _head.jade
- _header.jade
- index.jade
- about.jade
Наверное, вы догадались, что речь пойдёт о препроцессоре Jade, который имеет наиболее компактный синтаксис, похожий на Sass или Stylus. Однако, практически любой HTML-препроцессор имеет возможность вкладывать файлы в другие файлы, поэтому от препроцессора здесь ничего не зависит — эта структура может быть успешно применена, например, к Nunjucks.
Директори mixins и data
Начнём с директорий mixins и data, так как они наиболее просты для восприятия.
В директории mixins хранятся все примеси проекта, которые могут быть использованы в любом из jade-файлов.
Директория data содержит в себе какие-либо данные, необходимые в верстаемых страницах. При сборке шаблонов все файлы из этой директории конкатенируются, парсятся и пробрасываются в HTML-препроцессор, где по необходимости используются. Например, я помещаю в эту директорию файл _menu.json
, в котором хранятся пункты в формате name:href
для всех меню макета. Также, сюда можно положить файл _global.json
, в котором описать номера телефонов, основные заголовки, имена руководства, какие-либо текстовые материалы (возможности приложения, отзывы) и прочие данные, что могут поменяться во время разработки и поддержки сайта.
Ниже представлен фрагмент файла _menu.json
, содержащего пункты главного меню:
{
"navbar": {
"Home": "/",
"About": "/about.html"
}
}
А вот так эти данные могут быть использованы в любом jade-файле, например, _navbar.jade
:
nav.navbar-list
each href, item in _menu.navbar
a(href="#{href}", title="#{item}")= item
Директория layouts и файлы в корне
Файлы в корне директории шаблонов представляют собой точки входа всех страниц. Компилятор обращает внимание только эти файлы. Каждая страница расширяет какой-либо макет (изначально _default.jade
) и содержит следующее описание страницы:
- Язык
- Уникальное имя страницы, используемое в классе элемента
<body>
- Заголовок
- Название приложения для устройств Apple, отображаемое при создании ярлыка для сайта на рабочем столе
- Описание страницы
Ниже приведён пример точки входа для главной страницы сайта index.jade
:
extends layouts/_default
block vars
-
page = {
language: 'ru',
name: 'home',
title: 'Yellfy',
appTitle: 'Yellfy',
description: 'Your great description of page'
}
block header
include partials/_header
block main
include pages/index/_main
block footer
include partials/_footer
Соотвественно, макет, который расширяется главной страницей сайта, имеет вид:
doctype html
//- Global variables
block vars
//- Template
html(lang="#{page.language}")
head
include ../partials/_head
body(class="page-" + page.name)
block header
block main
block footer
Для себя я постарался максимально упростить макет, который расширяется страницами по умолчанию, чтобы лишний раз не создавать дополнительные макеты. Если же каждая страница имеет какую-то общую структуру, то наиболее правильным вариантом будет желание вынести все повторяющиеся элементы в макет и поместить его в директорию layouts.
Директория partials и pages
В директории partials содержатся файлы частей шаблона: шапки и подвала. Если каждая страница имеет одинаковую шапку и подвал, то скорее всего хорошо было бы поместить весь код этих частей именно в эти файлы.
Кроме шапки и подвала в директории partials имеется файл _head.jade
, в котором хранятся все мета-теги страниц. Именно для него каждая страница имеет описание. Вот те мета-теги, что будут автоматически заполнены на основе описания:
title #{page.title}
meta(name="description", content="#{page.description}")
meta(name="apple-mobile-web-app-title", content="#{page.appTitle}")
Директория pages содержит основную часть каждой страницы, представленную файлом _main.jade
и директорией с именем, совпадающим с именем файла точки входа страницы, собирающим всё содержимое воедино. Директория создаётся с расчётом на то, что основное содержимое страницы может быть составным и разработчику, то есть мне, захочется что-то вынести в отдельные файлы. Например, если страница содержит большое количество текста, то его можно вынести в markdown-файл и подключить в файле _main.jade
.
main.site-main
.area
include:markdown text.md
Директория components
Эта директория полностью совпадает с той, что была описана в статье про организацию кода для CSS-препроцессоров. Каждый компонент состоит из файла стилей и файла разметки. Из этих компонентов будет собираться вся страница.
Примеры компонентов:
- Глобальная навигация
- Dropdown-меню
- Рекламные блоки
- Подсветка кода
- Список статей
- Jumbotron
- Блок социальных кнопок
- Список категорий или тегов
- Стилизация контента статьи
Выводы
Как и в статье про CSS-препроцессоры я попытаюсь выделить плюсы и минусы моей структуры.
Плюсы
- Структура очень похожа на подход, используемый в почти каждой CMS
- Строгое разбиение по предназначению
- Очень просто поддерживать и искать нужные блоки
- Каждый файл обещает быть небольшим по объему
- Благодаря файлам в data можно легко менять содержимое страниц (пункты меню, телефоны, ссылки)
- Можно использовать директорию шаблонов как генератор простейших статистических сайтов (лендингов)
Минусы
- Много директорий и файлов
- Нужно думать: что поместить в partials, pages и components?