Создание статического сайта с помощью компонентов с помощью Nunjucks

Опубликовано: 2022-03-10
Краткое резюме ↬ Даже если вы вообще не используете клиентский JavaScript для создания сайта, это не означает, что вам нужно отказаться от идеи построения с помощью компонентов. Узнайте, как создать статический сайт с помощью препроцессора HTML.

В наши дни это довольно популярно, и, осмелюсь сказать, это чертовски хорошая идея — создавать сайты с компонентами. Вместо того, чтобы создавать целые страницы одну за другой, мы создаем систему компонентов (подумайте: форма поиска, карточка статьи, меню, нижний колонтитул), а затем собираем сайт с этими компонентами.

Фреймворки JavaScript, такие как React и Vue, сильно подчеркивают эту идею. Но даже если вы вообще не используете клиентский JavaScript для создания сайта, это не значит, что вам нужно отказаться от идеи создания с помощью компонентов! Используя препроцессор HTML, мы можем создать статический сайт и при этом получить все преимущества абстрагирования нашего сайта и его содержимого в повторно используемые компоненты.

Статические сайты в наши дни в моде, и это справедливо, поскольку они быстрые, безопасные и недорогие в размещении. Даже Smashing Magazine — статичный сайт, хотите верьте, хотите нет!

Давайте пройдемся по сайту, который я недавно создал с использованием этой техники. Я использовал CodePen Projects для его создания, который предлагает Nunjucks в качестве препроцессора, который идеально подходит для этой работы.

Четырехстраничный сайт с согласованным заголовком, навигацией и нижним колонтитулом

Это микросайт. Ему не нужна полноценная CMS для обработки сотен страниц. Для интерактивности не требуется JavaScript. Но для этого требуется несколько страниц с одинаковым макетом.

Согласованный верхний и нижний колонтитулы
Единый верхний и нижний колонтитулы на всех страницах
Еще после прыжка! Продолжить чтение ниже ↓

Один HTML не имеет хорошего решения для этого. Нам нужен импорт . Такие языки, как PHP, делают это простым с помощью таких вещей, как <?php include "header.php"; ?> <?php include "header.php"; ?> , но хосты статических файлов не запускают PHP (намеренно), и один только HTML не поможет. К счастью, мы можем выполнить предварительную обработку включений с помощью Nunjucks.

Импорт компонентов на страницы
Импорт компонентов возможен на таких языках, как PHP.

Здесь имеет смысл создать макет , включая фрагменты HTML, представляющие заголовок, навигацию и нижний колонтитул. Шаблоны Nunjucks имеют концепцию блоков, которые позволяют нам размещать контент в этом месте, когда мы используем макет.

 <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>The Power of Serverless</title> <link rel="stylesheet" href="/styles/style.processed.css"> </head> <body> {% include "./template-parts/_header.njk" %} {% include "./template-parts/_nav.njk" %} {% block content %} {% endblock %} {% include "./template-parts/_footer.njk" %} </body>

Обратите внимание, что включаемые файлы имеют имена вроде _file.njk . Это не совсем необходимо. Это может быть header.html или icons.svg , но они названы так, потому что 1) файлы, начинающиеся с подчеркивания, являются чем-то вроде стандартного способа сказать, что они являются частичными. В проектах CodePen это означает, что они не будут пытаться компилироваться в одиночку. 2) Назвав его .njk , мы могли бы использовать больше вещей Nunjucks, если захотим.

Ни в одном из этих кусочков нет ничего особенного. Это всего лишь небольшие фрагменты HTML, предназначенные для использования на каждой из наших четырех страниц.

 <footer> <p>Just a no-surprises footer, people. Nothing to see here.<p> </footer>

Сделав таким образом, мы можем внести одно изменение, и оно будет отражено на всех четырех страницах.

Использование макета для четырех страниц

Теперь каждая из наших четырех страниц может быть файлом. Давайте начнем с index.njk , который в проектах CodePen будет автоматически обрабатываться и создавать файл index.html при каждом сохранении.

Файл index.njk
Начиная с файла index.njk

Вот что мы могли бы поместить в index.njk , чтобы использовать макет и поместить некоторый контент в этот блок:

 {% extends "_layout.njk" %} {% block content %} <h1>Hello, World!</h1> {% endblock %}

Это купит нам полнофункциональную домашнюю страницу! Хороший! Каждая из четырех страниц может делать одно и то же, но размещать в блоке разный контент, и у нас есть небольшой четырехстраничный сайт, которым легко управлять.

Скомпилированный index.html
Файл index.njk компилируется в index.html.

Для справки, я не уверен, что назвал бы эти маленькие фрагменты повторно используемыми компонентами . Мы просто действуем эффективно и разбиваем макет на куски. Я думаю о компоненте больше как о повторно используемом куске, который принимает данные и выводит уникальную версию себя с этими данными. Мы доберемся до этого.

Создание активной навигации

Теперь, когда мы повторили идентичный фрагмент HTML на четырех страницах, можно ли применить уникальный CSS к отдельным элементам навигации, чтобы идентифицировать текущую страницу? Мы могли бы с помощью JavaScript и просмотра window.location и тому подобного, но мы можем сделать это и без JavaScript. Хитрость заключается в том, чтобы поместить class в <body> , уникальный для каждой страницы, и использовать его в CSS.

В нашем _layout.njk тело выводит имя класса в виде переменной:

 <body class="{{ body_class }}">

Затем, прежде чем мы вызовем этот макет на отдельной странице, мы устанавливаем эту переменную:

 {% set body_class = "home" %} {% extends "_layout.njk" %}

Допустим, наша навигация была структурирована как

 <nav class="site-nav"> <ul> <li class="nav-home"> <a href="/"> Home </a> ...

