This is the multi-page printable view of this section. .

Return to the regular view of this page.

Content components

Use Oink’s local, reusable components for richer documentation.

OINK promotes the content components that proved reusable across PGSTY sites into the theme. Each component has a stable authoring API, unique instance IDs, local assets, and a defined safety boundary. Site-specific data widgets remain outside the theme.

Loading model

Interactive shortcodes mark the features used by a page. OINK then adds each required stylesheet or runtime once, even if the page has several component instances. A plain page does not download component code it never uses.

Relative asset and link parameters pass through Hugo’s URL handling, so they remain correct under a subpath baseURL. Component markup also has print, dark-mode, mobile, keyboard, and reduced-motion behavior where applicable.

Everyday content primitives

Everyday primitives cover small structures that recur throughout engineering documentation. Each guide below explains when to use the primitive, shows the rendered result beside its source, and records its complete version-one API.

Choose a primitive

Documentation need Reference JavaScript
Release state, lifecycle, or short status Badge None
Shortcut or key sequence Kbd None
Configuration, parameter, or response data Fields and Field None
Repository or directory structure FileTree None; folders use details
Inspect a screenshot or architecture image Image Zoom Optional, loaded on demand
Compare several related images Gallery Reuses optional Image Zoom JS

Shared authoring contract

All primitives except Kbd use named parameters and standard {{< ... >}} shortcode notation. Parameter names are case-sensitive. Unknown parameters, quoted booleans or integers, empty required strings, invalid enum values, and incorrect parent/child combinations stop the build with the source position.

The public APIs do not accept arbitrary class, style, colors, or event handlers. Visible labels come from the author or Oink’s translations. Static primitives add no JavaScript; interactive primitives mark their page so the required runtime is included once.

Validation and fallbacks

The output contract keeps the same information available without a browser runtime:

Primitive HTML Markdown Print and RSS JavaScript
Badge Semantic status span or link Emphasized text or link Static inline content None
Kbd Nested kbd sequence Ctrl + K Plain key notation None
Fields Responsive definition list Metadata bullet list Complete definitions None
FileTree Nested lists and native disclosure Nested list Fully expanded tree None
Shared image Figure, image, and caption Ordinary image and caption Static figure Reuses Zoom when enabled
Gallery Responsive figure grid Images and captions Sequential static figures Reuses Zoom when enabled

Missing required parameters and invalid values fail the Hugo build instead of silently changing meaning. Historical positional imgproc remains compatible, but new content should use the accessible named form.

Deliberate limits

Version one does not add a public Icon shortcode or an icon parameter to Badge. Oink’s private shell SVG registry remains separate from author-facing content icons. Automatic TypeScript parsing, API playgrounds, directory reads, remote image downloads, and complex pan or wheel-zoom controls also remain outside the Hugo-only theme boundary.

Asciinema

Use asciinema for a terminal recording stored as a local .cast file:

GO-HTML-TEMPLATE
{{< asciinema
  file="images/install.cast"
  speed="1.5"
  markers="0:Start,1:Done"
>}}
images/install.cast

file is required and can also be the first positional argument. The terminal window uses title when supplied and otherwise displays the file value. Supported options are title, theme, fit (width, height, both, or none), autoplay, loop, preload, speed, startAt, poster, cols, rows, idleTimeLimit, pauseOnMarkers, and comma-separated markers.

Keep cast files local for offline use. A remote URL is accepted only when the author explicitly supplies it.

Advanced visualizations

ECharts and Infographic remain Oink content components, but each now has a dedicated section under Advanced. This page keeps the reusable component overview concise and points to the richer examples.

Apache ECharts

Use Apache ECharts for quantitative charts based on structured JSON or YAML. The chart gallery contains several live patterns, and callbacks and trusted code documents the explicit executable-code boundary.

AntV Infographic

Use Infographics with AntV for declarative processes, timelines, cycles, grids, and funnels. The dedicated pages explain template semantics, themes, local-first constraints, and accessible textual fallbacks.

doc-card and nav-card share one card implementation. doc-cards and nav-cards create responsive groups of one to four columns. The aliases let an existing site’s content keep its most descriptive name without duplicating markup or styles.

