Hugo有不少优秀的主题,学术类academic的可以参考https://github.com/Chen-Gary/hugo-theme-academic-old
。关于安装和配置academic
学术主题,可以参考其README文档。本文介绍如何进行更高阶hugo配置及定制。看完本篇博客,能够对hugo有更深的了解并可以完成一些定制化:
- 调整文章模板
- 个性化 - 集成看板娘
- 个性化 - 支持文章嵌入B站视频
- 国际化 & CJK
文章模板
一般情况下我们创建新文章有两种办法,一种直接拷贝原有文件目录然后进行更改,另一种可以使用hugo new
命令,如可以使用hugo new content post/{post-path}/index.md
来创建文章
(academic
学术主题的文章目录在content/post
,其他一些主题文章目录可能在content/posts
)。该命令会按如下顺序寻找模板进行内容生成:
archetypes/post.md
archetypes/default.md
themes/academic/archetypes/post.md
themes/academic/archetypes/default.md
在使用hugo new site {blog-path}
创建博客站点时,默认生成的目录包含archetypes/default.md
文件,
其内容如下
+++
title = '{{ replace .File.ContentBaseName "-" " " | title }}'
date = {{ .Date }}
draft = true
+++
该文件内容为hugo Front matter,为toml
格式。我们使用命令hugo new content post/test/index.md
进行测试,可以看到生成的文章内容如下:
+++
title = 'Test'
date = 2023-11-22T23:53:32+08:00
draft = true
+++
将archetypes/default.md
及content/post/test/index.md
移除,再次运行命令hugo new content post/test/index.md
,可以看到新生成的文章文件内容:
---
# Documentation: https://sourcethemes.com/academic/docs/managing-content/
title: "Test"
subtitle: ""
summary: ""
authors: []
tags: []
categories: []
date: 2023-11-22T23:58:38+08:00
lastmod: 2023-11-22T23:58:38+08:00
featured: false
draft: false
# Featured image
# To use, add an image named `featured.jpg/png` to your page's folder.
# Focal points: Smart, Center, TopLeft, Top, TopRight, Left, Right, BottomLeft, Bottom, BottomRight.
image:
caption: ""
focal_point: ""
preview_only: false
# Projects (optional).
# Associate this post with one or more of your projects.
# Simply enter your project's folder or file name without extension.
# E.g. `projects = ["internal-project"]` references `content/project/deep-learning/index.md`.
# Otherwise, set `projects = []`.
projects: []
---
这样我们就可以快速对Front matter内容进行定制化。
academic
主题还支持各种文章模板,如docs.md
、publication
等,可以在目录themes/academic/archetypes
中找到。比如新建课程Courses,可以使用命令hugo new content --kind docs courses/linux-programming/_index.md
,该命令应用themes/academic/archetypes/docs.md
布局,
本地可以浏览http://localhost:1313/courses/
查看效果。
个性化 - 集成看板娘
本章节通过集成看板娘,来演示如何定制主题(虽然我们使用的是academic
学术主题,但是二次元谁不爱呢)。
模板基础结构
首先,想要定制化主题,需要对hugo主题的结构有初步了解,academic
主题结构在目录themes/academic/layouts
中,
themes/academic/layouts
├── _default
│ └── _markup
├── authors
├── book
├── docs
├── partials
│ ├── comments
│ ├── functions
│ ├── jsonld
│ ├── marketing
│ └── widgets
├── project
├── publication
├── section
├── shortcodes
├── slides
├── talk
└── widget_page
关于站点内容,大致可以分为列表页及详情页,列表页如课程列表页/courses/
,详情页则是单页面/courses/example/
。themes/academic/layouts/_default/
目录是模板入口,其中
baseof.html
为站点大的框架,包含完整的HTML, 其中通过go html模板语法加载其他页面组件,组成最终的页面list.html
为列表页single.html
为详情页
list.html
及single.html
中均会通过define "main"
声明页面主体,然后在baseof.html
中通过代码{{ block "main" . }}{{ end }}
被引用。
当然我们看到layout
目录中有着非常多的内容,hugo会根据站点内容目录结构及Front matter中定义的类型等,加载不同的布局。如前述的courses目录,content/courses/example/_index.md
中定义了type: docs
,
则会应用themes/academic/layouts/docs
目录下的布局。该部分的细节加载机制及优先级等,
较为复杂,感兴趣的可以参考官方文档https://gohugo.io/templates/lookup-order/
。
添加看板娘
通过baseof.html
中的代码,我们可以看到站点HTML中的header
部分引用自{{ partial "site_head" . }}
。一般主题都留有给用户定制化的能力,academic
也不例外,通过创建custom_head.html
,我们可以在不改动模板的情况下进行扩展。其引用关系如下:
┌─────────────────────────────────────┐
│ │
│ _default/baseof.html │
│ │
└──────────────────┬──────────────────┘
│
│ {{ partial "site_head" . }}
│
┌──────────────────▼──────────────────┐
│ │
│ partials/site_head.html │
│ │
└──────────────────┬──────────────────┘
│
│ {{ partial "custom_head" . }}
│
┌──────────────────▼──────────────────┐
│ │
│ partials/custom_head.html │
│ │
└─────────────────────────────────────┘
参考themes/academic/layouts/partials/custom_head.html
中的注释,我们在站点根目录下创建文件layouts/partials/custom_head.html
,来覆盖加载主题默认的custom_head.html
文件,
并在其填入内容:
<link rel="stylesheet" href="https://fastly.jsdelivr.net/gh/stevenjoezhang/live2d-widget@latest/waifu.css">
<script src="https://fastly.jsdelivr.net/gh/stevenjoezhang/live2d-widget@latest/live2d.min.js"></script>
<script src="https://fastly.jsdelivr.net/gh/stevenjoezhang/live2d-widget@latest/waifu-tips.js"></script>
<script>
window.addEventListener('load', () => {
// https://fastly.jsdelivr.net/gh/fghrsh/live2d_api/model_list.json
localStorage.setItem("modelId", 2); // 2 -> "bilibili-live/22"
initWidget({
waifuPath: "https://fastly.jsdelivr.net/gh/stevenjoezhang/live2d-widget@latest/waifu-tips.json",
cdnPath: "https://fastly.jsdelivr.net/gh/fghrsh/live2d_api/",
tools: ["hitokoto", "asteroids", "switch-model", "switch-texture", "photo", "info", "quit"]
});
})
</script>
该代码会加载看板娘的样式和模型,并执行相关的初始化代码。最终我们可以在左下角看到bilibili看板娘, 效果如下:
看板娘来源于日语かんばんむすめ,指店铺的女性服务生、活招牌。以上示例代码参考自https://github.com/stevenjoezhang/live2d-widget , License为GPL-3.0 license 。模型
cdnPath
参数源自https://github.com/fghrsh/live2d_api/tree/master , 模型版权归属于原作者。
个性化 - 支持文章嵌入B站视频
Markdown可以引入原始HTML进行渲染,这样我们就可以在站点通过内嵌HTML的方式引入B站视频。以https://www.bilibili.com/video/BV1kE41147oo 视频为例,打开视频后在视频下方我们可以找到分享菜单,可以找到其嵌入代码部分
点击后可以复制嵌入的代码,如下:
<iframe src="//player.bilibili.com/player.html?aid=93495162&bvid=BV1kE41147oo&cid=159633574&p=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"> </iframe>
当然如果我们要更高效完成相关工作,可以使用hugo提供的shortcode
功能。hugo本身提供部分内置shortcode
,如figure
, gist
等。本节我们通过创建bilibili
shortcode
来实现快速嵌入B站视频的能力。
我们在站点根目录下创建文件layouts/shortcodes/bilibili.html
,填入如下内容:
{{- $vid := .Get "id" | default (.Get 0) -}}
{{ $q := "" }}
{{ if strings.HasPrefix (lower $vid) "bv" }}
{{ $q = querify "bvid" $vid }}
{{ else }}
{{ $q = querify "aid" $vid }}
{{ end }}
<iframe style="width: 100%; aspect-ratio: 16 / 9;"
src="//player.bilibili.com/player.html?{{ $q | safeURL }}&p=1"
scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true">
</iframe>
以上代码会根据传入的视频id
参数,生成嵌入的B站视频链接,同时通过CSS设置视频宽度为100%,宽高比为16:9。
然后我们就可以在Markdown中使用bilibili
shortcode
了。首先我们打开我们要嵌入的视频,
找到视频URL链接中video/
之后的BV
开头的视频ID,如链接https://www.bilibili.com/video/BV1kE41147oo/
中的BV1kE41147oo
,然后在文章中嵌入代码{{< bilibili BV1kE41147oo >}}
。效果如下:
更多关于shortcode
的用法,可以参考hugo官方文档https://gohugo.io/content-management/shortcodes/
。
国际化 & CJK
作为一个优秀的主题,academic
是支持国际化配置的。如果你的站点受众包括国内外的用户,可以通过国际化配置使站点支持语音切换。
国际化的配置在config/_default/languages.toml
文件中,默认只有英文配置。在配置文件中添加如下代码
[zh]
languageCode = "zh-Hans"
contentDir = "content/zh"
title = "学术"
[zh.params]
description = "测试中文站点"
[[zh.menu.main]]
name = "示例"
url = "#hero"
weight = 10
[[zh.menu.main]]
name = "文章"
url = "#posts"
weight = 20
[[zh.menu.main]]
name = "项目"
url = "#projects"
weight = 30
[[zh.menu.main]]
name = "出版物"
url = "#featured"
weight = 40
[[zh.menu.main]]
name = "课程"
url = "courses/"
weight = 50
[[zh.menu.main]]
name = "联系"
url = "#contact"
weight = 60
同时在content
目录下创建zh
目录,将原有的content
目录下的内容复制到zh
目录下。这时我们就可以在站点右上角看到语言切换菜单。
调整zh
目录下同个对应文章的内容后,我们就可以看到站点的语言切换效果了。切换至中文后,
可以看到菜单也对应变成中文。
hugo是用go语言编写的,其使用markdown库为goldmark 。 markdown在渲染时默认会将换行渲染为空格,在使用中日韩即CJK语言时,渲染后有些文字中间会有空格, 如下:
我们可以使用goldmark提供的CJK扩展来配置CJK渲染逻辑。配置文件在config/_default/config.toml
,
找到该段:
[markup]
defaultMarkdownHandler = "goldmark"
[markup.goldmark]
[markup.goldmark.renderer]
unsafe = true # Enable user to embed HTML snippets in Markdown content.
在其下面添加如下代码:
[markup.goldmark.extensions.cjk]
enable = true
eastAsianLineBreaks = true
escapedSpace = true
保存后可以观察效果。