Hinode logo
  • About 
  • Docs 
  • Components 
  • Guides 
  • Releases 
  •  
Docs
  • Getting Started
    • Introduction
    • Commands
    • Hosting and Deployment
    • Upgrading
    • Private Modules and Packages
    • Contribute
    • Troubleshooting
  • Content
    • Content Management
    • Content Organization
    • Typography
    • Links and Cross-References
    • Images and Figures
    • Tables
    • Icons
  • Configuration
    • Layout
    • Colors
    • Color Modes
    • Fonts
    • Languages
    • Navigation
    • Documentation
    • Analytics
    • Modules
    • Cookie Consent
    • Digital Asset Managers
  • Components
    • Abbr
    • Accordion
    • Alert
    • Animation
    • Args
    • Badge
    • Breadcrumb
    • Button
    • Button Group
    • Card
    • Card Group
    • Carousel
    • Collapse
    • Command Prompt
    • Docs
    • Example
    • File
    • Icon
    • Image
    • Ins
    • Kbd
    • Link
    • Map
    • Mark
    • Navbar
    • Navs and Tabs
    • Persona
    • Release
    • Spinner
    • Sub
    • Sup
    • Table
    • Timeline
    • Toast
    • Tooltip
    • Video
  • Advanced Settings
    • Overview
    • Styles
    • Scripts
    • Icons
    • Partial Development
    • Module Development
    • Server Headers
    • Server-Side Redirection
  • About
    • Credits
    • License
  • Getting Started
    • Introduction
    • Commands
    • Hosting and Deployment
    • Upgrading
    • Private Modules and Packages
    • Contribute
    • Troubleshooting
  • Content
    • Content Management
    • Content Organization
    • Typography
    • Links and Cross-References
    • Images and Figures
    • Tables
    • Icons
  • Configuration
    • Layout
    • Colors
    • Color Modes
    • Fonts
    • Languages
    • Navigation
    • Documentation
    • Analytics
    • Modules
    • Cookie Consent
    • Digital Asset Managers
  • Components
    • Abbr
    • Accordion
    • Alert
    • Animation
    • Args
    • Badge
    • Breadcrumb
    • Button
    • Button Group
    • Card
    • Card Group
    • Carousel
    • Collapse
    • Command Prompt
    • Docs
    • Example
    • File
    • Icon
    • Image
    • Ins
    • Kbd
    • Link
    • Map
    • Mark
    • Navbar
    • Navs and Tabs
    • Persona
    • Release
    • Spinner
    • Sub
    • Sup
    • Table
    • Timeline
    • Toast
    • Tooltip
    • Video
  • Advanced Settings
    • Overview
    • Styles
    • Scripts
    • Icons
    • Partial Development
    • Module Development
    • Server Headers
    • Server-Side Redirection
  • About
    • Credits
    • License

Partial Development

Share via
Hinode
Link copied to clipboard

Develop custom partials and shortcodes following Hinode's coding conventions.

On this page
Shared Partials   Nested Shortcodes   Argument Validation  

Hinode supports more than 30 shortcodes. Many of these shortcodes wrap an predefined Bootstrap component, such as the Button or Tooltip. Custom shortcodes include a Command Prompt, Image, and Timeline. Some of these components are maintained in a separate module, such as the Animation or Map. Hinode follows several conventions to standardize and streamline the development of shortcodes and partials. You are encouraged to use the same conventions, especially when contributing your own code for sharing.

Shared Partials  

Hugo supports two kinds of reusable components, being partials and shortcodes. A shortcode can be referenced from within content files, such as Markdown. Partials can be referenced by layout files, other partials, and shortcodes too. You cannot reference a shortcode from a partial though. To enable reuse, Hinode has shifted the bulk of the implementation of many of its shortcodes to separate partials. These partials are maintained in the layouts/partials/assets folder. The related shortcode then simply references the partial.

As an example, consider the implementation of the Breadcrumb. Hinode adds a breadcrumb to all pages (except the homepage) if enabled in the Site Parameters. The implementation is available in layouts/partials/assets/breadcrumb.html. The same component is also exposed as a shortcode, so it can be called from within a content page. The shortcode file layouts/shortcodes/breadcrumb.html includes the following statement to invoke the partial. The page argument passes the current page context to the underlying partial:

{{ partial "assets/breadcrumb.html" (dict "page" .page) }}

Nested Shortcodes  

Several shortcodes, such as the Accordion and Carousel, support the nesting of elements. For example, you can group multiple cards to align their heights. To enhance security, Hinode Does Not Process Raw HTML Content by Default. However, the parent shortcode card-group does need to further process the HTML output generated by the individual cards. To facilitate this, Hinode uses Scratch Variables  to pass trusted output from a child to its parent. These scratch variables are not accessible from within the content page, thus shielding them from any unwanted input.

