feat: Add GitHub/Obsidian-style Markdown callout support

Implements Hugo's new blockquote render hooks (v0.132.0+) to support standard
Markdown alert syntax, improving content portability across platforms.

Features:
- 5 alert types: note, tip, important, warning, caution
- Custom titles with `> [!TYPE]+ Custom Title` syntax
- Multilingual support (EN, ES, FR, DE, ZH) with `callout_*` i18n keys
- Shared renderer for both shortcodes and render hooks
- Backward compatibility with deprecated `{{< callout >}}` shortcode

Example usage:
```markdown
> [!NOTE]
> This is a note callout with important information.

> [!WARNING]+ Custom Warning Title
> This warning has a custom title instead of just "Warning".

> [!TIP]
> Here's a helpful tip for better workflow!
```

Breaking changes: None (backward compatible)
Deprecation: `{{< callout >}}` shortcode now shows warning, use standard syntax

Configuration required (already applied to all sites by default):
```yaml
markup:
  goldmark:
    parser:
      attribute:
        block: true
```
This commit is contained in:
George Cushen committed 2025-09-23 00:21:53 +01:00
1 parent b8ab618087
commit 1412d517b6
11 files changed
+327 -26

No files matched your search

+1 -1
View File
@@ -20,7 +20,7 @@ markup:
parser:
# Support Latex math(?)
attribute:
block: true
block: true # For callouts as quote blocks
title: true
extensions:
# Support Latex math
+16
View File
@@ -26,6 +26,22 @@
- id: related
translation: Ähnliches
# Callouts
- id: callout_note
translation: Hinweis
- id: callout_tip
translation: Tipp
- id: callout_important
translation: Wichtig
- id: callout_warning
translation: Warnung
- id: callout_caution
translation: Vorsicht
- id: backlinks
translation: Backlinks
+16
View File
@@ -26,6 +26,22 @@
- id: related
translation: Related
# Callouts
- id: callout_note
translation: Note
- id: callout_tip
translation: Tip
- id: callout_important
translation: Important
- id: callout_warning
translation: Warning
- id: callout_caution
translation: Caution
- id: backlinks
translation: Backlinks
+16
View File
@@ -26,6 +26,22 @@
- id: related
translation: Relacionado
# Callouts
- id: callout_note
translation: Nota
- id: callout_tip
translation: Consejo
- id: callout_important
translation: Importante
- id: callout_warning
translation: Advertencia
- id: callout_caution
translation: Precaución
- id: minute_read
translation: min de lectura
+16
View File
@@ -26,6 +26,22 @@
- id: related
translation: Sur le même sujet
# Callouts
- id: callout_note
translation: Note
- id: callout_tip
translation: Conseil
- id: callout_important
translation: Important
- id: callout_warning
translation: Attention
- id: callout_caution
translation: Prudence
- id: minute_read
translation: min. de lecture
+16
View File
@@ -26,6 +26,22 @@
- id: related
translation: 相关
# Callouts
- id: callout_note
translation: 注意
- id: callout_tip
translation: 提示
- id: callout_important
translation: 重要
- id: callout_warning
translation: 警告
- id: callout_caution
translation: 小心
- id: minute_read
translation: 分钟阅读时长
@@ -0,0 +1,31 @@
{{/*
Hugo Blox Builder Blockquote Render Hook
Renders standard blockquotes and GitHub/Obsidian-style alerts (callouts).
Supports alert types: note, tip, important, warning, caution
Syntax examples:
- > [!NOTE]
> This is a note callout.
- > [!WARNING]+ Custom Title
> This is a warning with custom title.
*/}}
{{ if eq .Type "alert" }}
{{/* Use custom title if provided, otherwise let render_callout handle default */}}
{{ $title := .AlertTitle }}
{{/* Use shared callout renderer */}}
{{ partial "functions/render_callout" (dict
"type" .AlertType
"content" .Text
"title" $title
"source" "renderhook"
) }}
{{ else }}
{{/* Render regular blockquotes */}}
<blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6">
{{ .Text }}
</blockquote>
{{ end }}
@@ -1,4 +1,17 @@
{{/*
DEPRECATED: This shortcode is deprecated in favor of standard Markdown alert syntax.
Instead of:
{{< callout note >}}
Your content here
{{< /callout >}}
Use standard GitHub/Obsidian alert syntax:
> [!NOTE]
> Your content here
This provides better portability across Markdown platforms.
Docs: https://docs.hugoblox.com/reference/markdown/#callouts
Parameters
@@ -8,25 +21,16 @@
Default Hugo Blox Builder available options include "note" and "warning".
Otherwise, you can add your own icon to assets/media/icons/ and reference its name when calling the shortcode.
*/}}
{{ $icon := "information-circle" }}
{{ $class := "bg-primary-100 dark:bg-primary-900" }}
{{ $class_text := "text-primary-600 dark:text-primary-300" }}
{{ with (.Get 0) }}
{{ if eq . "note" }}
{{ $icon = "information-circle" }}
{{ else if eq . "warning" }}
{{ $icon = "exclamation-triangle" }}
{{ $class = "bg-yellow-100 dark:bg-yellow-900" }}
{{ $class_text = "text-red-400" }}
{{ else }}
{{ $icon = . }}
{{end}}
{{end}}
<div class="flex px-4 py-3 mb-6 rounded-md {{$class}}">
<span class="pr-3 pt-1 {{$class_text}}">
{{ partial "functions/get_icon" (dict "name" $icon "attributes" "height=\"24\"") }}
</span>
<span class="dark:text-neutral-300">
{{- .Inner | markdownify | emojify -}}
</span>
</div>
{{/* Log deprecation warning */}}
{{ partial "functions/logger" (dict "page" .Page "level" "warn" "message" "The callout shortcode is deprecated. Use standard Markdown alert syntax instead: > [!NOTE]") }}
{{/* Get callout type from parameter */}}
{{ $type := (.Get 0) | default "note" }}
{{/* Use shared callout renderer */}}
{{ partial "functions/render_callout" (dict
"type" $type
"content" (.Inner | markdownify | emojify)
"source" "shortcode"
) }}
@@ -0,0 +1,80 @@
{{/*
Hugo Blox Builder Shared Callout Renderer
Renders callouts with consistent styling for both shortcodes and render hooks.
Parameters:
- type: The callout type (note, tip, important, warning, caution, or custom icon name)
- content: The callout content (HTML)
- title: Optional title for the callout
- source: "shortcode" or "renderhook" for context
*/}}
{{ $type := (lower .type) | default "note" }}
{{ $content := .content }}
{{ $title := .title }}
{{ if not $title }}
{{/* Try i18n translation with "callout_" prefix, fall back to title case */}}
{{ $i18n_key := printf "callout_%s" $type }}
{{ $title = or (i18n $i18n_key) (title $type) }}
{{ end }}
{{ $source := .source | default "shortcode" }}
{{/* Define icon and styling mappings for different alert types */}}
{{ $alertConfigs := dict
"note" (dict
"icon" "information-circle"
"class" "bg-primary-100 dark:bg-primary-900"
"textClass" "text-primary-600 dark:text-primary-300"
)
"tip" (dict
"icon" "light-bulb"
"class" "bg-green-100 dark:bg-green-900"
"textClass" "text-green-600 dark:text-green-300"
)
"important" (dict
"icon" "exclamation-circle"
"class" "bg-purple-100 dark:bg-purple-900"
"textClass" "text-purple-600 dark:text-purple-300"
)
"warning" (dict
"icon" "exclamation-triangle"
"class" "bg-yellow-100 dark:bg-yellow-900"
"textClass" "text-red-400"
)
"caution" (dict
"icon" "exclamation-triangle"
"class" "bg-red-100 dark:bg-red-900"
"textClass" "text-red-600 dark:text-red-300"
)
}}
{{/* Get configuration for this callout type, or use custom icon */}}
{{ $config := index $alertConfigs $type }}
{{ $icon := $type }}
{{ $class := "bg-primary-100 dark:bg-primary-900" }}
{{ $textClass := "text-primary-600 dark:text-primary-300" }}
{{ if $config }}
{{ $icon = $config.icon }}
{{ $class = $config.class }}
{{ $textClass = $config.textClass }}
{{ end }}
<div class="flex px-4 py-3 mb-6 rounded-md {{ $class }}">
<span class="pr-3 pt-1 {{ $textClass }}">
{{ partial "functions/get_icon" (dict "name" $icon "attributes" "height=\"24\"") }}
</span>
<div class="dark:text-neutral-300">
{{/* Display title if provided */}}
{{- with $title -}}
<div class="font-semibold mb-1">
{{- . -}}
</div>
{{- end -}}
{{/* Display content */}}
<div>
{{- $content -}}
</div>
</div>
</div>