Разработка кастомного шорткода Hugo

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.
Разработка и обслуживание любых видов сайтов:
Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Разработка кастомного шорткода Hugo
Простая
~1 рабочий день
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Разработка кастомного шорткода Hugo

Шорткоды Hugo — механизм встраивания переиспользуемых компонентов непосредственно в Markdown-контент. Это решение для случаев, когда нужно добавить в статью что-то сложнее обычного текста: предупреждение, таблицу сравнения, вставку видео с параметрами, интерактивный блок. Авторы контента не трогают HTML — они используют простой синтаксис.

Синтаксис вызова

{{</* предупреждение type="warning" */>}}
Текст предупреждения
{{</* /предупреждение */>}}

{{</* youtube id="dQw4w9WgXcQ" autoplay="false" */>}}

{{</* цитата author="Дональд Кнут" source="The Art of Computer Programming" */>}}
Преждевременная оптимизация — корень всех зол.
{{</* /цитата */>}}

Два варианта синтаксиса:

  • {{< >}} — вывод без экранирования HTML (для компонентов с разметкой)
  • {{% %}} — контент внутри обрабатывается как Markdown

Простой шорткод: callout/предупреждение

{{/* layouts/shortcodes/callout.html */}}
{{ $type := .Get "type" | default "info" }}
{{ $title := .Get "title" }}

{{ $icons := dict
  "info"    "ℹ️"
  "warning" "⚠️"
  "danger"  "🚨"
  "success" "✅"
  "tip"     "💡"
}}

<div class="callout callout--{{ $type }}">
  <div class="callout__icon">{{ index $icons $type }}</div>
  <div class="callout__body">
    {{ with $title }}
    <strong class="callout__title">{{ . }}</strong>
    {{ end }}
    <div class="callout__content">{{ .Inner | markdownify }}</div>
  </div>
</div>

Использование:

{{</* callout type="warning" title="Важно" */>}}
Перед обновлением сделайте резервную копию базы данных.
{{</* /callout */>}}

Шорткод с позиционными параметрами

{{/* layouts/shortcodes/figure.html */}}
{{ $src := .Get 0 }}
{{ $alt := .Get 1 | default "" }}
{{ $caption := .Get 2 | default "" }}
{{ $width := .Get "width" | default "100%" }}

{{ $img := resources.Get $src }}
{{ if $img }}
  {{ $webp := $img | images.Resize (printf "%s WebP" (default "1200x" (.Get "resize"))) }}
  <figure class="article-figure" style="max-width: {{ $width }}">
    <picture>
      <source srcset="{{ $webp.Permalink }}" type="image/webp">
      <img src="{{ $img.Permalink }}" alt="{{ $alt }}" loading="lazy">
    </picture>
    {{ with $caption }}
    <figcaption>{{ . | markdownify }}</figcaption>
    {{ end }}
  </figure>
{{ else }}
  <!-- Fallback для внешних изображений -->
  <figure class="article-figure" style="max-width: {{ $width }}">
    <img src="{{ $src }}" alt="{{ $alt }}" loading="lazy">
    {{ with $caption }}<figcaption>{{ . }}</figcaption>{{ end }}
  </figure>
{{ end }}

Использование:

{{</* figure "images/architecture.png" "Архитектура системы" "Диаграмма компонентов приложения" width="80%" */>}}

Шорткод с вкладками (tabs)

Сложный случай: несколько шорткодов, связанных между собой через scratch:

{{/* layouts/shortcodes/tabs.html */}}
{{ .Scratch.Set "tabs" slice }}
{{ .Inner | markdownify }}

