Hugo. Поддержка многоязычности

2026-03-03 · 6 мин. для прочтения
blog computer-science

Hugo. Поддержка многоязычности.

Содержание

1 Общая информация

  • Hugo имеет встроенную мощную поддержку многоязычных сайтов.

2 Базовая настройка многоязычности

  • В Hugo многоязычность настраивается в конфигурационном файле.
  • Определяются языки, их параметры (например, languageCode, weight для порядка, contentDir для переопределения папки контента).
  • По умолчанию Hugo ожидает, что файлы контента для разных языков будут лежать в отдельных подпапках внутри content/, либо иметь специальные метки в именах файлов.

3 Многоязычность при использовании отдельных файлов

  • При подходе с отдельными файлами есть несколько способов организовать переводы.
  • Во всех вариантах изображения и другие файлы, используемые в переводах, обычно размещаются в папке static/.
  • Если для разных языков нужны разные версии одного изображения, придётся создавать отдельные папки внутри static/ (например, static/images/en/photo.jpg и static/images/ru/photo.jpg) и вручную прописывать пути в Markdown.

3.1 Раздельные подпапки для каждого языка

  • Структура:
    content/
      en/
        about.md
        blog/
          first-post.md
      ru/
        about.md
        blog/
          first-post.md
    

3.1.1 Плюсы

  • Чёткое разделение, каждый язык в своей папке.
  • Легко найти все страницы для конкретного языка.

3.1.2 Минусы

  • Нет прямой связи между переводами (Hugo связывает их автоматически по имени файла и пути, если они совпадают).
  • Ресурсы (изображения) всё ещё нужно хранить глобально в static или assets, что может привести к дублированию.

3.2 Один каталог, файлы с суффиксом языка

  • Можно помещать все файлы в общую папку и использовать суффиксы в именах:
    content/
      about.en.md
      about.ru.md
      blog/
        first-post.en.md
        first-post.ru.md
    

3.2.1 Плюсы

  • Компактно, файлы переводов лежат рядом.

3.2.2 Минусы

  • При большом количестве языков каталог может стать захламлённым.
  • Ресурсы (изображения) глобальны.
  • Нет удобного способа хранить локализованные версии картинок рядом с текстом.

4 Многоязычность с page bundles

  • Page bundles позволяют хранить все ресурсы страницы (текст, изображения, PDF) в одной папке, а для разных языков — создавать параллельные папки с локализованными версиями.

4.1 Структура с leaf bundles

  • Допустим, у вас есть страница «О проекте» на двух языках. Вместо двух отдельных файлов вы создаёте две папки:

    content/
      about.en/
        index.en.md      (или просто index.md с указанием языка в front matter)
        photo.jpg        (общая картинка, если подходит для всех языков)
      about.ru/
        index.ru.md      (или index.md с языком в front matter)
        photo.jpg        (отдельная картинка для русской версии)
    
  • Такой подход разъединяет переводы (они в разных папках).

  • Лучший способ — использовать одну общую папку для страницы и внутри неё размещать локализованные файлы с суффиксами:

    content/
      about/                     # папка страницы (bundle)
        index.en.md              # английская версия
        index.ru.md              # русская версия
        photo.jpg                # общее изображение (если одинаково для всех языков)
        diagram-ru.png           # изображение, относящееся только к русской версии
        diagram-en.png           # изображение для английской версии
        brochure.pdf             # общий PDF
    
  • В этом случае:

    • Все ресурсы, общие для языков, лежат на том же уровне, что и файлы index.*.md.
    • Ресурсы, специфичные для языка, также лежат рядом и могут быть использованы только в соответствующей локализованной версии.
    • В шаблонах вы можете обращаться к ресурсам через .Resources и фильтровать их по языку, если задали для них параметр lang в front matter.

4.2 Как Hugo связывает переводы

  • Внутри папки страницы файлы index.en.md и index.ru.md автоматически распознаются как переводы друг друга, потому что они находятся в одной директории и имеют одинаковое базовое имя (до суффикса языка).
  • Hugo создаёт для них страницы на разных языках и связывает их через .Translations.

