Не так давно я написал статью, в которой рассматривался один из возможных вариантов организации кода для 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?