GO-HTML-TEMPLATE
{{< nav-cards cols="3" >}}
  {{< nav-card
    title="Architecture"
    link="/docs/about/architecture/"
    icon="fa-solid fa-diagram-project"
    desc="Understand the build and runtime boundaries."
  >}}
  {{< nav-card
    title="Deployment"
    link="/docs/deploy/"
    badge="Hugo-only"
  >}}Publish the static output.{{< /nav-card >}}
{{< /nav-cards >}}

A card accepts title, link, image, alt, icon, desc, accent, and badge. Its body can contain Markdown links. Tokens such as {version} in desc resolve from site parameters when a matching value exists.

Wrap document cards in doc-carousel to create an accessible horizontal carousel:

GO-HTML-TEMPLATE
{{< doc-carousel label="OINK workflow" >}}
  {{< doc-card title="Write" >}}Create paired content.{{< /doc-card >}}
  {{< doc-card title="Build" >}}Run Hugo Extended.{{< /doc-card >}}
  {{< doc-card title="Verify" >}}Inspect the static site.{{< /doc-card >}}
{{< /doc-carousel >}}

label supplies the carousel’s accessible name. Arrow keys and visible previous/next controls navigate the track; reduced-motion preferences disable unnecessary animation.

Details

details emits native details and summary elements:

GO-HTML-TEMPLATE
{{% details title="Why Hugo-only?" closed="false" %}}
Committed browser assets keep the consuming build reproducible.
{{% /details %}}
Why Hugo-only?
Committed browser assets keep the consuming build reproducible.

title sets the summary. The block is closed by default; set closed=false to render it open.

Tabs

OINK keeps Docsy’s tabpane and tab authoring model while preserving selected=true and whitespace behavior used by imported sites:

GO-HTML-TEMPLATE
{{< tabpane text=true >}}
  {{< tab header="Local" selected=true >}}
  Build with the complete local theme.
  {{< /tab >}}
  {{< tab header="Cloudflare" >}}
  Run the same Hugo command from the source branch.
  {{< /tab >}}
{{< /tabpane >}}
Local
Build with the complete local theme.
Cloudflare
Run the same Hugo command from the source branch.

Use text=true for Markdown content; otherwise tabs are syntax-highlighted code. Tab panes also support language-aware persistence, disabled tabs, and right-aligned entries. Generated tab and panel IDs have matching ARIA relationships.

Parameters

param prints a page parameter, falling back to the site parameter of the same name:

GO-HTML-TEMPLATE
Current version: {{< param version >}}

Current version: v0.2.0

The shortcode fails the build when the named parameter does not exist. This is intentional: a missing release or repository value should not silently produce misleading documentation.

Existing rich content

OINK also ships local runtimes for inherited content features:

  • fenced mermaid, math, and markmap code blocks;
  • swaggerui and redoc API documentation shortcodes;
  • Docsy blocks, alerts, image, include, readfile, cards, and other established shortcodes.

See Shortcodes and Diagrams and formulae for the complete authoring reference.

Authoring rules

  • Prefer structured data over executable content.
  • Give images useful alt text and carousels a meaningful label.
  • Do not enable autoplay unless the content genuinely requires it.
  • Test several identical instances on one page when creating a new wrapper.
  • Verify keyboard navigation, focus visibility, dark and light themes, mobile layout, print output, and reduced-motion behavior.
  • Keep business-specific data components in the consuming site.

1 - Badge

Add compact, semantic status labels without custom colors or JavaScript.

Use Badge to place a short status beside a feature, option, or release name. The author chooses a semantic tone; Oink maps it to theme tokens that retain contrast in light and dark modes.

When to use

Badge works well for lifecycle states such as Beta, New, Experimental, and Deprecated. Keep the text explicit: color supplements the label and never replaces it. Use ordinary prose or an alert when the status needs explanation, instructions, or a deadline.

Quick start

Source

GO-HTML-TEMPLATE
{{< badge text="Beta" tone="warning" >}}
{{< badge text="Deprecated" tone="danger" outline=false >}}
{{< badge text="v0.3" tone="info" link="/blog/release/" >}}

Rendered result

Neutral Info Supported Beta Deprecated v0.3

The final badge is a link. The others are static inline labels.

Parameters

Badge parameters

text
string, required

A nonempty string shown to the reader.

tone
enum, default: neutral

One of neutral, info, success, warning, or danger.

link
URL

A validated internal, relative, HTTP(S), or mailto: destination. When set, the Badge becomes a link.

outline
boolean, default: true

