Зачем вообще читать про минорный релиз #

18 февраля 2026 вышел Hugo v0.156.0. Если поверхностно прочитать changelog, это очередной минор: пара новых методов, несколько депрекейтов, опция конфига. Звучит как «обновлюсь когда руки дойдут».

Но именно из таких минорных релизов и копится технический долг. Депрекейт API сегодня — это broken-build через год, когда вы решите перейти на крупную версию. Минута, потраченная сейчас, чтобы привести шаблоны в соответствие, экономит вечер разбирательств позже.

В этом посте — что реально изменилось, что заметно в шаблонах, и короткий чек-лист, который проходится за 30 минут.

Главное за один взгляд #

Релиз 0.156.0 содержит шесть значимых изменений:

  1. Добавлены новые API: hugo.Data и hugo.Sites.
  2. Устаревшими объявлены site.Data и site.Sites (пока работают для обратной совместимости).
  3. В контекст link render hooks добавлены методы IsBlock и Ordinal.
  4. Добавлен новый метод site.Home.Translations; site.Home.AllTranslations помечен как deprecated.
  5. Появилась опция конфигурации disableSetLocale.
  6. Помечен как deprecated путь _vendor/github.com/gohugoio/locales.

Дальше — по каждому пункту, что это значит на практике и что менять.

Переезд site.Data → hugo.Data 🧱 #

Самое заметное смысловое изменение — переезд глобальных коллекций данных и сайтов с пространства имён site.* на hugo.*.

Сейчас в шаблонах вы могли писать:

{{ range site.Data.authors }}
  ...
{{ end }}

После 0.156 рекомендуется:

{{ range hugo.Data.authors }}
  ...
{{ end }}

Версия со старым site.Data пока работает — ради совместимости. Но в release notes явно сказано: новые методы предпочтительнее, старые помечены как deprecated. Когда придёт следующая major-версия (Hugo любит чистить депрекейты), site.Data могут совсем убрать.

Аналогичная история с site.Siteshugo.Sites. Используется реже, в основном на мультисайтах с подмножеством общих ресурсов.

Что делать: массовый поиск-замена в шаблонах темы и проекта:

grep -rn 'site\.Data\|site\.Sites' layouts/ themes/*/layouts/ 2>/dev/null

Если хитов нет — вы никак не зависите от этого изменения. Если есть — заменить на hugo.Data и hugo.Sites.

Render hooks: IsBlock и Ordinal 🔗 #

Если у вас есть кастомные link render hooks (файл layouts/_default/_markup/render-link.html или подобный), в их контексте теперь доступны два новых метода:

  • IsBlock — true, если ссылка стоит как самостоятельный блок (например, <p>[link](url)</p> где это единственный элемент абзаца), а не inline внутри текста.
  • Ordinal — порядковый номер ссылки в документе, начиная с 0.

Зачем это нужно:

{{/* render-link.html */}}
{{ if .IsBlock }}
  {{/* Самостоятельная ссылка — рендерим как карточку */}}
  <a class="link-card" href="{{ .Destination | safeURL }}">
    <span class="link-card__num">{{ add .Ordinal 1 }}</span>
    <span class="link-card__text">{{ .Text | safeHTML }}</span>
  </a>
{{ else }}
  {{/* Inline-ссылка — обычный <a> */}}
  <a href="{{ .Destination | safeURL }}">{{ .Text | safeHTML }}</a>
{{ end }}

Это удобно для блогов с активным использованием ссылок: можно по-разному оформлять «отдельные ссылки на источники» и «inline-упоминания».

Ordinal помогает строить нумерованные списки источников или footnote-style references без ручной разметки.

Мультиязычность: site.Home.Translations 🌐 #

Метод site.Home.AllTranslations помечен как deprecated. Заменяет его более узкий site.Home.Translations.

Разница:

  • AllTranslations возвращает все языковые версии главной страницы, включая текущую.
  • Translations возвращает только другие языки, без текущей версии.

