sudakov.spb.ru

Бортовой журнал жизни (ту-152)

04 апр. 2025

Организация сайта по тегам

Как я настроил теги и улучшил структуру постов на своем сайте

Недавно я решил улучшить структуру своего блога на Hugo, чтобы теги были более автоматизированными и удобными для навигации. Моя цель была такая: каждую папку в content/posts/ можно было бы воспринимать как тег, и все посты внутри этой папки автоматически получали бы соответствующий тег. Также я хотел, чтобы URL постов оставались в привычном формате год/месяц/название, а страница с тегами показывала бы все посты, связанные с определенным тегом.

Вот как я это сделал.

1. Структура контента

Ранее все мои посты находились в папке content/posts/, но теперь я начал разделять их по папкам в зависимости от тегов. Например:

content/posts/tech/linux-setup.md
content/posts/life/daily-thoughts.md

Теперь каждый пост в папке tech/ будет автоматически ассоциироваться с тегом tech, а пост в папке life/ — с тегом life.

2. Изменения в config.toml

Чтобы сохранить формат URL для постов в виде год/месяц/название, я добавил или проверил в config.toml следующую настройку:

[permalinks]
  posts = "/:year/:month/:title"

Это позволяет сохранить текущую структуру ссылок, как у меня было раньше:

https://sudakov.spb.ru/2025/04/linux-setup/

При этом мне не нужно переживать, что изменения в структуре папок как-то повлияют на адреса уже существующих постов.

3. Добавление тегов на страницы постов

Теперь, чтобы автоматизировать процесс добавления тегов на страницы постов, я добавил в файл single.html следующий код:

{{/* Определяем тег по названию родительской папки */}}
{{ $sections := split .File.Dir "/" }}
{{ $tag := index $sections (sub (len $sections) 2) }}

{{/* Проверяем, что тег не "posts", иначе не показываем */}}
{{ if ne $tag "posts" }}
    <div class="post-tags">
        <strong>Тег:</strong> <a href="{{ "/tags/" | relURL }}{{ $tag | urlize }}">{{ $tag }}</a>
    </div>
{{ end }}

Этот код:

  • Берёт путь к текущему файлу.
  • Извлекает имя родительской папки, которое и является тегом (например, tech или life).
  • Добавляет ссылку на страницу тега (например, /tags/tech/).

Это позволяет автоматически привязать тег к каждому посту, просто распределяя их по папкам.

4. Страница тегов

Чтобы страница с тегами выводила все доступные теги и соответствующие им посты, я подправил шаблон terms.html. Вместо стандартного отображения тегов, я теперь читаю папки внутри content/posts/ и вывожу их как теги:

{{ $tags := readDir "content/posts" }}
<div class="tag-cloud">
    {{ range $tags }}
        {{ if .IsDir }}
            <a href="{{ "/tags/" | relURL }}{{ .Name | urlize }}" class="tag-item">
                {{ .Name }}
            </a>
        {{ end }}
    {{ end }}
</div>

Этот код позволяет Hugo автоматически обрабатывать папки в content/posts/ как теги и генерировать для каждого тега страницу.

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

Итоговые изменения

Теперь вся структура сайта стала более логичной и автоматизированной. Каждая папка внутри content/posts/ — это по сути тег, а каждый пост автоматически получает ссылку на этот тег, если он находится внутри соответствующей папки.

  1. Структура URL для постов остаётся прежней: /год/месяц/название/.
  2. Теги теперь добавляются автоматически через структуру папок.
  3. Страница тегов отображает все доступные теги, и по клику на тег показываются все соответствующие посты.

Эти изменения сделали сайт более организованным и удобным как для меня, так и для пользователей.

А ты знал: "Никто не понимает рекурсию, пока не понимает рекурсию."