Проблема: рутина при создании постов
Когда я только начинал вести блог на Hugo, каждый новый пост создавался через боль и страдания:
- Создать папку вручную
content/posts/название-поста/ - Скопировать туда
index.mdиз соседней папки - Отредактировать front matter (дату, заголовок, теги)
- Придумать slug для красивого URL
- …и не забыть, что папку лучше назвать на латинице
На всё это уходило пара минут чисто механической работы. А когда постов 10–20, это начинает реально бесить.
В этой статье я расскажу, как я решил эту проблему с помощью штатных возможностей Hugo: архетипов (archetypes), пермалинков (permalinks) и правильной организации бандлов (bundles).
Что такое бандл и зачем папка для каждого поста
Hugo поддерживает три типа контента:
Три способа хранения контента в Hugo
- Простой файл .md (без папки)
Самый простой способ — просто положить файл мой-пост.md в папку content/posts/:
| |
Плюсы:
- Максимально просто, ничего создавать не нужно
- Подходит для простых постов без изображений
Минусы:
- Все изображения нужно класть в общую папку static/images/
- Нельзя прикрепить к посту специфичные файлы (PDF, архивы и т.д.)
- Изображения нужно называть уникально, чтобы не пересекались с другими постами
- Leaf bundle (папка + index.md)
| |
Плюсы:
- Все ресурсы поста в одном месте
- Можно ссылаться на изображения относительно:

- Не нужно думать об уникальности имён файлов
Минусы:
- Нужно создавать папку (но мы это автоматизировали)
- Branch bundle (папка + _index.md)
| |
Плюсы:
- _index.md позволяет задать заголовок, описание для всей секции
- Можно настроить отдельный шаблон для списка постов
Структура моего блога:
| |
Плюсы такого подхода:
- Все посты хранятся одинаково — папка + index.md. Не нужно думать, какой способ выбрать.
- Все файлы поста в одном месте
- Можно удобно ссылаться на изображения:
 - Не нужно придумывать уникальные имена для картинок глобально
- Если я захочу экспортировать пост в другой блог, достаточно скопировать одну папку со всеми ресурсами.
Почему папку бандла нужно называть на латинице
Здесь кроется важный момент. Hugo позволяет использовать любые символы в именах папок, включая кириллицу. Но есть две причины использовать латиницу:
- Чистые URL. Если папка называется
мой-пост, то URL будет/%D0%BC%D0%BE%D0%B9-%D0%BF%D0%BE%D1%81%D1%82/. Браузер это поймёт, но выглядит ужасно. - Slug без транслитерации. Имя папки удобно использовать как
slug— последний сегмент URL. А латиница в URL — это стандарт и хороший тон.
Правило: папку называем на латинице (например, my-awesome-post), а заголовок внутри пишем по-русски.
Как автоматизировать создание бандла через консоль
Команда для создания бандла с одной папкой:
| |
Hugo сам создаст папку, сгенерирует index.md с front matter из архетипа.
Важно: эта команда появилась в Hugo 0.112. В старых версиях нужно было сначала создать папку, потом файл.
Настройка архетипа (archetype)
Архетип — это шаблон для новых файлов. Он лежит в archetypes/default.md (или в archetypes/post-bundle.md для конкретного типа).
Мой архетип выглядит так (TOML-формат):
| |
Разберём ключевые моменты: Поле Значение 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:
| |
Теперь при сборке сайта Hugo сам построит нужную структуру. При этом внутри content/ всё остаётся по-прежнему — папка в posts/.
Полный цикл создания поста (без лишних телодвижений)
Вот как теперь выглядит создание нового поста в моём блоге:
| |
Что ещё можно добавить в 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. Обсудим.