HugoPress

Pluggable and UI less Hugo modules framework, which defines several functions and partials to load and render Hugo modules automatically. The main advantage is that once the theme support HugoPress, their users have the ability to install the modules without requesting new features to the theme.

Module
github.com/hugomods/hugopress
GitHub Stars Used By Used By Used By Used By

How it Works?

An HTML page is composed of a number of HTML markup blocks.

flowchart TD
  blocks---BS

  subgraph html
  HS[HTML begin] --> blocks[/Render blocks/]
  blocks --> HE[HTML end]
  end

  subgraph block
  BS[Start] --> attrs[/Render attributes/]
  attrs --> hooks[/Render hooks/]
  hooks --> BE[End]
  end

There are two key concepts: attributes and hooks.

Attributes

The attributes are used to append attributes to HTML tags.

NameDescription
documentThe attributes will be appended into the <html> tag.
bodyThe attributes will be appended into the <body> tag.

The attributes partial should return key-value pairs.

1{{- return dict
2  "lang" .Page.Lang
3  "data-foo" "bar"
4  "data-hello" "world"
5}}

Attributes Parameters

NameTypeDefaultDescription
cacheableBooleanfalseWhether to cache the attributes.

Attributes Context

The context (aka the .) of attributes’ partial.

NameTypeDescription
PagePageCurrent page.

Hooks

The hooks are used to render HTML of the module in a specific place, such as <head>, <body>.

NameDescription
head-beginAt the beginning of the <head> tag.
head-endBefore the <head> end.
body-beginAt the beginning of the <body> tag.
body-endBefore the <body> end.

Hooks Parameters

NameTypeDefaultDescription
cacheableBooleanfalseWhether to cache the hooks.

Hooks Context

The context (aka the .) of hook partial.

NameTypeDescription
TotalNumberThe number of modules in the current hook.
IndexNumberThe index number of current module.
HasPrevBooleanWhether there are modules(s) before the current.
HasNextBooleanWhether there are modules(s) after the current.
PagePageCurrent page.

Guide

Create a HugoPress Theme

Modify your baseof.html as following for getting much more flexible, and then override the theme blocks.

 1{{/* layouts/_default/baseof.html */}}
 2<!DOCTYPE html>
 3<html {{ partial "hugopress/document-attributes" . | safeHTMLAttr -}}>
 4  <head>
 5    {{- partial "hugopress/head-begin.html" . }}
 6    {{/* Theme head block begin. */}}
 7    <title>{{- block "title" . -}}{{ .Title }}{{- end -}}</title>
 8    {{/* Theme head block end. */}}
 9    {{- partial "hugopress/head-end.html" . }}
10  </head>
11  <body {{ partial "hugopress/body-attributes" . | safeHTMLAttr -}}>
12    {{- partial "hugopress/body-begin.html" . }}
13    {{/* Theme body block begin. */}}
14    {{- block "main" . }}{{- end }}
15    {{/* Theme body block end. */}}
16    {{- partial "hugopress/body-end.html" . }}
17  </body>
18</html>

Create a HugoPress Modules

Let’s take the hello module as an example, which

  1. Append data-hello="world" into the <html> tag.
  2. Generate <meta name="hello" content="world"> inside the <head> tag.
  3. Print Hello world. at the beginning of <body> tag.

Initialize Module

$ mkdir hugo-mod-hello
$ cd hugo-mod-hello
$ hugo mod init github.com/user/hugo-mod-hello

Modules Configuration

1[params.hugopress.modules.hello.attributes.document]
2[params.hugopress.modules.hello.hooks.head-end]
3[params.hugopress.modules.hello.hooks.body-begin]

We need to specify the attributes and hooks used by the module in config.toml.

Modules Architecture

$ tree layouts/partials/hugopress/modules/hello
├── attributes
│   └── document.html
└── hooks
    ├── body-begin.html
    └── head-end.html

The module files should be placed under the layouts/partials/hugopress/modules folder.

The source code can be found at hello module files.

Disable Module

1[params.hugopress.modules.hello]
2disable = true

Cacheable Attributes and Hooks

1[params.hugopress.modules.hello.attributes.document]
2cacheable = true
3
4[params.hugopress.modules.hello.hooks.body-begin]
5cacheable = true

Hooks Weight

Lower weight gets higher precedence.

1[params.hugopress.modules.hello.hooks.body-begin]
2weight = 1

Functions

NameDescription
{{ partial "hugopress/functions/has-modules" $hookName }}Indicate if there are modules associate to the specified hook.
{{ partial "hugopress/functions/exists" $moduleName }}Indicate whether the module exists.
{{ partial "hugopress/functions/is-disabled" $moduleName }}Indicate whether the module was disabled, false if module doesn’t exist.