Set to false to select the filled treatment.

Pass booleans without quotes. For example, use outline=false, not outline="false". Unknown parameters and invalid tone or link values stop the Hugo build and report the source position.

Semantics and fallback

A static badge renders as a span; a linked badge renders as an a. Oink does not make it a live status region, so adding a badge does not create unexpected screen-reader announcements. Its visible text remains present in every output: Markdown uses emphasized text (and preserves the link), while print and RSS use static inline content. Badge loads no JavaScript.

Deliberate limits

Badge does not accept arbitrary colors, CSS classes, styles, or event handlers. Version one also has no icon parameter. Use a concise textual label now; content icons can receive a separate public API after their naming, licensing, accessibility, and Markdown fallback contracts are settled.

2 - Kbd

Write keyboard shortcuts as accessible, static key sequences.

Use Kbd to distinguish literal keys and shortcuts from surrounding prose. It renders semantic HTML, remains readable in Markdown and print, and needs no JavaScript.

When to use

Use Kbd for keys the reader should press, including multi-key shortcuts. Use inline code for commands, option names, or text the reader should type; those are not physical or virtual keys.

Quick start

Source

GO-HTML-TEMPLATE
Press {{< kbd "Ctrl" "K" >}} to open search.
Use {{< kbd "⌘" "Shift" "P" >}} to open the command palette.

Rendered result

Press Ctrl with K to open search. Use with Shift with P to open the command palette, or press Alt with Enter to apply an action.

Interface

Kbd accepts one or more nonempty positional strings:

GO-HTML-TEMPLATE
{{< kbd "key" >}}
{{< kbd "first key" "second key" "third key" >}}

It has no named parameters. Quotes are required because every key must be a string. Missing keys, blank strings, named arguments, or non-string values stop the build with the source position.

Use the label printed on the relevant platform when the distinction matters. For cross-platform instructions, name the platform in prose instead of placing alternatives inside one key sequence.

Semantics and fallback

HTML contains one nested kbd element per key. Visual plus signs are hidden from assistive technology; a localized word separates the keys for screen readers. Markdown, print, and RSS use an unambiguous sequence such as Ctrl + K. The instruction remains complete when CSS or JavaScript is absent.

Deliberate limits

Kbd represents simultaneous key sequences only. It does not model menus, gesture input, key remapping, platform detection, or an interactive shortcut recorder. Explain sequential actions in prose: “press Escape, then Enter.”

3 - Fields and Field

Describe configuration, parameters, properties, and response fields with responsive semantic HTML.

Use fields with field children to document named values and their metadata. The component favors a responsive definition list over a wide fixed table, so long names and descriptions remain usable on narrow screens.

When to use

Fields works for configuration keys, command or API parameters, object properties, and response members. Use a regular Markdown table when readers must compare many rows across the same columns. Use prose when the entries are steps rather than definitions.

Quick start

Source

GO-HTML-TEMPLATE
{{< fields label="Search configuration" >}}
  {{< field name="offlineSearch" type="boolean" required=true default=true >}}
  Builds a **local** search index and command palette.
  {{< /field >}}

  {{< field name="offlineSearchMaxResults" type="integer" default=10 >}}
  Limits the number of visible results.
  {{< /field >}}
{{< /fields >}}

Rendered result

Search configuration

offlineSearch
boolean, required, default: true

Builds a local search index and command palette.

offlineSearchMaxResults
integer, default: 10

Limits the number of visible results while retaining keyboard navigation.

searchPlaceholder
string, default: ""

Sets optional placeholder text. The empty-string default remains visible.

theme.components.media.previewMaximumWidthInCharacters
string, default: auto

This deliberately long field name demonstrates wrapping without widening the page.

Descriptions accept Markdown, including links, emphasis, inline code, and lists. Keep each description self-contained because Markdown output presents each one beneath its metadata.

Fields parameters

fields parameters

label
string

A nonempty visible label associated with the complete definition list.

The container must have at least one direct field child. Text or another shortcode directly inside fields stops the build.

Field parameters

field parameters

name
string, required

A nonempty string identifying the field.

type
string

A nonempty type label such as boolean, string[], or duration.

required
boolean, default: false

When true, adds the localized required marker.

default
scalar

A string, boolean, integer, or floating-point value. false, 0, and "" are preserved.

