模块指南

想要创建和分享你的创意 HB 模块吗?这里有你想要知道的一切。

示例功能

源码

让我们从 hello 示例开始,其:

  • <html><body> 上追加属性。
  • 使用钩子以添加自定义 HTML 标记,如元标记、CSS 和 JS。
  • 于页面显示问候信息,并使用 SCSS、TypeScript 修改其样式和文本。

准备工作

  • 一个用于模块测试的 HB 站点,如果还没有,可以使用入门主题
  • 熟悉雨果开发。
  • 已安装好构建工具

初始化模块

首先,创建并初始化一个模块。

1mkdir hello && cd hello
1git init
1hugo mod init example.com/vendor/hello

请将模块路径 example.com/vendor/hello 替换成你的,比如 github.com/hbstack/hello,其中 vendor 为组织名称或你的用户名。

设置 HB 站点

推荐于 HB 站点导入本地模块,以方便开发和调试。

导入本地模块

首先,我们需要导入本地模块到 HB 站点。

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}

然后于 go.mod 中将其映射到本地路径。

1replace example.com/vendor/hello => /path/to/hello

其中 /path/to/hello 为模块的路径,相对路径和绝对路径都是有效的。

启动测试站点

1hugo server --gc --disableFastRender

模块配置文件

回到模块,创建以下模块配置文件。

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}

其声明了 github.com/hbstack/hb 模块是必须的。

现在是时候开始实现功能了。

<html><body> 上追加属性

追加以下配置以添加额外的 HTML 属性。

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}

其中 cacheable 表明属性是否可缓存,若属性值包含动态内容,则禁用。

然后通过模板定义额外的属性。

若无意外,HTML 源代码如下所示:

1<html ... data-hello="document" ...>
2  <body ... data-hello="body" ...>
3  </body>
4</html>

使用钩子

本例子只使用了若干个钩子,所有可用的钩子可从文档和 HugoPress’s 内置钩子中找到。

请注意,钩子模板的上下文不同于常规模板,详情请参阅 hooks context

<head> 上生成内容

有两个内置的钩子可用于在 <head> 内放置自定义内容:head-beginhead-end,通常用于生成元标记、导入样式等。

追加以下配置以启用。

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}

同属性,若模板包含动态内容,则禁用 cacheable

然后创建对应的模板:

现在页面将包含以下元标记。

1<head>
2  <meta name="hello" content="head-begin">
3  <meta name="hello" content="head-end">
4</head>

显示问候语

最后,于页面顶部显示一则问候语。

配置如下:

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}
layouts/partials/hugopress/modules/hb-vendor-hello/hooks/body-begin.html
1<div class="hb-vendor-hello text-center">Hello!</div>

如无意外,该问候语将显示与页面顶部。

添加样式

你也许希望添加样式以美化页面,以问候语为例,我们修改其背景色和颜色。

为了实现模块的灵活性,我们定义了以下参数。

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}

接着创建以下 SCSS 文件。

assets/hb/modules/vendor-hello/scss/variables.tmpl.scss
1$hb-vendor-hello-bg: {{ default "blue" .params.hb.vendor_hello.bg }};
2$hb-vendor-hello-color: {{ default "white" .params.hb.vendor_hello.color }};
assets/hb/modules/vendor-hello/scss/index.scss
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 */

重启 Hugo 服务器以确保完全加载 SCSS 文件。

添加脚本

最后,让我们利用 JS 修改问候语。

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}
assets/hb/modules/vendor-hello/js/index.ts
1import * as params from '@params'
2
3document.querySelector('.hb-vendor-hello').innerText = params.vendor_hello.message

于生产模式下测试

脚本使用到的样式会被 PurgeCSS 移除,详情请参阅 PurgeCSS

PurgeCSS 只有在生产模式下生效,我们可以通过以下命令于生产模式预览模块。

1hugo server -e production --minify --gc --renderToDisk -b http://localhost:1313 -p 1313

发布

当模块完成后,是时候通过推送到远程仓库以发布模块了,然后将映射关系从 go.mod 中移除。