Добавил статью "Как автоматизировать создание постов в Hugo: slugs, архетипы и бандлы"

This commit is contained in:
2026-04-18 09:57:02 +03:00
parent 8d44c23a35
commit 28b724d985
2 changed files with 195 additions and 1 deletions
+15
View File
@@ -1,6 +1,21 @@
---
date = '{{ .Date }}'
lastmod = '{{ .Date }}'
draft = true
title = '{{ replace .File.ContentBaseName "-" " " | title }}'
slug = '{{ .File.ContentBaseName }}'
description = ''
categories = [
'uncategorized',
]
tags = [
'draft',
]
keywords = [
'hugo',
'blog'
]
---
@@ -0,0 +1,179 @@
---
date = '2026-04-18T09:44:39+03:00'
lastmod = '2026-04-18T09:44:39+03:00'
draft = true
title = 'Как автоматизировать создание постов в Hugo: slugs, архетипы и бандлы'
slug = 'hugo-slugs-archetypes-bundles'
description = 'Настраиваем Hugo так, чтобы не копировать index.md вручную, не мучиться с транслитерацией и получать красивые URL с датами'
categories = [
'Hugo',
'DevOps'
]
tags = [
'hugo',
'static-site-generator',
'automation',
'frontmatter'
]
keywords = [
'hugo',
'blog'
]
---
## Проблема: рутина при создании постов
Когда я только начинал вести блог на Hugo, каждый новый пост создавался через боль и страдания:
1. Создать папку вручную `content/posts/название-поста/`
2. Скопировать туда `index.md` из соседней папки
3. Отредактировать front matter (дату, заголовок, теги)
4. Придумать slug для красивого URL
5. ...и не забыть, что папку лучше назвать на латинице
На всё это уходило пара минут чисто механической работы. А когда постов 10–20, это начинает реально бесить.
В этой статье я расскажу, как я решил эту проблему с помощью штатных возможностей Hugo: **архетипов (archetypes)**, **пермалинков (permalinks)** и правильной организации **бандлов (bundles)**.
## Что такое бандл и зачем папка для каждого поста
Hugo поддерживает два типа контента:
- **Leaf bundle** — папка с файлом `index.md`. Внутрь можно складывать изображения, файлы, другие ресурсы. Идеально для блога.
- **Branch bundle** — папка с `_index.md`. Используется для секций-списков (например, `/posts/`).
Структура моего блога:
content/
├── posts/
│ ├── hugo-slugs-archetypes-bundles/
│ │ ├── index.md
│ │ ├── images/
│ │ │ └── diagram.png
│ │ └── code-example.txt
│ └── другой-пост/
│ └── index.md
Плюсы такого подхода:
- Все файлы поста в одном месте
- Можно удобно ссылаться на изображения: `![схема](images/diagram.png)`
- Не нужно придумывать уникальные имена для картинок глобально
## Почему папку бандла нужно называть на латинице
Здесь кроется важный момент. Hugo позволяет использовать любые символы в именах папок, включая кириллицу. Но есть **две причины использовать латиницу**:
1. **Чистые URL.** Если папка называется `мой-пост`, то URL будет `/%D0%BC%D0%BE%D0%B9-%D0%BF%D0%BE%D1%81%D1%82/`. Браузер это поймёт, но выглядит ужасно.
2. **Slug без транслитерации.** Имя папки удобно использовать как `slug` — последний сегмент URL. А латиница в URL — это стандарт и хороший тон.
**Правило:** папку называем на латинице (например, `my-awesome-post`), а заголовок внутри пишем по-русски.
## Как автоматизировать создание бандла через консоль
Команда для создания бандла с одной папкой:
```bash
hugo new content posts/название-папки/index.md
```
Hugo сам создаст папку, сгенерирует index.md с front matter из архетипа.
Важно: эта команда появилась в Hugo 0.112. В старых версиях нужно было сначала создать папку, потом файл.
## Настройка архетипа (archetype)
Архетип — это шаблон для новых файлов. Он лежит в archetypes/default.md (или в archetypes/post-bundle.md для конкретного типа).
Мой архетип выглядит так (TOML-формат):
```toml
---
date = '{{ .Date }}'
lastmod = '{{ .Date }}'
draft = true
title = '{{ replace .File.ContentBaseName "-" " " | title }}'
slug = '{{ .File.ContentBaseName }}'
description = ''
author = 'Кразя'
categories = [
'uncategorized'
]
tags = [
'draft'
]
---
```
Разберём ключевые моменты:
Поле Значение
title Берёт имя папки, заменяет дефисы на пробелы и делает заглавные буквы. my-awesome-post → My Awesome Post
slug Просто берёт имя папки как есть: my-awesome-post
.File.ContentBaseName Встроенная переменная Hugo — имя текущей папки без расширения и пути
После создания поста я вручную меняю title на русский и заполняю description, categories, tags.
## Настройка permalinks для красивых URL
Чтобы URL выглядел как 2025/03/my-awesome-post/, а не как posts/my-awesome-post/, добавляем в hugo.toml:
```toml
[permalinks]
posts = "/:year/:month/:slug/"
```
Теперь при сборке сайта Hugo сам построит нужную структуру. При этом внутри content/ всё остаётся по-прежнему — папка в posts/.
## Полный цикл создания поста (без лишних телодвижений)
Вот как теперь выглядит создание нового поста в моём блоге:
```bash
# 1. Создаём бандл с латинским именем папки
hugo new content posts/hugo-best-practices/index.md
# 2. Открываем файл и правим русский заголовок, описание, теги
vim content/posts/hugo-best-practices/index.md
# 3. Пишем пост в markdown
# 4. Смотрим локально
hugo server -D
# 5. Публикуем
make deploy
```
## Что ещё можно добавить в front matter
В процессе настройки я выяснил, что Hugo поддерживает много полезных полей:
|Поле |Назначение|
|publishDate |Отложенная публикация (не рендерится до указанной даты)|
|expiryDate |Автоматическое снятие с публикации|
|lastmod |Дата последнего изменения (для SEO)|
|aliases |Редиректы со старых URL|
|weight |Ручная сортировка в списке (меньше — выше)|
|images |Изображение для Open Graph и Twitter Cards|
|params |Кастомные параметры для темы|
## Итог
После всех настроек создание нового поста занимает ровно столько времени, сколько нужно на написание контента. Никакой ручной возни с папками и копированием index.md.
Ключевые выводы:
- Используйте leaf bundles (папка + index.md) для хранения всех ресурсов поста в одном месте
- Папки называйте на латинице — это даст чистые URL и автоматический slug
- Настройте архетип с переменной {{ .File.ContentBaseName }} для автоматической генерации title и slug
- Добавьте [permalinks] в конфиг для красивых URL с датами
Создавайте новый пост одной командой: ```bash hugo new content posts/имя-папки/index.md```
Теперь можно сосредоточиться на том, ради чего всё затевалось — на содержании.
Если у тебя есть свои лайфхаки по Hugo или ты знаешь, как сделать транслитерацию slug прямо из заголовка — пишите мне в Telegram https://t.me/kpa39l. Обсудим.