Become a backer or sponsor to support our work.
Do you want to create and share your creative HB modules? Here is everything you want to know.
Let’s get started with a hello
example, which:
<html>
and <body>
.First of all, create and initial a module.
1mkdir hello && cd hello
1git init
1hugo mod init example.com/vendor/hello
Replace the module path example.com/vendor/hello
as your own, such as github.com/hbstack/hello
, the vendor
is your organization name or username.
example.com/vendor/hello
as the module path in the rest of steps.It’s recommended importing the local module into your HB site for developing.
Firstly, we need to import the local hello module into site’s configuration:
hugo.toml
1[module]
2 [[module.imports]]
3 path = 'example.com/vendor/hello'
hugo.yaml
1module:
2 imports:
3 - path: example.com/vendor/hello
hugo.json
1{
2 "module": {
3 "imports": [
4 {
5 "path": "example.com/vendor/hello"
6 }
7 ]
8 }
9}
And then mapping the module to local path in site’s go.mod
.
1replace example.com/vendor/hello => /path/to/hello
The /path/to/hello
is the file path of the hello module, both of relative path and absolute path are valid.
1hugo server --gc --disableFastRender
Back to the module, create a module configuration file.
hugo.toml
1[module]
2 [[module.imports]]
3 path = 'github.com/hbstack/hb'
hugo.yaml
1module:
2 imports:
3 - path: github.com/hbstack/hb
hugo.json
1{
2 "module": {
3 "imports": [
4 {
5 "path": "github.com/hbstack/hb"
6 }
7 ]
8 }
9}
It declared that the github.com/hbstack/hb
module is required.
It’s time to start implementing the functionalities.
hb-vendor-hello
is used as the HugoPress module name, we suggest naming your module with same pattern hb-vendor-name
, to avoid conflicting with HugoPress modules and HB built-in modules.<html>
and <body>
To add additional HTML attributes by appending the following configuration.
hugo.toml
1[params]
2 [params.hugopress]
3 [params.hugopress.modules]
4 [params.hugopress.modules.hb-vendor-hello]
5 [params.hugopress.modules.hb-vendor-hello.attributes]
6 [params.hugopress.modules.hb-vendor-hello.attributes.body]
7 cacheable = true
8 [params.hugopress.modules.hb-vendor-hello.attributes.document]
9 cacheable = true
hugo.yaml
1params:
2 hugopress:
3 modules:
4 hb-vendor-hello:
5 attributes:
6 body:
7 cacheable: true
8 document:
9 cacheable: true
hugo.json
1{
2 "params": {
3 "hugopress": {
4 "modules": {
5 "hb-vendor-hello": {
6 "attributes": {
7 "body": {
8 "cacheable": true
9 },
10 "document": {
11 "cacheable": true
12 }
13 }
14 }
15 }
16 }
17 }
18}
The cacheable
flag caches the attributes to improve the build performance, disable it if the attributes contain dynamic data.
And then define the additional attributes via partials.
1{{- return dict
2 "data-hello" "document"
3-}}
1{{- return dict
2 "data-hello" "body"
3-}}
If everything is OK, the HTML source code looks like follows:
1<html ... data-hello="document" ...>
2 <body ... data-hello="body" ...>
3 </body>
4</html>
This example uses only a few hooks, all available hooks could be found on our docs and HugoPress’s built-in hooks.
Please note that the context of hook partials is different than regular partial, see hooks context.
<head>
There are two built-in hooks for putting custom stuff on <head>
: head-begin
and head-end
, which used to generate meta tags, include stylesheet and so on.
Append the following configuration to enable it.
hugo.toml
1[params]
2 [params.hugopress]
3 [params.hugopress.modules]
4 [params.hugopress.modules.hb-vendor-hello]
5 [params.hugopress.modules.hb-vendor-hello.hooks]
6 [params.hugopress.modules.hb-vendor-hello.hooks.head-begin]
7 cacheable = true
8 [params.hugopress.modules.hb-vendor-hello.hooks.head-end]
9 cacheable = true
hugo.yaml
1params:
2 hugopress:
3 modules:
4 hb-vendor-hello:
5 hooks:
6 head-begin:
7 cacheable: true
8 head-end:
9 cacheable: true
hugo.json
1{
2 "params": {
3 "hugopress": {
4 "modules": {
5 "hb-vendor-hello": {
6 "hooks": {
7 "head-begin": {
8 "cacheable": true
9 },
10 "head-end": {
11 "cacheable": true
12 }
13 }
14 }
15 }
16 }
17 }
18}
Same as attributes, disable the
cacheable
if the template contains dynamic data.
And then create the corresponding templates.
1<meta name="hello" content="head-begin">
1<meta name="hello" content="head-end">
Now the pages have the following meta tags.
1<head>
2 <meta name="hello" content="head-begin">
3 <meta name="hello" content="head-end">
4</head>
Finally, create greeting messages on the top of pages.
Configuration as following.
hugo.toml
1[params]
2 [params.hugopress]
3 [params.hugopress.modules]
4 [params.hugopress.modules.hb-vendor-hello]
5 [params.hugopress.modules.hb-vendor-hello.hooks]
6 [params.hugopress.modules.hb-vendor-hello.hooks.body-begin]
7 cacheable = true
hugo.yaml
1params:
2 hugopress:
3 modules:
4 hb-vendor-hello:
5 hooks:
6 body-begin:
7 cacheable: true
hugo.json
1{
2 "params": {
3 "hugopress": {
4 "modules": {
5 "hb-vendor-hello": {
6 "hooks": {
7 "body-begin": {
8 "cacheable": true
9 }
10 }
11 }
12 }
13 }
14 }
15}
1<div class="hb-vendor-hello text-center">Hello!</div>
Now the greeting message will be shown on the top of pages.
You may want to beautify the HTML generated by module with styles, let’s take the greeting message as an example that change the background and color.
To make module flexible, we declare parameters for those styles.
hugo.toml
1[params]
2 [params.hb]
3 [params.hb.vendor_hello]
4 bg = 'blue'
5 color = 'white'
hugo.yaml
1params:
2 hb:
3 vendor_hello:
4 bg: blue
5 color: white
hugo.json
1{
2 "params": {
3 "hb": {
4 "vendor_hello": {
5 "bg": "blue",
6 "color": "white"
7 }
8 }
9 }
10}
And then create the SCSS files.
1$hb-vendor-hello-bg: {{ default "blue" .params.hb.vendor_hello.bg }};
2$hb-vendor-hello-color: {{ default "white" .params.hb.vendor_hello.color }};
1/* purgecss start ignore */
2
3.hb-vendor-hello {
4 background: $hb-vendor-hello-bg;
5 color: $hb-vendor-hello-color;
6}
7
8/* purgecss end ignore */
Restart the Hugo server to ensure loading the SCSS files fully.
Finally, let’s modify the greeting message in JS way.
hugo.toml
1[params]
2 [params.hb]
3 [params.hb.vendor_hello]
4 message = 'Hello world!'
hugo.yaml
1params:
2 hb:
3 vendor_hello:
4 message: Hello world!
hugo.json
1{
2 "params": {
3 "hb": {
4 "vendor_hello": {
5 "message": "Hello world!"
6 }
7 }
8 }
9}
1import * as params from '@params'
2
3document.querySelector('.hb-vendor-hello').innerText = params.vendor_hello.message
The styles used by JavaScript will be removed by PurgeCSS, please checkout the PurgeCSS section for details.
The PurgeCSS gets processed on production mode only, we could preview the module on production mode via:
1hugo server -e production --minify --gc --renderToDisk -b http://localhost:1313 -p 1313
Once the module is done, it’s time to publish it by pushing it to your git providers, and then remove the mapping from go.mod
.