4.3 Преимущества для многоязычности

  • Локализованные ресурсы.
    • Изображения, документы и другие файлы могут быть разными для разных языков и храниться прямо в папке страницы.
    • Например, для английской версии у вас может быть диаграмма с английскими подписями (diagram-en.png), а для русской — с русскими (diagram-ru.png).
    • Они лежат рядом и легко управляются.
  • Упрощённая структура.
    • Все файлы, относящиеся к одной «логической» странице, находятся в одной папке, даже если у неё много языковых версий.
    • Не нужно разносить по разным корневым папкам (например, content/en/about/ и content/ru/about/).
  • Удобство в шаблонах.
    • Можно использовать .Resources.Get для получения файла, специфичного для языка, или просто обращаться по имени, зная, что оно не конфликтует с другими языками.
    • Например, чтобы вывести изображение для текущего языка, можно сделать {{ $img := .Resources.Get (printf "photo-%s.jpg" .Lang) }}.
  • Поддержка веток (branch bundles)
    • Для разделов (например, раздел блога) используется _index.md.
    • В многоязычном контексте вы можете иметь _index.en.md и _index.ru.md в одной папке раздела, а дочерние страницы организовать как подпапки с переводами внутри.
    • Это позволяет локализовать даже структуру разделов.

4.4 Пример с разделом блога

  • Каждый пост может иметь локализованные обложки.
  • При этом в шаблоне списка постов можно подгружать правильное изображение в зависимости от текущего языка.
content/
  blog/                      # раздел блога (branch bundle)
    _index.en.md             # заголовок раздела на английском
    _index.ru.md             # заголовок раздела на русском
    first-post/              # leaf bundle для поста
      index.en.md
      index.ru.md
      cover.jpg              # общая обложка
    second-post/
      index.en.md
      index.ru.md
      cover-ru.jpg
      cover-en.jpg

5 Дополнительные возможности

  • Переопределение языка в front matter
    • Можно использовать один файл index.md и указать язык в front matter (lang: ru). 1
    • Но подход с суффиксами в имени файла (index.ru.md) часто удобнее и автоматически определяет язык без необходимости писать front matter.
  • Меню и настройки
    • Hugo позволяет локализовать меню, параметры сайта и даже шаблоны.
  • Интернационализация строк
    • Для интерфейсных строк (например, «Читать далее») можно использовать i18n папку с файлами переводов.

6 Миграция многоязычного сайта на page bundle

6.1 Конфигурация языков (languages.yaml)

  • В отличие от подхода с отдельными папками (content/ru/, content/en/), здесь мы оставляем единую папку content/ без переопределения contentDir.

  • Языки определяются так:

    # config/_default/languages.yaml
    ru:
      languageCode: ru-RU
      languageName: Русский
      weight: 1
      params:
        description: "Описание сайта на русском"
    
    en:
      languageCode: en-US
      languageName: English
      weight: 2
      params:
        description: "Site description in English"
    
  • Не указывайте contentDir — контент для всех языков будет браться из одной корневой папки content/.

  • Hugo сам определит язык по суффиксу в имени файла (например, index.ru.md) или по значению lang в front matter.

6.2 Структура контента с Page Bundle

  • Внутри content/ каждая страница (или раздел) представляется отдельной папкой (bundle). Внутри папки лежат файлы с языковыми суффиксами.

6.2.1 Пример для главной страницы (_index.md)

content/
└──── _index.en.md      # английская версия
└──── _index.ru.md      # русская версия

6.2.2 Пример для блога

content/
├── blog/                 # раздел блога (branch bundle)
│   ├── _index.en.md      # заголовок раздела на английском
│   ├── _index.ru.md      # заголовок раздела на русском
│   └── my-first-post/    # отдельный пост (leaf bundle)
│       ├── index.en.md
│       ├── index.ru.md
│       └── cover.jpg

6.3 Настройка URL и префиксов языков

  • Чтобы русская версия была доступна по /ru, а английская по /en/ (или наоборот), в конфигурации Hugo (config/_default/hugo.yaml) нужно включить префиксы:
defaultContentLanguage: en
defaultContentLanguageInSubdir: true

  1. Запрещено, начиная с hugo 0.144.0. Необходимо удалить из файлов эту конструкцию:

    ind . -iname "*.ru.md" -exec sed -i '/^lang: ru$/d' '{}' \;
    
     ↩︎
Дмитрий Сергеевич Кулябов
Authors
Профессор кафедры теории вероятностей и кибербезопасности
Работаю профессором на кафедре теории вероятностей и кибербезопасности Российского университета дружбы народов им. Патриса Лумумбы. Научные интересы относятся к области теоретической физики и математического моделирования.