Сравнение нюансов тем для двух основных генераторов статических сайтов JAMstack
Недавно я взял на себя задачу создать тему сайта документации для двух проектов. Оба проекта нуждались в одинаковых базовых функциях, но в одном используется Jekyll, а в другом - Hugo.
С точки зрения типичного разработчика, очевидно, был только один вариант. Я решил создать одну и ту же тему в обоих фреймворках и дать вам, дорогой читатель, параллельное сравнение.
Этот пост не является исчерпывающим руководством по созданию темы, а предназначен для ознакомления вас с процессом создания темы в любом из генераторов. Вот что мы расскажем:
1. How theme files are organized 2. Create a stylesheet 3. Sass and CSS in Jekyll 4. Sass and Hugo Pipes in Hugo 5. Configure and deploy to GitHub Pages 6. Configure Jekyll 7. Deploy to GitHub Pages
Вот дерьмовый каркас темы, которую я собираюсь создать.
Если вы планируете развивать тему, возможно, будет полезно обслуживать тему локально по мере ее создания; оба генератора предлагают эту функцию. Для Джекилла запустите jekyll serve
, а для Хьюго запустите hugo serve
.
Есть два основных элемента: основная область содержимого и важнейшее меню боковой панели. Для их создания вам потребуются файлы шаблонов, которые сообщают генератору сайта, как создавать HTML-страницу. Чтобы организовать файлы шаблонов тем разумным образом, вам сначала нужно знать, какую структуру каталогов ожидает генератор сайта.
Как организованы файлы тем
Jekyll поддерживает темы на основе гемов, которые пользователи могут устанавливать, как и любые другие драгоценные камни Ruby. Этот метод скрывает файлы тем в геме, поэтому для целей этого сравнения мы не используем темы на основе гемов.
Когда вы запустите jekyll new-theme <name>
, Jekyll создаст для вас новую тему. Вот как выглядят эти файлы:
.
├── assets
├── Gemfile
├── _includes
├── _layouts
│ ├── default.html
│ ├── page.html
│ └── post.html
├── LICENSE.txt
├── README.md
├── _sass
└── <name>.gemspec
Имена каталогов достаточно информативны. Каталог _includes
предназначен для небольших фрагментов кода, которые вы повторно используете в разных местах, почти так же, как вы смазываете все маслом. (Только я?) Каталог _layouts
содержит шаблоны для разных типов страниц вашего сайта. Папка _sass
предназначена для файлов Sass, используемых для создания таблицы стилей вашего сайта.
Вы можете создать новую тему Hugo, запустив hugo new theme <name>
. В нем есть эти файлы:
.
├── archetypes
│ └── default.md
├── layouts
│ ├── 404.html
│ ├── _default
│ │ ├── baseof.html
│ │ ├── list.html
│ │ └── single.html
│ ├── index.html
│ └── partials
│ ├── footer.html
│ ├── header.html
│ └── head.html
├── LICENSE
├── static
│ ├── css
│ └── js
└── theme.toml
Вы можете увидеть некоторое сходство. Файлы шаблонов страниц Хьюго заправлены в layouts/
. Обратите внимание, что у типа страницы _default
есть файлы для list.html
и single.html
. В отличие от Jekyll, Hugo использует эти конкретные имена файлов, чтобы различать страницы со списком (например, страницу со ссылками на все ваши сообщения в блоге) и отдельные страницы (например, одну из ваших сообщений в блоге). Каталог layouts/partials/
содержит многоразовые биты, а для файлов таблиц стилей выделено место в static/css/
.
Эти структуры каталогов не высечены в камне, поскольку оба генератора сайтов допускают некоторую настройку. Например, Jekyll позволяет вам определять коллекции, а Hugo использует пакеты страниц. Эти функции позволяют вам организовать ваш контент несколькими способами, но пока давайте посмотрим, где разместить несколько простых страниц.
Куда размещать контент
Чтобы создать меню сайта, которое выглядит так:
Introduction
Getting Started
Configuration
Deploying
Advanced Usage
All Configuration Settings
Customizing
Help and Support
Вам понадобятся два раздела («Введение» и «Расширенное использование»), содержащие соответствующие подразделы.
Jekyll не строго придерживается местоположения своего контента. Он ожидает страниц в корне вашего сайта и будет строить все, что там есть. Вот как вы можете организовать эти страницы в корне вашего сайта Jekyll:
.
├── 404.html
├── assets
├── Gemfile
├── _includes
├── index.markdown
├── intro
│ ├── config.md
│ ├── deploy.md
│ ├── index.md
│ └── quickstart.md
├── _layouts
│ ├── default.html
│ ├── page.html
│ └── post.html
├── LICENSE.txt
├── README.md
├── _sass
├── <name>.gemspec
└── usage
├── customizing.md
├── index.md
├── settings.md
└── support.md
Вы можете изменить расположение источника сайта в своей Конфигурации Jekyll.
В Hugo весь отображаемый контент ожидается в папке content/
. Это предотвращает попытки Hugo отображать нежелательные страницы, например 404.html
, в качестве содержания сайта. Вот как можно организовать свой content/
каталог в Hugo:
.
├── _index.md
├── intro
│ ├── config.md
│ ├── deploy.md
│ ├── _index.md
│ └── quickstart.md
└── usage
├── customizing.md
├── _index.md
├── settings.md
└── support.md
Для Хьюго _index.md
и index.md
означают разные вещи. Может быть полезно знать, какой тип пакета страниц вы хотите использовать для каждого раздела: лист, без дочерних элементов или ветвь.
Теперь, когда у вас есть представление о том, где разместить вещи, давайте посмотрим, как создать шаблон страницы.
Как работает шаблонизатор
Шаблоны страниц Jekyll созданы с использованием языка шаблонов Liquid. Он использует фигурные скобки для вывода переменного содержания на страницу, например заголовка страницы: {{ page.title }}
.
В шаблонах Хьюго также используются фигурные скобки, но они созданы с помощью Go Templates. Синтаксис похож, но отличается: {{ .Title }}
.
И шаблоны Liquid, и Go могут обрабатывать логику. Liquid использует синтаксис тегов для обозначения логических операций:
{% if user %}
Hello {{ user.name }}!
{% endif %}
И Go Templates помещает свои функции и аргументы в синтаксис фигурных скобок:
Hello !
Языки шаблонов позволяют вам создать одну скелетную HTML-страницу, а затем указать генератору сайта разместить переменное содержимое в определенных вами областях. Давайте сравним два возможных default
шаблона страниц для Джекилла и Хьюго.
Тема каркаса Jekyll default
пуста, поэтому мы рассмотрим их стартовую тему Minima. Вот _layouts/default.html
в Jekyll (Liquid):
<!DOCTYPE html>
<html lang="{{ page.lang | default: site.lang | default: "en" }}">
{%- include head.html -%}
<body>
{%- include header.html -%}
<main class="page-content" aria-label="Content">
<div class="wrapper">
{{ content }}
</div>
</main>
{%- include footer.html -%}
</body>
</html>
Вот тема оформления Хьюго layouts/_default/baseof.html
(шаблоны Go):
<!DOCTYPE html>
<html>
<body>
<div id="content">
{{- block "main" . }}{{- end }}
</div>
</body>
</html>
Другой синтаксис, та же идея. Оба шаблона содержат многоразовые биты для head.html
, header.html
и footer.html
. Они появляются на многих страницах, поэтому есть смысл не повторяться. В обоих шаблонах также есть место для основного контента, хотя в шаблоне Jekyll используется переменная ({{ content }}
), а в Hugo - блок ({{- block "main" . }}{{- end }}
). Блоки - это еще один способ, которым Hugo позволяет определять повторно используемые биты.
Теперь, когда вы знаете, как работает шаблон, вы можете создать меню боковой панели для темы.
Создание меню верхнего уровня с помощью объекта Pages
Вы можете программно создать меню верхнего уровня из своих страниц. Это будет выглядеть так:
Introduction
Advanced Usage
Начнем с Джекила. Вы можете отображать ссылки на страницы сайта в своем шаблоне Liquid, перебирая объект site.pages
, который предоставляет Jekyll, и создавая список:
<ul>
{% for page in site.pages %}
<li><a href="{{ page.url | absolute_url }}">{{ page.title }}</a></li>
{% endfor %}
</ul>
Это вернет все страницы сайта, включая все те, которые вам могут не понадобиться, например 404.html
. Вы можете фильтровать страницы, которые вам действительно нужны, с помощью еще пары тегов, например, условно включая страницы, если для них установлен параметр section: true
:
<ul>
{% for page in site.pages %}
{%- if page.section -%}
<li><a href="{{ page.url | absolute_url }}">{{ page.title }}</a></li>
{%- endif -%}
{% endfor %}
</ul>
Вы можете добиться того же эффекта с немного меньшим количеством кода в Hugo. Прокрутите объект .Pages
Хьюго, используя действие range
в Go Template:
<ul>
{{ range .Pages }}
<li>
<a href=""></a>
</li>
{{ end }}
</ul>
Этот шаблон использует объект .Pages
для возврата всех страниц верхнего уровня в каталоге content/
вашего сайта Hugo. Поскольку Hugo использует определенную папку для контента сайта, который вы хотите отобразить, дополнительная фильтрация не требуется для создания простого меню страниц сайта.
Создание меню с вложенными ссылками из списка данных
Оба генератора сайтов могут использовать отдельно определенный список данных со ссылками для отображения меню в вашем шаблоне. Это больше подходит для создания вложенных ссылок, например:
Introduction
Getting Started
Configuration
Deploying
Advanced Usage
All Configuration Settings
Customizing
Help and Support
Jekyll поддерживает файлы данных в нескольких форматах, включая YAML. Вот определение меню выше в _data/menu.yml
:
section:
- page: Introduction
url: /intro
subsection:
- page: Getting Started
url: /intro/quickstart
- page: Configuration
url: /intro/config
- page: Deploying
url: /intro/deploy
- page: Advanced Usage
url: /usage
subsection:
- page: Customizing
url: /usage/customizing
- page: All Configuration Settings
url: /usage/settings
- page: Help and Support
url: /usage/support
Вот как отобразить данные в шаблоне боковой панели:
{% for a in site.data.menu.section %}
<a href="{{ a.url }}">{{ a.page }}</a>
<ul>
{% for b in a.subsection %}
<li><a href="{{ b.url }}">{{ b.page }}</a></li>
{% endfor %}
</ul>
{% endfor %}
Этот метод позволяет создать собственное меню с двумя уровнями вложенности. Уровни вложенности ограничены for
циклами в шаблоне. Для рекурсивной версии, которая обрабатывает дополнительные уровни вложенности, см. Навигация по вложенному дереву с рекурсией.
Hugo делает нечто подобное со своими шаблонами меню. Вы можете определить ссылки меню в своей конфигурации сайта Hugo и даже добавить полезные свойства, которые понимает Hugo, например, взвешивание. Вот определение меню выше в config.yaml
:
sectionPagesMenu: main
menu:
main:
- identifier: intro
name: Introduction
url: /intro/
weight: 1
- name: Getting Started
parent: intro
url: /intro/quickstart/
weight: 1
- name: Configuration
parent: intro
url: /intro/config/
weight: 2
- name: Deploying
parent: intro
url: /intro/deploy/
weight: 3
- identifier: usage
name: Advanced Usage
url: /usage/
- name: Customizing
parent: usage
url: /usage/customizing/
weight: 2
- name: All Configuration Settings
parent: usage
url: /usage/settings/
weight: 1
- name: Help and Support
parent: usage
url: /usage/support/
weight: 3
Хьюго использует identifier
, которое должно соответствовать имени раздела, вместе с переменной parent
для обработки вложенности. Вот как отобразить меню в шаблоне боковой панели:
<ul>
{{ range .Site.Menus.main }}
{{ if .HasChildren }}
<li>
<a href="{{ .URL }}">{{ .Name }}</a>
</li>
<ul class="sub-menu">
{{ range .Children }}
<li>
<a href="{{ .URL }}">{{ .Name }}</a>
</li>
{{ end }}
</ul>
{{ else }}
<li>
<a href="{{ .URL }}">{{ .Name }}</a>
</li>
{{ end }}
{{ end }}
</ul>
Функция range
выполняет итерацию по данным меню, а переменная Хьюго .Children
обрабатывает вложенные страницы за вас.
Собираем шаблон вместе
С вашим меню в многоразовом бите боковой панели (_includes/sidebar.html
для Jekyll и partials/sidebar.html
для Hugo) вы можете добавить его в шаблон default.html
.
В Джекилле:
<!DOCTYPE html>
<html lang="{{ page.lang | default: site.lang | default: "en" }}">
{%- include head.html -%}
<body>
{%- include sidebar.html -%}
{%- include header.html -%}
<div id="content" class="page-content" aria-label="Content">
{{ content }}
</div>
{%- include footer.html -%}
</body>
</html>
В Хьюго:
<!DOCTYPE html>
<html>
<body>
<div id="content" class="page-content" aria-label="Content">
{{- block "main" . }}{{- end }}
</div>
</body>
</html>
Когда сайт будет создан, каждая страница будет содержать весь код из вашего sidebar.html
.
Создать таблицу стилей
Оба генератора сайтов принимают Sass для создания таблиц стилей CSS. Джекил имеет встроенную обработку Sass, а Хьюго использует Hugo Pipes. У обоих вариантов есть свои особенности.
Sass и CSS в Jekyll
Чтобы обработать файл Sass в Jekyll, создайте свои определения стилей в каталоге _sass
- например, в файле по адресу _sass/style-definitions.scss
:
$background-color: #eef !default;
$text-color: #111 !default;
body {
background-color: $background-color;
color: $text-color;
}
Jekyll не будет создавать этот файл напрямую, так как он обрабатывает файлы только с предварительной записью. Чтобы создать конечный путь к файлу для таблицы стилей вашего сайта, используйте заполнитель с пустым титульным листом там, где вы хотите разместить .css
файл, например assets/css/style.scss
. В этом файле просто импортируйте свои стили:
---
---
@import "style-definitions";
У этой довольно хакерской конфигурации есть положительный момент: вы можете использовать теги и переменные шаблона Liquid в своем файле-заполнителе. Это хороший способ разрешить пользователям устанавливать переменные, например, с сайта _config.yml
.
Полученная таблица стилей CSS на вашем сгенерированном сайте имеет путь /assets/css/style.css
. Вы можете разместить ссылку на него в head.html
своего сайта, используя:
<link rel="stylesheet" href="{{ "/assets/css/style.css" | relative_url }}" media="screen">
Сасс и Хьюго Пайпс в Хьюго
Hugo использует Hugo Pipes для преобразования Sass в CSS. Вы можете добиться этого, используя функцию обработки ресурсов Хьюго, resources.ToCSS
, которая ожидает источник в каталоге assets/
. В качестве аргумента он принимает файл SCSS. Используя определения ваших стилей в файле Sass по адресу assets/sass/style.scss
, вот как получить, обработать и связать ваш Sass в head.html
вашей темы:
{{ $style := resources.Get "/sass/style.scss" | resources.ToCSS }}
<link rel="stylesheet" href="{{ $style.RelPermalink }}" media="screen">
Обработка активов Hugo требует расширенного Hugo, которого у вас может не быть по умолчанию. Вы можете получить расширенный Hugo на странице релизов.
Настроить и развернуть на страницах GitHub
Прежде чем ваш генератор сайтов сможет построить ваш сайт, ему нужен файл конфигурации для установки некоторых необходимых параметров. Файлы конфигурации находятся в корневом каталоге сайта. Среди других настроек вы можете объявить имя темы, которая будет использоваться при создании сайта.
Настроить Jekyll
Вот минимальный _config.yml
для Джекилла:
title: Your awesome title
description: >- # this means to ignore newlines until "baseurl:"
Write an awesome description for your new site here. You can edit this
line in _config.yml. It will appear in your document head meta (for
Google search results) and in your feed.xml site description.
baseurl: "" # the subpath of your site, e.g. /blog
url: "" # the base hostname & protocol for your site, e.g. http://example.com
theme: # for gem-based themes
remote_theme: # for themes hosted on GitHub, when used with GitHub Pages
С remote_theme
любая тема Jekyll, размещенная на GitHub, может использоваться с сайтами, размещенными на страницах GitHub.
Jekyll имеет конфигурацию по умолчанию, поэтому любые параметры, добавленные в ваш файл конфигурации, переопределяют значения по умолчанию. Вот дополнительные настройки конфигурации.
Настроить Hugo
Вот минимальный пример config.yml
Хьюго:
baseURL: https://example.com/ # The full domain your site will live at
languageCode: en-us
title: Hugo Docs Site
theme: # theme name
Хьюго не делает никаких предположений, поэтому, если необходимый параметр отсутствует, вы увидите предупреждение при создании или обслуживании своего сайта. Вот все настройки конфигурации для Hugo.
Развернуть на страницах GitHub
Оба генератора создают ваш сайт с помощью команды.
Для Джекила используйте jekyll build
. Смотрите дополнительные варианты сборки здесь.
Для Хьюго используйте hugo
. Вы можете запустить hugo help
или просмотреть дополнительные параметры сборки здесь.
Вам нужно будет выбрать источник для вашего сайта GitHub Pages; после этого ваш сайт будет обновляться каждый раз, когда вы запускаете новую сборку. Конечно, вы также можете автоматизировать сборку GitHub Pages с помощью GitHub Actions. Вот один для сборки и развертывания с Hugo и один для сборки и развертывания Jekyll.
Время для шоу
Все существенные различия между этими двумя генераторами скрыты под капотом; Тем не менее, давайте посмотрим на готовые темы в двух цветовых вариациях.
Хьюго
Джекил
Шикарно!
Подожди, кто победил?
И у Хьюго, и у Джекила есть свои причуды и удобства.
С точки зрения разработчика, Jekyll - подходящий выбор для простых сайтов без сложных организационных требований. Если вы хотите рендерить некоторые одностраничные сообщения в доступной теме и размещать их на GitHub Pages, Jekyll поможет вам быстро приступить к работе.
Лично я использую Hugo. Мне нравятся организационные возможности его Page Bundles, и он поддерживается преданной и добросовестной командой, которая, кажется, действительно стремится облегчить удобство для своих пользователей. Это очевидно во многих функциях и удобных приемах Хьюго, таких как обработка магов и шорткоды. Кажется, они выпускают новые исправления и версии примерно так же часто, как я делаю новую чашку кофе, что, в зависимости от вашего варианта использования, может быть фантастическим или раздражающим.
Если вы все еще не можете решить, не волнуйтесь. Созданная мной Тема документации OpenGitDocs доступна как для Hugo, так и для Jekyll. Начните с одного, а при желании смените его позже. В этом преимущество выбора.