Every field also requires a nonempty body. It must be a direct child of fields. Parameter names and types are validated at build time, and unknown parameters are errors.

Semantics and fallback

HTML uses dl, dt, and dd. Metadata is displayed as columns where space permits and stacks naturally on mobile. The optional label names the definition list for assistive technology. Markdown emits an indented bullet list with code-formatted names, types, and defaults; print and RSS retain every definition. No JavaScript is loaded.

Deliberate limits

Version one does not implement kind, deprecated, since, location, or per-field links. It also does not parse TypeScript or an API schema inside Hugo. An external generator may emit these shortcodes later, keeping compiler and schema runtimes outside the theme while preserving this output contract.

4 - FileTree

Present repository and directory structures as semantic, progressively disclosed lists.

Use FileTree to explain the part of a repository or directory layout that matters to the reader. Folders use native disclosure controls in interactive HTML; every output retains the complete nested structure.

When to use

FileTree works best for curated structures in setup guides, architecture overviews, and contribution instructions. Use a code block for literal command output that should be copied verbatim. Describe generated or highly dynamic trees in prose instead of committing a large snapshot that will quickly drift.

Quick start

Source

GO-HTML-TEMPLATE
{{< filetree label="Repository structure" >}}
  {{< filetree/folder name="content" open=true >}}
    {{< filetree/file name="_index.md" >}}
    {{< filetree/folder name="docs" open=true >}}
      {{< filetree/file name="getting-started.md" >}}
    {{< /filetree/folder >}}
  {{< /filetree/folder >}}
  {{< filetree/file name="hugo.yml" link="/docs/getting-started/" >}}
{{< /filetree >}}

Rendered result

Repository structure

The blog folder starts closed. Activate its summary with a pointer, Enter, or Space to reveal the child file; this behavior comes from the native details element rather than a custom script.

Root parameters

filetree parameters

label
string

A nonempty visible label associated with the root list.

The root accepts only direct filetree/folder and filetree/file children. Add at least one meaningful entry rather than publishing an empty tree.

Folder and file parameters

filetree/folder parameters

name
string, required

A nonempty visible directory name.

open
boolean, default: false

Controls the initial interactive HTML state.

filetree/file parameters

name
string, required

A nonempty visible file name.

link
URL

A validated internal, relative, HTTP(S), or mailto: destination.

A folder can contain folders and files recursively. A file cannot contain children. Unknown parameters, text between children, or a child outside an allowed parent stops the build with its source position.

Semantics and fallback

The structure is a nested ul. Interactive folders add native details and summary; Oink deliberately does not declare role="tree", because that ARIA widget would require a complete arrow-key navigation model. Print and RSS expand all folders. Markdown becomes a nested list with linked file names where applicable. No JavaScript is loaded.

Deliberate limits

FileTree is author-controlled and never reads a local directory during a Hugo build. This keeps builds safe and reproducible. Version one also has no public badge or icon parameters for entries; the built-in folder and file glyphs are presentational theme details, not content APIs.

5 - Image Zoom

Let readers inspect meaningful standalone images with an optional native dialog.

Image Zoom progressively enhances eligible content images with one native dialog. It is useful for screenshots and architecture diagrams whose details may be hard to read at the document width. The original image remains complete when JavaScript or dialog support is unavailable.

When to use

Enable zoom when a reader benefits from seeing the source image at a larger size. Prefer a purpose-built crop or a clearer diagram when enlargement does not solve the readability problem. Decorative icons, logos embedded in prose, and linked thumbnails should retain their existing behavior.

Enable the feature

Image Zoom is disabled by default. Enable it for the whole site in Hugo configuration:

YAML
params:
  ui:
    image_zoom:
      enable: true

A page can override the site value in its front matter with the same structure. Use a real boolean:

YAML
params:
  ui:
    image_zoom:
      enable: false

Oink only includes the JavaScript runtime and dialog on an enabled page that has an eligible image. Enabling the switch alone adds no runtime to a text-only page.

Quick start

Source

Ordinary standalone Markdown images are eligible. The named imgproc form is useful when Oink should generate a smaller preview but open the original:

GO-HTML-TEMPLATE
{{< imgproc
  src="images/content-primitives/oink.webp"
  command="Fit"
  options="640x320"
  alt="OINK local-first documentation preview"
>}}
A processed preview with a **Markdown caption**.
{{< /imgproc >}}

Rendered result