Теперь мы можем настроить таргетинг на эту ссылку и при необходимости применить особый стиль, выполнив следующие действия:

 body.home .nav-home a, body.services .nav-services a { /* continue matching classes for all pages... */ /* unique active state styling */ } 
Стиль активного состояния в навигации
Стилизация навигационных ссылок с активным классом.

О, а эти значки? Это просто отдельные файлы .svg , которые я поместил в папку и включил, например

 {% include "../icons/cloud.svg" %}

И это позволяет мне стилизовать их так:

 svg { fill: white; }

Предполагая, что элементы SVG внутри уже не имеют атрибутов fill .

Создание контента в Markdown

На главной странице моего микросайта содержится большой объем контента. Я, конечно, мог бы написать и поддерживать это в самом HTML, но иногда приятно оставить такие вещи для Markdown. Markdown кажется более чистым для написания и, возможно, немного легче смотреть на него, когда много копий.

Это очень просто в проектах CodePen. Я создал файл с .md , который автоматически преобразуется в HTML, а затем включил его в файл index.njk .

Markdown, скомпилированный в HTML в проектах CodePen
Файлы в уценке компилируются в HTML в проектах CodePen.
 {% block content %} <main class="centered-text-column"> {% include "content/about.html" %} </main> {% endblock %}

Создание реальных компонентов

Будем считать компоненты повторяемыми модулями, которые при передаче данных создают себя. В таких средах, как Vue, вы будете работать с отдельными файловыми компонентами, которые представляют собой изолированные фрагменты шаблонного HTML, ограниченного CSS и специфичного для компонентов JavaScript. Это очень круто, но нашему микросайту не нужно ничего особенного.

Нам нужно создать несколько «карточек» на основе простого шаблона, чтобы мы могли создавать такие вещи:

Компоненты карточного стиля
Создание повторяющихся компонентов с помощью шаблонов

Создание воспроизводимого компонента, такого как в Nunjucks, требует использования того, что они называют макросами. Макросы восхитительно просты. Они похожи на то, как если бы у HTML были функции !

 {% macro card(title, content) %} <div class="card"> <h2>{{ title }}</h2> <p>{{ content }}</p> </div> {% endmacro %}

Затем вы вызываете его по мере необходимости:

 {{ card('My Module', 'Lorem ipsum whatever.') }}

Вся идея здесь в том, чтобы разделить данные и разметку . Это дает нам довольно четкие и ощутимые преимущества:

  1. Если нам нужно внести изменения в HTML, мы можем изменить их в макросе, и они будут изменены везде, где используется этот макрос.
  2. Данные не запутаны в разметке
  3. Данные могут поступать откуда угодно! Мы кодируем данные прямо в вызовы макросов, как мы сделали выше. Или мы могли бы сослаться на некоторые данные JSON и перебрать их в цикле. Я уверен, что вы могли бы даже представить установку, в которой данные JSON поступают из своего рода безголовой CMS, процесса сборки, бессерверной функции, задания cron или чего-то еще.

Теперь у нас есть эти повторяющиеся карты, которые объединяют данные и разметку, как раз то, что нам нужно:

Данные и разметка для компонента хранятся отдельно
HTML управляется в макросе, а данные могут поступать откуда угодно

Сделайте столько компонентов, сколько хотите

Вы можете взять эту идею и работать с ней. Например, представьте, что Bootstrap — это, по сути, набор CSS, в котором вы следуете шаблонам HTML. Вы можете сделать каждый из этих шаблонов макросом и вызывать их по мере необходимости, по существу разбивая структуру на компоненты.

Вы можете вкладывать компоненты, если хотите, придерживаясь своего рода философии атомарного дизайна. Nunjucks также предлагает логику, то есть вы можете создавать условные компоненты и варианты, просто передавая разные данные.

На простом сайте, который я сделал, я сделал другой макрос для раздела идей сайта, потому что он включал немного другие данные и немного другой дизайн карточки.

Составляющие карты в разделе Идеи
Можно создать столько компонентов, сколько вы хотите

Быстрый случай против статических сайтов

Я мог бы возразить, что большинство сайтов выигрывают от компонентной архитектуры, но только некоторые сайты подходят для того, чтобы быть статическими. Я работаю над множеством сайтов, на которых использование внутренних языков уместно и полезно.

На одном из моих сайтов, CSS-Tricks, есть такие вещи, как логин пользователя с довольно сложной системой разрешений: форумы, комментарии, электронная коммерция. Хотя ни одна из этих вещей полностью не останавливает идею статической работы, я часто рад, что у меня есть база данных и внутренние языки для работы. Это помогает мне создавать то, что мне нужно, и держит все под одной крышей.

Идите вперед и примите статичную жизнь!

Помните, что одно из преимуществ построения таким образом, как мы делали в этой статье, заключается в том, что конечным результатом является просто набор статических файлов. Простота размещения, быстрота и безопасность. Тем не менее, нам не пришлось отказываться от работы в удобной для разработчиков форме. Этот сайт будет легко обновлять и добавлять в будущем.

  • Последний проект — это микросайт The Power of Serverless for Front-End Developers (https://thepowerofserverless.info/).
  • Хостинг статических файлов, если вы спросите меня, является частью бессерверного движения.
  • Вы можете увидеть весь код (и даже разветвить копию для себя) прямо на CodePen. Он создается, поддерживается и размещается полностью на CodePen с использованием CodePen Projects.
  • CodePen Projects обрабатывает все материалы Nunjucks, о которых мы говорили здесь, а также такие вещи, как обработка Sass и размещение изображений, которыми я воспользовался для сайта. Вы можете воспроизвести то же самое, скажем, с помощью процесса сборки на основе Gulp или Grunt локально. Вот шаблонный проект, который вы можете раскрутить.