{{ $tabs := .Scratch.Get "tabs" }}
<div class="tabs" data-tabs>
  <div class="tabs__nav" role="tablist">
    {{ range $i, $tab := $tabs }}
    <button
      class="tabs__trigger{{ if eq $i 0 }} is-active{{ end }}"
      role="tab"
      aria-selected="{{ if eq $i 0 }}true{{ else }}false{{ end }}"
      aria-controls="tab-panel-{{ $tab.id }}"
    >{{ $tab.label }}</button>
    {{ end }}
  </div>
  {{ range $i, $tab := $tabs }}
  <div
    id="tab-panel-{{ $tab.id }}"
    class="tabs__panel{{ if not (eq $i 0) }} is-hidden{{ end }}"
    role="tabpanel"
  >{{ $tab.content | safeHTML }}</div>
  {{ end }}
</div>
{{/* layouts/shortcodes/tab.html */}}
{{ $label := .Get "label" }}
{{ $id := $label | urlize }}
{{ $content := .Inner | markdownify }}

{{ $tabs := .Parent.Scratch.Get "tabs" }}
{{ $tabs = $tabs | append (dict "label" $label "id" $id "content" $content) }}
{{ .Parent.Scratch.Set "tabs" $tabs }}

JavaScript для переключения:

document.querySelectorAll('[data-tabs]').forEach(tabGroup => {
  tabGroup.querySelectorAll('.tabs__trigger').forEach((trigger, i) => {
    trigger.addEventListener('click', () => {
      tabGroup.querySelectorAll('.tabs__trigger').forEach(t => {
        t.classList.remove('is-active');
        t.setAttribute('aria-selected', 'false');
      });
      tabGroup.querySelectorAll('.tabs__panel').forEach(p => p.classList.add('is-hidden'));
      trigger.classList.add('is-active');
      trigger.setAttribute('aria-selected', 'true');
      tabGroup.querySelector(`#${trigger.getAttribute('aria-controls')}`).classList.remove('is-hidden');
    });
  });
});

Шорткод для вставки кода с заголовком

{{/* layouts/shortcodes/code.html */}}
{{ $lang := .Get "lang" | default "bash" }}
{{ $title := .Get "title" | default "" }}
{{ $filename := .Get "filename" | default "" }}

<div class="code-block">
  {{ if or $title $filename }}
  <div class="code-block__header">
    {{ with $filename }}<span class="code-block__filename">{{ . }}</span>{{ end }}
    {{ with $title }}<span class="code-block__title">{{ . }}</span>{{ end }}
    <button class="code-block__copy" onclick="copyCode(this)">Копировать</button>
  </div>
  {{ end }}
  <div class="code-block__content">
    {{ highlight (.Inner | trim "\n") $lang "" }}
  </div>
</div>

Шорткод для таблицы сравнения

{{/* layouts/shortcodes/compare.html */}}
{{ $headers := split (.Get "headers") "," }}
{{ $rows := split .Inner "\n" | after 0 }}

<div class="compare-table-wrapper">
  <table class="compare-table">
    <thead>
      <tr>
        {{ range $headers }}
        <th>{{ . | trim " " }}</th>
        {{ end }}
      </tr>
    </thead>
    <tbody>
      {{ range $rows }}
      {{ if . }}
      <tr>
        {{ $cells := split . "|" }}
        {{ range $cells }}
        <td>{{ . | trim " " | markdownify }}</td>
        {{ end }}
      </tr>
      {{ end }}
      {{ end }}
    </tbody>
  </table>
</div>

Дебаггинг шорткодов

{{/* Вывод всех параметров для отладки */}}
{{ if hugo.IsServer }}
<pre class="debug-shortcode">
Params: {{ .Params | jsonify (dict "indent" "  ") }}
Inner: {{ .Inner }}
Parent: {{ with .Parent }}{{ .Name }}{{ end }}
</pre>
{{ end }}

Сроки

Один простой шорткод (предупреждение, цитата, badge) — 2–4 часа. Набор из 5–10 шорткодов с CSS и базовым JS — 2–3 дня. Сложные связанные шорткоды (tabs, accordion, compare table) с полным покрытием edge-кейсов — 3–5 дней.