Activate the image with a pointer, Enter, or Space. Close the dialog with Escape, the visible close button, or the backdrop.

OINK local-first documentation preview

The document displays a processed preview. Image Zoom opens the original resource, and closing the dialog restores focus to this trigger.

An image inside a link is deliberately skipped and remains a link:

Linked OINK image remains a link

Eligible images

Oink enhances a meaningful image when all of these conditions hold:

  • The image is standalone in a paragraph or figure, or Gallery marks it explicitly.
  • It has a nonempty alt value and usable source.
  • It is not inside a link, button, or element marked data-no-zoom.
  • It is not marked aria-hidden="true", role="presentation", or role="none".

Inline images among text and empty-alt decorative images are skipped. Authors can add data-no-zoom to an image or ancestor in trusted HTML when an otherwise eligible image should not open.

Named imgproc parameters

Named imgproc parameters

src
resource path, required

An exact page or global image resource.

command
enum, required

One of Fit, Resize, Fill, or Crop.

options
string, required

Nonempty Hugo image-processing options, such as 640x320.

alt
string

Meaningful alternative text. It is required for content images and omitted only with decorative=true.

decorative
boolean, default: false

When true, alt must be absent and Image Zoom is suppressed.

The optional shortcode body is a Markdown caption. The historical three-value positional imgproc form remains compatible, but new content should use the named form so alternative text is enforced at build time.

Interaction and fallback

Progressive enhancement wraps an eligible image in a real button with aria-haspopup="dialog". The native dialog moves focus to its close button, supports Escape, copies the image’s alternative text and direct caption, and restores focus after closing. Without JavaScript or HTMLDialogElement, the image and caption remain ordinary static content. Markdown, print, and RSS do not include dialog controls.

Deliberate limits

Version one does not implement dragging, panning, wheel zoom, editing, or previous and next image navigation. It also never downloads a remote image at build time. Use Gallery to group related images while reusing this same dialog.

6 - Gallery

Arrange related images in a responsive static grid that can reuse Image Zoom.

Gallery groups related images in a responsive grid. It is static-first: images, alternative text, and captions remain available without JavaScript. When Image Zoom is enabled, Gallery reuses the same dialog instead of loading another lightbox.

When to use

Use Gallery to compare a small set of screenshots, states, or related visual examples. Use a single image when sequence and comparison do not matter. Use Carousel when the content intentionally needs slide navigation and hiding noncurrent items is acceptable.

Quick start

Source

GO-HTML-TEMPLATE
{{< gallery columns=3 label="OINK screenshots" >}}
  {{< gallery/image
    src="images/content-primitives/oink.webp"
    alt="OINK documentation overview"
    caption="Documentation overview"
  >}}
  {{< gallery/image
    src="/images/feedback.png"
    alt="OINK feedback interface"
    caption="Feedback controls"
  >}}
{{< /gallery >}}

Rendered result

This page enables Image Zoom. Activate any image to inspect it in the shared dialog. With JavaScript disabled, the same three figures remain visible in the same reading order.

gallery parameters

columns
integer, default: 2

An unquoted value from 1 through 4; this is the desktop maximum.

label
string

A nonempty visible label associated with the gallery list.

The container requires at least one direct gallery/image child and accepts no ordinary body text. Small viewports reduce the effective column count without changing the requested desktop maximum.

Image parameters

gallery/image parameters

src
image URL, required

A validated page, global, static, or remote image URL.

alt
string, required

Meaningful nonempty plain text describing the image.

caption
string

Nonempty plain text shown below the image.

Gallery records intrinsic width and height for local Hugo resources when available and adds lazy loading. It accepts a remote source URL but never downloads that image during the Hugo build, so remote dimensions remain unknown. Captions do not render Markdown; keep them concise and move rich explanation into nearby prose.

Semantics and fallback

HTML uses a labeled ul of figure, img, and optional figcaption elements. Each image retains its own alternative text; the gallery label names the collection. Markdown emits ordinary images followed by italic captions. Print and RSS render sequential static figures. Gallery has no private JavaScript runtime: it only marks its images for Image Zoom when that page-level feature is enabled.

Deliberate limits

Gallery does not crop images to a forced aspect ratio, reorder them by breakpoint, hide overflow, or provide slide navigation. It has no Gallery-specific lightbox. These constraints preserve document order and keep the fallback complete.