Hugo博客Book主题装修小记第二辑。既- 第一辑的功能性定制后,已经用了大半年了。进行一些外观的美化,包括博客logo的绘制,黑暗模式,归档页面等。
增加侧栏底部信息工具栏 #
- 亮暗主题切换;
- 站点信息统计;
- 构建时间信息。
效果如下:
<!-- /themes/hugo-book/layouts/partials/docs/menu-foot.html -->
<script>
(function () {
const THEME_KEY = 'bookTheme';
const theme = localStorage.getItem(THEME_KEY) || 'light';
document.documentElement.setAttribute('data-theme', theme);
})();
</script>
{{- $scratch := newScratch -}}
{{- range (where .Site.RegularPages "Section" "posts") -}}
{{- $scratch.Add "total" .WordCount -}}
{{- end -}}
{{- $siteStart := time "2024-11-23" -}}
{{- $daysAlive := div (sub (now.Unix) $siteStart.Unix) 86400 -}}
{{- $totalWords := $scratch.Get "total" -}}
{{- $totalPosts := len (where .Site.RegularPages "Section" "posts") -}}
<div class="last-build text-small" style="margin-top: auto; padding: 1em 0; text-align: center; opacity: 0.8; line-height: 1.6;">
<div class="theme-toggle text-small" style="text-align: center; margin-bottom: 0.6em;">
<label class="switch-container" title="切换亮暗模式">
<input type="checkbox" id="themeToggleBLabel">
<span class="slider"></span>
</label>
</div>
<div style="margin-bottom: 0.3em;">
站龄 {{ $daysAlive }} 天|文章 {{ $totalPosts }} 篇|累计 {{ $totalWords }} 字
</div>
<div>
<span style="
display: inline-block;
width: 8px;
height: 8px;
background-color: var(--color-link);
border-radius: 50%;
box-shadow: 0 0 4px var(--color-link);
margin-right: 6px;
vertical-align: middle;
"></span>
Last built on: {{ now.Format "2006-01-02 15:04" }}
</div>
</div>
<script>
const THEME_KEY = 'bookTheme';
const toggleBtn = document.getElementById('themeToggleBLabel');
if (toggleBtn) {
toggleBtn.addEventListener('click', () => {
const currentTheme = localStorage.getItem(THEME_KEY) || 'light';
const newTheme = currentTheme === 'light' ? 'dark' : 'light';
document.body.setAttribute('data-theme', newTheme);
localStorage.setItem(THEME_KEY, newTheme);
});
const savedTheme = localStorage.getItem(THEME_KEY);
if (savedTheme) {
document.body.setAttribute('data-theme', savedTheme);
}
}
</script>
修改menu.html
<!-- /themes/hugo-book/layouts/partials/docs/menu.html -->
<nav>
<div>
{{ partial "docs/brand" . }}
{{ partial "docs/search" . }}
{{ if hugo.IsMultilingual }}
{{ partial "docs/languages" . }}
{{ end }}
{{ partial "docs/inject/menu-before" . }}
{{ partial "docs/menu-hugo" .Site.Menus.before }}
{{ partial "docs/menu-filetree" . }}
{{ partial "docs/menu-hugo" .Site.Menus.after }}
{{ partial "docs/inject/menu-after" . }}
</div>
{{ partial "docs/menu-foot" . }}
</nav>
<!-- Restore menu position as soon as possible to avoid flickering -->
{{ $script := resources.Get "menu-reset.js" | resources.Minify }}
{{ with $script.Content }}
<script>{{ . | safeJS }}</script>
{{ end }}
// /themes/hugo-book/assets/_custom.scss
:root {
@include theme-light;
}
body[data-theme='dark'] {
@include theme-dark;
}
.book-logo {
color: var(--color-link);
}
Logo的替换与颜色自适应 #
自制了新的网站logo,颜色与亮/暗色主题一致切换,效果如下:
<!-- /themes/hugo-book/layouts/partials/docs/brand.html -->
<h2 class="book-brand">
<a class="brand-link" href="{{ cond (not .Site.Home.File) .Sites.Default.Home.RelPermalink .Site.Home.RelPermalink }}">
{{- with .Site.Params.BookLogo -}}
<svg class="book-logo" fill="currentColor" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 128 128" version="1.1">
<g id="surface1">
<path style=" stroke:none;fill-rule:evenodd;fill-opacity:1;" d="M 76.304688 45.84375 C 79.792969 46.046875 83.488281 49.089844 84.144531 49.664062 C 85.019531 50.429688 79.097656 58.5 80.996094 72.207031 C 82.898438 85.914062 89.453125 102.679688 78.769531 102.546875 C 76.0625 81.359375 59.328125 69.835938 60.203125 67.882812 C 61.078125 65.925781 69.011719 49.816406 73.003906 46.78125 C 74 46.023438 75.140625 45.773438 76.304688 45.84375 Z M 79.21875 25.652344 C 81.410156 25.503906 87.265625 32.222656 87.414062 34.332031 C 87.5625 36.441406 82.304688 38.160156 80.113281 38.308594 C 77.921875 38.457031 74.390625 37.242188 74.269531 35.226562 C 74.148438 33.210938 77.027344 25.800781 79.21875 25.652344 Z M 62.457031 19.570312 C 65.054688 19.636719 68.527344 20.394531 69.289062 21.421875 C 70.511719 23.066406 68.429688 30.304688 66.84375 30.160156 C 65.257812 30.011719 59.097656 21.742188 59.503906 20.285156 C 59.65625 19.738281 60.898438 19.53125 62.457031 19.570312 Z M 58.449219 10.179688 C 56.746094 10.121094 55.0625 10.136719 53.417969 10.226562 C 45.527344 10.652344 38.558594 12.789062 34.667969 16.753906 C 33.390625 21.117188 51.546875 20.578125 56.792969 35.339844 C 62.8125 38.214844 63.792969 39.644531 63.566406 44.226562 C 63.277344 49.726562 48.167969 57.527344 51.511719 66.898438 C 55.246094 76.664062 46.550781 83.238281 44.125 91.976562 C 37.464844 111.089844 48.84375 120 56.6875 120.503906 C 58.105469 113.839844 51.183594 107.832031 51.902344 103.597656 C 52.492188 101.191406 55.355469 108.3125 58.847656 104.777344 C 60.640625 99.796875 51.554688 93.679688 51.378906 90.359375 C 51.859375 87.824219 58 97.128906 61.078125 93.898438 C 62.5625 90.46875 54.109375 81.375 58.3125 81.453125 C 61.019531 81.539062 63.816406 84.519531 68.679688 96.125 C 71.222656 102.273438 73.949219 110.855469 70.59375 120.210938 C 83.097656 118.972656 89.15625 111.199219 92.238281 101.449219 C 95.316406 91.699219 83.128906 73.234375 89.066406 61.707031 C 95 50.175781 103.980469 34.953125 90.632812 21.785156 C 83.335938 14.582031 70.386719 10.589844 58.449219 10.179688 Z M 64 0 C 99.347656 0 128 28.652344 128 64 C 128 99.347656 99.347656 128 64 128 C 28.652344 128 0 99.347656 0 64 C 0 28.652344 28.652344 0 64 0 Z M 64 0 "/>
</g>
</svg>
{{- end -}}
<span class="brand-text">{{ .Site.Title }}</span>
</a>
</h2>
// /themes/hugo-book/assets/_fonts.scss
.book-logo {
color: var(--color-link);
}
文章元数据彩色标签 #
输出高、低两种饱和度颜色,分别在亮、暗色主题中使用,自动切换。效果如下:
<!-- /themes/hugo-book/layouts/partials/docs/post-meta.html -->
<div class="flex justify-between align-center">
{{ range $taxonomy, $_ := .Site.Taxonomies }}
{{ with $terms := $.GetTerms $taxonomy }}
<div>
{{ range $term := $terms }}
{{ $tagColor := substr (md5 $term.Title) 0 6 }}
<div class="tag" style="--tag-color-light: #{{ $tagColor }}33; --tag-color-dark: #{{ $tagColor }}aa;">
<a href="{{ $term.RelPermalink }}">{{ $term.Title }}</a>
</div>
{{ end }}
</div>
{{ end }}
{{ end }}
{{ with .Date }}
<div class="flex align-center text-small book-post-date">
<span>{{ partial "docs/date" (dict "Date" . "Format" $.Site.Params.BookDateFormat) }}</span>
</div>
{{ end }}
</div>
// /themes/hugo-book/assets/_custom.scss
.tag {
display: inline;
padding: 0 $padding-4;
border-radius: 2px;
font-size: 0.75em;
background:var(--tag-color-light);
color: var(--body-font-color);
margin-left: 2px;
}
body[data-theme="dark"] .tag {
background: var(--tag-color-dark);
}
移除字体包 #
检查加载项时,发现hugo-book主题用了Roboto字体包,依赖外部资源。移除以加快访问速度,同时设置了一系列的备选字体,若用户端存在,则自动选用。
// /themes/hugo-book/assets/_fonts.scss 删减为以下内容
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
}
code {
font-family: ui-monospace, SFMono-Regular, Consolas, "Liberation Mono", Menlo, monospace;
}
静态资源托管 #
Twikoo的默认表情CDN为https://owo.imaegoo.com/owo.json
,似乎国内访问不太顺畅。想着作为静态资源放在本站内可能会更快一点?手动下载owo.json
至/themes/hugo-book/static/
文件夹内,在Twikoo的后台管理页面,配置管理
- 插件
- EMOTION_CDN
中填入https://osnsyc.top/owo.json
。还可以在owo.json
中编辑自定义表情。
{
"颜文字": {
"type": "emoticon",
"container": [
{ "icon": "OωO", "text": "Author: DIYgod" },
{ "icon": "|´・ω・)ノ", "text": "Hi" },
{ "icon": "ヾ(≧∇≦*)ゝ", "text": "开心" },
{ "icon": "(☆ω☆)", "text": "星星眼" },
{ "icon": "(╯‵□′)╯︵┴─┴", "text": "掀桌" },
{ "icon": " ̄﹃ ̄", "text": "流口水" },
{ "icon": "(/ω\)", "text": "捂脸" },
{ "icon": "∠( ᐛ 」∠)_", "text": "给跪" },
{ "icon": "(๑•̀ㅁ•́ฅ)", "text": "Hi" },
{ "icon": "→_→", "text": "斜眼" },
{ "icon": "୧(๑•̀⌄•́๑)૭", "text": "加油" },
{ "icon": "٩(ˊᗜˋ*)و", "text": "有木有WiFi" },
{ "icon": "(ノ°ο°)ノ", "text": "前方高能预警" },
{ "icon": "(´இ皿இ`)", "text": "我从未见过如此厚颜无耻之人" },
{ "icon": "⌇●﹏●⌇", "text": "吓死宝宝惹" },
{ "icon": "(ฅ´ω`ฅ)", "text": "已阅留爪" },
{ "icon": "(╯°A°)╯︵○○○", "text": "去吧大师球" },
{ "icon": "φ( ̄∇ ̄o)", "text": "太萌惹" },
{ "icon": "ヾ(´・ ・`。)ノ\"", "text": "咦咦咦" },
{ "icon": "( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃", "text": "气呼呼" },
{ "icon": "(ó﹏ò。)", "text": "我受到了惊吓" },
{ "icon": "Σ(っ °Д °;)っ", "text": "什么鬼" },
{ "icon": "( ,,´・ω・)ノ\"(´っω・`。)", "text": "摸摸头" },
{ "icon": "╮(╯▽╰)╭ ", "text": "无奈" },
{ "icon": "o(*////▽////*)q ", "text": "脸红" },
{ "icon": ">﹏<", "text": "" },
{ "icon": "( ๑´•ω•) \"(ㆆᴗㆆ)", "text": "" }
]
},
"Emoji": {
"type": "emoji",
"container": [
{ "icon": "😂", "text": "" },
{ "icon": "😀", "text": "" },
{ "icon": "😅", "text": "" },
{ "icon": "😊", "text": "" },
{ "icon": "🙂", "text": "" },
{ "icon": "🙃", "text": "" },
{ "icon": "😌", "text": "" },
{ "icon": "😍", "text": "" },
{ "icon": "😘 ", "text": "" },
{ "icon": "😜", "text": "" },
{ "icon": "😝", "text": "" },
{ "icon": "😏", "text": "" },
{ "icon": "😒", "text": "" },
{ "icon": "🙄", "text": "" },
{ "icon": "😳 ", "text": "" },
{ "icon": "😡", "text": "" },
{ "icon": "😔", "text": "" },
{ "icon": "😫", "text": "" },
{ "icon": "😱", "text": "" },
{ "icon": "😭", "text": "" },
{ "icon": "💩", "text": "" },
{ "icon": "👻", "text": "" },
{ "icon": "🙌", "text": "" },
{ "icon": "🖕", "text": "" },
{ "icon": "👍", "text": "" },
{ "icon": "👫", "text": "" },
{ "icon": "👬", "text": "" },
{ "icon": "👭", "text": "" },
{ "icon": "🌚", "text": "" },
{ "icon": "🌝", "text": "" },
{ "icon": "🙈", "text": "" },
{ "icon": "💊", "text": "" },
{ "icon": "😶", "text": "" },
{ "icon": "🙏", "text": "" },
{ "icon": "🍦", "text": "" },
{ "icon": "🍉", "text": "" },
{ "icon": "😣", "text": "" }
]
}
}
同理,把twikoo.min.js
也放在站内,试试效果。
<!-- /themes/hugo-book/layouts/partials/docs/comments.html -->
<script src="https://osnsyc.top/twikoo.min.js"></script>
博文列表的重置 #
hugo-book主题的默认post list比较丑,重新调整了一下样式:标题缩小、摘要缩小、添加彩色标签、增加边距。
<!-- 以下两条皆改为此样式 -->
<!-- /themes/hugo-book/layouts/posts/list.html -->
<!-- themes/hugo-book/layouts/taxonomy/taxonomy.html -->
{{ define "main" }}
{{ range sort .Paginator.Pages }}
<article class="markdown book-post-list">
<div class="book-post-list-title">
<a href="{{ .RelPermalink }}">{{ partial "docs/title.html" . }}</a>
</div>
{{ partial "docs/post-meta" . }}
<div class="book-post-list-content">
{{- .Summary | truncate 100 -}}
<br>
<a href="{{ .RelPermalink }}">
阅读全文
<svg class="read-more-icon" width="24" height="24" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M36 7L43 13.4615L36 21" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="miter"/><path d="M40 14H17.0062C10.1232 14 4.27787 19.6204 4.00964 26.5C3.72612 33.7696 9.73291 40 17.0062 40H34.0016" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="miter"/></svg>
</a>
</div>
</article>
{{ end }}
{{ template "_internal/pagination.html" . }}
{{ end }}
{{ define "toc" }}
{{ partial "docs/taxonomy" . }}
{{ end }}
// /themes/hugo-book/assets/_custom.scss
.book-post-list {
margin: 0 $padding-8 $padding-24;
&:hover {
transform: scale(1.02);
}
.book-post-list-title a {
font-size: 1.2em !important;
font-weight: bold !important;
color: var(--body-font-color) !important;
&:visited {
color: var(--gray-1000) !important;
}
}
.book-post-list-content{
font-size: $font-size-14;
margin-top: $padding-4;
}
.read-more-icon {
height: $font-size-14;
width: $font-size-14;
margin-left: 0.3em;
}
}
归档页面 #
在post list页面,每页只列10条博文,博文数量多了后查阅不太方便。新增一个归档archive模块,只列出年份、标题、日期,50条后自动分页。效果如下:
新建 /content/archives/_index.md
---
title: 归档 | Archives
BookComments: False
weight: 10
---
## 显示在第一页的内容
# hugo.toml
[menu]
[[menu.after]]
name = "归档 | Archives"
pageRef = '/archives'
weight = 10
<!-- 新建 /themes/hugo-book/layouts/archives/list.html -->
{{ define "main" }}
<article class="markdown book-article">
<div class="book-archive-list">
{{ $posts := where .Site.RegularPages "Type" "posts" }}
{{ $paginator := .Paginate ($posts.ByDate.Reverse) 50 }}
{{ if eq $paginator.PageNumber 1 }}
{{ .Content }}
{{ end }}
{{ $currentYear := "" }}
{{ range $paginator.Pages }}
{{ $year := .Date.Year }}
{{ if ne $year $currentYear }}
{{ if not (eq $currentYear "") }}
</ul>
{{ end }}
<h3>{{ $year }}</h3>
<ul>
{{ $currentYear = $year }}
{{ end }}
<li>
<div class="book-archive-item">
<a href="{{ .RelPermalink }}">{{ .Title }}</a>
<span class="book-archive-date">{{ .Date.Format "2006-01-02" }}</span>
</div>
</li>
{{ end }}
</ul>
</div>
</article>
{{ template "_internal/pagination.html" . }}
{{ end }}
{{ define "toc" }}
{{ partial "docs/taxonomy" . }}
{{ end }}
// /themes/hugo-book/assets/_custom.scss
.book-archive-list {
margin: 0 $padding-8 $padding-24;
.book-archive-item {
display: flex;
justify-content: space-between;
align-items: baseline;
}
.book-archive-date {
font-size: $font-size-14;
color: var(--gray-1000);
white-space: nowrap;
}
}
修改RSS输出 #
- 修改频道
description
; - 在摘要中增加图片,在阅读器中更为美观。图片默认抓取frontmatter中的
banner
值,若banner
不存在则抓取正文中的第一张图片;
修改模板如下,在Folo中的预览效果如下:
<!-- //themes/hugo-book/layouts/_default/rss.xml -->
{{- $authorEmail := "" }}
{{- with site.Params.author }}
{{- if reflect.IsMap . }}
{{- with .email }}
{{- $authorEmail = . }}
{{- end }}
{{- end }}
{{- end }}
{{- $authorName := "" }}
{{- with site.Params.author }}
{{- if reflect.IsMap . }}
{{- with .name }}
{{- $authorName = . }}
{{- end }}
{{- else }}
{{- $authorName = . }}
{{- end }}
{{- end }}
{{- $pctx := . }}
{{- if .IsHome }}{{ $pctx = .Site }}{{ end }}
{{- $pages := slice }}
{{- if or $.IsHome $.IsSection }}
{{- $pages = $pctx.RegularPages }}
{{- else }}
{{- $pages = $pctx.Pages }}
{{- end }}
{{- $limit := .Site.Config.Services.RSS.Limit }}
{{- if ge $limit 1 }}
{{- $pages = $pages | first $limit }}
{{- end }}
{{- printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }}
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>{{ if eq .Title .Site.Title }}{{ .Site.Title }}{{ else }}{{ with .Title }}{{ . }} on {{ end }}{{ .Site.Title }}{{ end }}</title>
<link>{{ .Permalink }}</link>
<description>凉糕 | 自然学徒, 深海探客</description><!-- <description>Recent content {{ if ne .Title .Site.Title }}{{ with .Title }}in {{ . }} {{ end }}{{ end }}on {{ .Site.Title }}</description> -->
<generator>Hugo</generator>
<language>{{ site.Language.LanguageCode }}</language>{{ if not .Date.IsZero }}
<lastBuildDate>{{ (index $pages.ByLastmod.Reverse 0).Lastmod.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</lastBuildDate>{{ end }}
{{- range $pages }}
<item>
<title>{{ .Title }}</title>
<link>{{ .Permalink }}</link>
<pubDate>{{ .PublishDate.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
{{- with $authorEmail }}<author>{{ . }}{{ with $authorName }} ({{ . }}){{ end }}</author>{{ end }}
<guid>{{ .Permalink }}</guid>
<description>{{ .Summary | transform.XMLEscape | safeHTML }}
{{- if .Params.banner -}}
{{ printf `<![CDATA[<img src="%s" alt="%s" />]]>` (.Params.banner | absURL) .Title | safeHTML }}
{{- else -}}
{{- $firstImage := findRE `<img[^>]+src="([^">]+)"` .Content 1 -}}
{{- if $firstImage -}}
{{- $imageSrc := index (findRE `src="([^">]+)"` (index $firstImage 0)) 0 | replaceRE `src="([^">]+)"` "$1" -}}
{{ printf `<![CDATA[<img src="%s" alt="%s" />]]>` ($imageSrc | absURL) .Title | safeHTML }}
{{- end -}}
{{- end -}}
</description>
</item>
{{- end }}
</channel>
</rss>
增加视频短代码 #
视频短代码,效果如下:
/* /themes/hugo-book/assets/_custom.scss */
/* video ------- */
.video-container {
max-width: $card-width !important;
margin: 1em auto;
position: relative;
display: flex;
}
/* video --- end */
<!-- /themes/hugo-book/layouts/shortcodes/video.html -->
{{- $src := .Get "src" -}}
{{- $title := .Get "title" -}}
{{- $description := .Get "description" -}}
{{- $width := .Get "width" | default "100%" -}}
<div class="video-container">
<video width="{{ $width }}" controls>
<source src="{{ $src }}" type="video/mp4">
Your browser does not support the video tag.
</video>
</div>
使用方法:
{{< video src="https://img.osnsyc.top/OrpheusBannerV3.mp4">}}