Take a look at the card shortcode. It generates HTML content by invoking the underlying partial. If a parent is available (such as a card-group shortcode), it redirects or appends the partial output to the scratch variable inner. When no parent is available, the partial output is written to the default output stream instead. The partial output is trusted (note: the actual content processed as input by the card partial is not trusted) with the safeHTML pipeline instruction.

{{ $output := partial "assets/card.html" (dict [...]) }}
{{ with .Parent }}
    {{ $current := .Scratch.Get "inner" }}
    {{ if $current }}
        {{ .Scratch.Set "inner" (print $current $output) }}
    {{ else }}
        {{ .Scratch.Set "inner" $output }}
    {{ end }}
{{ else }}
    {{ print $output | safeHTML }}
{{ end }}

Next, the parent card-group shortcode reads the scratch variable inner and passes this as an argument to the card-group partial. Each of the child card shortcodes should have processed the inner content. If any content remains, the card-group shortcode raises a warning and skips this input for further processing.

{{ $inner := .Scratch.Get "inner" }}
{{ $input := trim .Inner " \r\n" }}
{{ if $input }}
    {{ $input = replace $input "\n" "\n  " }}
    {{ warnf "Unexpected inner content: %s\r\n      %s" .Position $input }}
{{ end }}

{{ partial "assets/card-group.html" (dict "page" .Page "cards" $inner [...]) }}

Argument Validation  

Added in 0.22.0   

Most shortcodes support multiple arguments to configure their behavior and to refine their appearance. These shortcodes share many of these arguments with an underlying partial. Hinode uses a standardized approach to validate these arguments. All arguments are formally defined in a separate data structure file. Hinode uses the YAML format by default, although several formats are supported. The partial utilities/IsInvalidArgs.html (provided by the Mod-Utils Module  ) then uses this specification to validate all arguments. Refer to the documentation to review the Supported Data Format.

Let’s consider the following example. The Toast shortcode displays a dismissable message in the bottom-right corner of the screen. We can trigger it by assigning its unique identifier to a button.

Show toast  
First title
This is a toast message
markdown
{{< button toast="toast-example-1" >}}Show toast{{< /button >}}

{{< toast id="toast-example-1" header="First title" >}}This is a toast message{{< /toast >}}

The toast shortcode displays the message This is a toast message provided as inner input. Additionally, it supports the following arguments:

Name Type Required Default Comment
class string Class attribute of the toast element.
header string Header of the toast message. Uses the site title by default.
id string Unique identifier of the toast message, defaults to toast-message-n with sequence n.
Name Type Required Default
class string
Class attribute of the toast element.
header string
Header of the toast message. Uses the site title by default.
id string
Unique identifier of the toast message, defaults to toast-message-n with sequence n.

The toast shortcode invokes the underlying partial to render the actual HTML output. The partial supports similar arguments, but expects the inner content to be passed as argument message instead. The following file formalizes these specifications:

  • toast.yml
comment: >-
  Prepares a toast message. Use a trigger to display the message.
arguments:
  id:
    type: string
    optional: true
    comment: >-
      Unique identifier of the toast message, defaults to `toast-message-n`
      with sequence n.
  header:
    type: string
    optional: true
    comment: Header of the toast message. Uses the site title by default.
  class:
    type: string
    optional: true
    comment: Class attribute of the toast element.
  message:
    type:
      - string
      - template.HTML
    optional: false
    comment: Toast message.
    group: partial
body:
  type: string
  optional: false
  comment: Toast mesage.
  group: shortcode
...

The shortcode uses the following code to validate its arguments, excluding the message argument that belongs to the partial group. When an error occurs, the shortcode logs an error message with a reference to the context .Position.

{{ if partial "utilities/IsInvalidArgs.html" (dict "structure" "toast" "args" .Params "group" "shortcode") }}
    {{ errorf "Invalid arguments: %s" .Position -}}
    {{ $error = true }}
{{ end }}

The underlying partial uses a similar call. Notable differences are the validated arguments (. instead of .Params) and the group (partial instead of shortcode). Partials are not aware of their context, so a generic error is logged instead.

{{ if partial "utilities/IsInvalidArgs.html" (dict "structure" "toast" "args" . "group" "partial") }}
    {{- errorf "partial [assets/toast.html] - Invalid arguments" -}}
    {{ $error = true }}
{{ end }}
• Update to Hinode v0.27.13 (b6f5054)
On this page:
Shared Partials   Nested Shortcodes   Argument Validation  
Partial development
Partial development
Hinode is a clean documentation and blog theme for your Hugo site based on Bootstrap 5.
Code licensed MIT, docs CC BY-NC 4.0
Currently v0.29.3
Privacy | Cookies
 
Links
Home 
About 
Docs 
Components 
Releases 
Guides
Getting Started 
Developing Modules 
Optimization 
Versioning 
Community
Issues   
Discussions   
Contribute 
Hinode
Code copied to clipboard