Старый код:

{{ range site.Home.AllTranslations }}
  {{ if ne .Lang $.Lang }}
    <a href="{{ .Permalink }}">{{ .Language.LanguageName }}</a>
  {{ end }}
{{ end }}

После 0.156 ту же логику можно записать прямее:

{{ range site.Home.Translations }}
  <a href="{{ .Permalink }}">{{ .Language.LanguageName }}</a>
{{ end }}

Меньше кода, понятнее намерение. Если вы вели мультиязычный сайт с языковым переключателем — самое время заменить.

Опция disableSetLocale ⚙️ #

В конфиге появилась новая опция:

disableSetLocale = true

По умолчанию Hugo пытается установить системную локаль операционной системы согласно языку текущего сайта. Это влияет на форматирование дат, чисел, сортировку строк (strings.Sort).

Иногда это поведение нежелательно. Например, в CI-контейнере может не быть нужной локали, и Hugo молча падает на дефолт. Или вы хотите, чтобы поведение было одинаковым на всех машинах сборки независимо от языка контента.

disableSetLocale = true отключает эту попытку. Hugo использует значения из конфига и встроенные форматтеры без обращения к OS-уровню setlocale().

Когда нужно: CI-сборки на минимальных образах (alpine, debian-slim), где локали могут отсутствовать; репозитории с воспроизводимой сборкой; ситуации, когда вы заметили различия в форматах между локальной сборкой и CI.

Депрекейт пути _vendor/github.com/gohugoio/locales #

Путь _vendor/github.com/gohugoio/locales помечен как устаревший. Если вы его явно использовали (например, импортировали как submodule в проект), стоит начать миграцию на встроенные локали Hugo — релиз поддерживает их через стандартный механизм.

Большинство пользователей этот путь не трогали, поэтому пункт скорее для разработчиков тем, чем для авторов сайтов.

Чек-лист обновления за 30 минут ✅ #

Чтобы пройти миграцию без сюрпризов:

  1. Поднять версию Hugo до 0.161.0 (если ещё на старой) или 0.156.0 как промежуточный шаг. Если работаете в Docker, обновить ARG HUGO_VERSION и пересобрать образ.

  2. Поиск устаревших API в шаблонах:

    grep -rn 'site\.Data\|site\.Sites\|AllTranslations' layouts/ themes/*/layouts/

    Если хиты есть — заменить на hugo.Data, hugo.Sites, Translations.

  3. Проверить кастомные render hooks, если они есть. Можно ли получить пользу от новых IsBlock и Ordinal?

  4. Решить про disableSetLocale. Если CI-сборки иногда дают разные форматы дат в зависимости от хоста, добавить опцию в конфиг.

  5. Прогнать сборку:

    hugo --minify --gc

    Не должно быть warning’ов. Если появились — каждый из них чем-то да полезен, не игнорировать.

  6. Открыть несколько критичных страниц локально, проверить, что меню, переводы, render hooks работают.

  7. Закоммитить и задеплоить. На статичном Hugo-сайте откат — это git revert плюс пересборка, минут 5.

Итог 🧠 #

Hugo 0.156.0 — не «громкий релиз ради хайпа». Это пакет аккуратных архитектурных изменений: переезд на новые API, расширение возможностей для тех, кто пишет render hooks, чистка мультиязычной части.

Главная польза от такого релиза — возможность снять немного технического долга прямо сейчас, пока депрекейты ещё работают. Пропустишь — через год будешь разбираться, почему что-то перестало рендериться.

Если у вас минимальный шаблонный код (стандартная тема без кастомных hook’ов и без мультиязычности), переход почти прозрачен. Если у вас активные render hooks или мультиязык — стоит выделить полчаса на ревизию.

И да: каждый минор-релиз стоит читать. Не как обязательное домашнее задание, но как короткую инвестицию в собственный код.

Источники #