Skip to content

Add Hextra shortcodes (Bootstrap 5 port)#172

Merged
fitzergerald merged 3 commits intomasterfrom
hextra-shortcodes
Apr 1, 2026
Merged

Add Hextra shortcodes (Bootstrap 5 port)#172
fitzergerald merged 3 commits intomasterfrom
hextra-shortcodes

Conversation

@simihablo
Copy link
Copy Markdown

Summary

  • Ports 14 shortcodes from the Hextra Hugo theme to the academy-theme, rewritten from Tailwind CSS to Bootstrap 5 classes
  • All shortcodes are namespaced under hextra/ (e.g. {{< hextra/callout >}}, {{< hextra/tabs >}}) to avoid conflicts with existing Hugo built-in, Docsy, and academy-theme shortcodes
  • The theme build passes cleanly with these additions

Shortcodes added

Shortcode Usage
hextra/callout {{< hextra/callout type="info" >}}Text{{< /hextra/callout >}}
hextra/cards + hextra/card Card grid with images, icons, subtitles, tags
hextra/details {{% hextra/details title="Expand" %}}Content{{% /hextra/details %}}
hextra/steps Numbered step list via CSS counters
hextra/tabs + hextra/tab Bootstrap nav-tabs with optional cross-page sync
hextra/badge Inline badges with color variants
hextra/icon Inline SVG icons from data/hextra/icons.yaml
hextra/pdf Embedded PDF viewer
hextra/include Include another page's rendered content
hextra/jupyter Render Jupyter notebook cells
hextra/asciinema Asciinema terminal recording player
hextra/term Glossary term tooltip via data/<lang>/termbase.yaml
hextra/filetree/* Interactive file tree (container, folder, file)

Files added/modified

  • 17 shortcode templates in layouts/shortcodes/hextra/
  • 2 partials in layouts/partials/hextra/utils/ (icon renderer, file-path resolver)
  • 1 data file data/hextra/icons.yaml (SVG icon definitions)
  • 1 SCSS file assets/scss/_hextra_shortcodes.scss (custom component styles)
  • 2 JS modules in assets/js/hextra/ (tab sync, filetree toggle)
  • 1 modified file assets/scss/_styles_project.scss (added SCSS import)

Design decisions

  • Bootstrap 5 rewrite: Every Tailwind utility class was translated to Bootstrap equivalents (alerts, cards, nav-tabs, badges, etc.) with custom SCSS only where Bootstrap has no equivalent (step counters, details chevron animation, card hover effects)
  • Inline JS via Page.Store guards: Tab sync and filetree toggle scripts are emitted once per page only when those shortcodes are actually used — no global JS overhead
  • Hugo Store API preserved: The tabs/tab parent-child communication pattern from Hextra is maintained for content collection at build time

Test plan

  • Verify hugo build succeeds with zero template errors
  • Create a test content page using each shortcode and confirm rendering
  • Test hextra/callout with all 5 types (default, info, warning, error, important) and emoji variant
  • Test hextra/tabs with multiple tab groups and verify Bootstrap JS switching works
  • Test hextra/filetree folder expand/collapse toggle
  • Test hextra/card with images, icons, and tags
  • Verify existing shortcodes (alert, details, pageinfo, etc.) still work unchanged
  • Verify no CSS class collisions between new hextra styles and existing Bootstrap/Docsy styles

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a set of Hextra-inspired Hugo shortcodes to the academy theme, rewritten to use Bootstrap 5 classes and supported by new utility partials, icons data, and theme SCSS/JS assets.

Changes:

  • Introduces 17 new hextra/* shortcodes (callouts, cards, tabs, steps, details, filetree, embeds, etc.).
  • Adds supporting utilities (hextra/utils/*) and a large data/hextra/icons.yaml icon set.
  • Adds shortcode-specific styling (_hextra_shortcodes.scss) and new JS modules under assets/js/hextra/.

Reviewed changes

Copilot reviewed 24 out of 24 changed files in this pull request and generated 15 comments.

Show a summary per file
File Description
layouts/shortcodes/hextra/term.html New glossary-term tooltip shortcode backed by data/<lang>/termbase.yaml.
layouts/shortcodes/hextra/tabs.html Bootstrap 5 tabs container + optional cross-page sync (inline script).
layouts/shortcodes/hextra/tab.html Child tab shortcode that populates parent Store.
layouts/shortcodes/hextra/steps.html Steps container (CSS-counter-based styling via SCSS).
layouts/shortcodes/hextra/pdf.html PDF iframe embed using file-path resolver partial.
layouts/shortcodes/hextra/jupyter.html Jupyter notebook renderer from local or remote .ipynb.
layouts/shortcodes/hextra/include.html Includes another page’s rendered content via RenderShortcodes.
layouts/shortcodes/hextra/icon.html Renders inline SVGs from data/hextra/icons.yaml.
layouts/shortcodes/hextra/filetree/container.html Filetree wrapper + inline folder toggle script.
layouts/shortcodes/hextra/filetree/folder.html Filetree folder row with open/closed state and icons.
layouts/shortcodes/hextra/filetree/file.html Filetree file row with file icon + name.
layouts/shortcodes/hextra/details.html <details>-based accordion/card with chevron styling.
layouts/shortcodes/hextra/cards.html Cards grid container using Bootstrap row/cols utilities.
layouts/shortcodes/hextra/card.html Linked card component with optional image/icon/badge + image processing.
layouts/shortcodes/hextra/callout.html Bootstrap alert-based callout component with icon/emoji support.
layouts/shortcodes/hextra/badge.html Inline badge shortcode with semantic-to-Bootstrap color mapping.
layouts/shortcodes/hextra/asciinema.html Asciinema player container + file resolution + markers support.
layouts/partials/hextra/utils/icon.html Utility partial to render raw SVG from site.Data.hextra.icons.
layouts/partials/hextra/utils/file-path.html Utility to resolve relative/absolute/URL paths for embeds.
data/hextra/icons.yaml Adds the SVG icon registry used by hextra/icon.
assets/scss/_styles_project.scss Imports the new hextra shortcode SCSS.
assets/scss/_hextra_shortcodes.scss New Bootstrap-compatible styling for the added shortcodes.
assets/js/hextra/tabs.js JS module for tab sync (currently duplicates inline script).
assets/js/hextra/filetree.js JS module for filetree toggling (currently inconsistent with templates).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Port 14 shortcodes from the Hextra Hugo theme, rewritten to use
Bootstrap 5 classes instead of Tailwind CSS, and namespaced under
hextra/ to avoid conflicts with existing Hugo, Docsy, and
academy-theme shortcodes.

Shortcodes added:
  hextra/callout, hextra/cards, hextra/card, hextra/details,
  hextra/steps, hextra/tabs, hextra/tab, hextra/badge, hextra/icon,
  hextra/pdf, hextra/include, hextra/jupyter, hextra/asciinema,
  hextra/term, hextra/filetree/container, hextra/filetree/folder,
  hextra/filetree/file

Supporting files:
  - layouts/partials/hextra/utils/{icon,file-path}.html
  - data/hextra/icons.yaml (SVG icon definitions)
  - assets/scss/_hextra_shortcodes.scss (custom styles)
  - assets/js/hextra/{tabs,filetree}.js (standalone JS modules)

Signed-off-by: Alex Quinn <227241865+alexquincy@users.noreply.github.com>
…k rendering

- Switch steps and details shortcodes from {{% %}} to {{< >}} syntax
  to prevent Goldmark from stripping raw HTML output of nested shortcodes
- Use .InnerDeindent | .Page.RenderString in steps.html to render
  Markdown headings while preserving nested shortcode output
- Enable goldmark.renderer.unsafe in theme config so .Page.RenderString
  does not strip raw HTML from nested shortcodes (cards, tabs, filetree, etc.)

Signed-off-by: Alex Quinn <227241865+alexquincy@users.noreply.github.com>
- tab.html: normalize selected param to boolean via eq comparison to
  "true" so that selected="false" is no longer truthy
- term.html: guard data lookup with nested `with` blocks so missing
  language key or termbase gracefully degrades instead of erroring
- filetree/folder.html: use fixed data-state="closed"/"open" on icon
  spans so toggle script correctly shows/hides the right icon
- filetree/file.html: use plainify instead of markdownify to avoid
  block-level HTML inside an inline span
- card.html: render <div> instead of <a> when no link is provided for
  valid HTML/a11y; add rel="noopener noreferrer" on external links
- badge.html: add rel="noopener noreferrer" to badge links
- asciinema.html: remove unreachable errorf dead code; use jsonify for
  marker serialization to prevent injection; add inline CDN script and
  player initialization so asciinema-player actually loads
- jupyter.html: render markdown cells via .Page.RenderString instead of
  raw safeHTML; gate HTML notebook outputs behind allowUnsafeHTML param
- icons.yaml: fix partial path in usage comment
- Remove unused assets/js/hextra/{filetree,tabs}.js that duplicated
  inline scripts already emitted by shortcode templates

Signed-off-by: Alex Quinn <227241865+alexquincy@users.noreply.github.com>
@fitzergerald fitzergerald merged commit b518c57 into master Apr 1, 2026
2 checks passed
@fitzergerald fitzergerald deleted the hextra-shortcodes branch April 1, 2026 23:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants