在上次搭建好的毛坯基础上,做点简单的小装饰,尽量满足自己的一些小需求,文章中的代码均是来源网络,自己结合 GPT 做了部分调整,在满足功能的同时尽量保持美观。
一. 时间轴
想把今年看的书来做一个记录,平时自己是用苹果自带的图书,下载好书籍导入到图书中进行阅读。阅读完图书后,苹果有一个已读完的菜单,用的是时间轴来记录已读书籍的情况。自己对于这种展示方式比较喜欢,所以就在网上找到了这个。作者原先是用这个来做简历的展示,时间轴表示每份工作的时长,主体部分就是描述工作内容相关的。同理,我可以把它用到记录阅读书籍上,时间轴表示每本书阅读的一个时长,主题部分可以写读后感、相关书籍链接等。
具体步骤
直接参考项目给出的步骤,一步一步执行,全程都很顺利,没有遇到任何问题。
二. 用户评论
目前使用的主题是自带 Disqus 插件的,需要自己注册一个 Disqus 账号,使用免费的服务就可以了。注册号账号后,将网站和你的 Disqus 站点名称做一个绑定,把站点名称填写到 Hugo 项目的配置文件里,整个过程也是很顺利。不过后面在使用时发现一个问题,Disqus 相关域名已经被 GFW 屏蔽了,导致文章下面的 Disqus 评论模块一直加载不出来,访问加载页面时体验不太好。后
三. 朋友圈
一开始自己玩 Halo 时,很喜欢其中一个功能,叫做瞬间。这个其实就是类似朋友圈这种,发布个简单的动态。自己想在现有的模块里,新增一个类似的功能模块。在 Hugo 里面一个 MD 就是一篇文章,没有办法直接实现。自己在网上找了三个相关链接,分别都折腾了一会,链接1折腾成功了,链接2和链接3都以失败告终,主要是自己实力不够😂。链接1自己是单独用一个项目来运行的,虽然运行成功,但是没有结合到现有的主题里面, 只能通过网址跳转达到目的,不够优雅故最终还是放弃。链接2我看了作者的网站,实现效果很好,页面也很美观,但是开源的项目说明文档太少,自己很多地方看不太懂,本来想邮件咨询下作者,想着还是怕麻烦,第二个也放弃了。链接3其实是自己最看好的,作者就是在原来的主题里,自己写了几段代码,定义页面样式、动态文章合并,在原有的主题里就嵌入了这个功能。自己感觉很优雅,作者的网站自己也看了,效果也十分不错。无奈自己代码能力太差,和作者不是同一个主题,在现有自己用的主题上,自己没有移植成功。如果有类似 shortcodes 这样,已经设计好了的,直接调用这个模块,自己只要专注内容编写,就能达到效果就好了。
链接1: zhejian1111/hugo-theme-rand-thoughts: 自己制作的Hugo朋友圈主题
链接2: happyet/hugo-theme-quan: 微信朋友圈 Hugo 主题。
链接3: Hugo 添加瞬间页 | Tofuwine’s Blog
四. Umami
Umami 是一种免费的开源网站分析工具,专为隐私保护而设计。给博客添加这个主要是方便查看数据,虽然也没几个人看😂。Umami 数据展示既美观又直观,看过的应该都会喜欢吧,而且还是开源的,很适合个人来折腾。
具体步骤
找到用于字数统计的短代码,也就是 shortcodes,感兴趣可以去 Github 搜一下,有挺多好玩的短代码。本次要实现的这个功能用的是下面这一段。
创建一个 Vercel 账户,同时把 Umami 的项目 Fork 到你自己的仓库里,为接下来在 Vercel 部署项目做好准备。
在 Vercel 中选择 Storage 菜单,然后创建数据库,选择 Neon 创建 Postgres 数据库。进入到刚刚创建的数据库里,在 Quickstart 中找到 DATABASE_URL,将它的名称和值都复制保存下。在 Vercel 中选择 Overview 菜单, 然后添加新项目,选择之前 Fork 的 Umami 项目进行部署,这里添加一个变量,变量名称就是刚刚我们复制的 DATABASE_URL, 值就是它对应的值。点击部署大概3分钟不到就会成功。
点击项目对应的网址进行访问,默认账号为 admin,密码为 umami。添加自己的网站,同时将对应的跟踪代码复制保存,下面是自己部署好的。
<script defer src="https://neweix.buzz/script.js" data-website-id="311bdb09-1bf5-45c5-9921-7b7aa72a834d"></script>
将上面的的跟踪代码粘贴到 Hugo 的 head 标签里面,针对我用的主题位置是 mainroad/layouts/_default 下面的 baseof.html,其他主题可以找找 主题/layouts/partials/head.html 这个文件添加进去。 为了方便查看数据,你可以在 Umami 后台设置一个无需登录就可查看数据的公共链接,我把这个链接放在博客最底下版权那里,就是有个小计数板的图标,这样方便自己没事看看。
Tip
由于 Vercel 部署的项目默认访问地址是 xxx.vercel.app,这个是被墙了的,所以如果想统计国内的访问情况,需要给项目添加一个你自己的域名,保证此域名能够在国内正常访问。
五. 字数统计
纯粹为了好玩,想看看每一篇博客有多少字,这个时候想起了写语文作文的字数要求😅。
具体步骤
找到用于字数统计的短代码,也就是 shortcodes,感兴趣可以去 Github 搜一下,有挺多好玩的短代码。本次要实现的这个功能用的是下面这一段。
<span class="meta__text">{{ .WordCount }} 字</span>
根据你的主题,找到对应你要添加元素的位置,目前我用的主题已经有了日期和分类,所以我先找到了日期和分类的位置,参考这两个来决定 字数统计 这个放到那里。经过查找定位是 mainroad/layouts/_default/single.html,下面是替换后的部分,只体现重要的一部分。
<header class="post__header">
<h1 class="post__title">{{ .Title }}</h1>
{{- with .Params.lead }}
<p class="post__lead">{{ . }}</p>
{{- end }}
<div class="post__meta meta">
{{ with partial "post_meta.html" . }}
{{ . }}
{{- end }}
<!-- 字数统计,为了好看加了一个小铅笔图标 -->
<div class="meta__item-wordcount meta__item">
<svg class="meta__icon" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 21h9" />
<path d="M16.5 3.5l4 4L7 21H3v-4L16.5 3.5z" />
</svg>
<span class="meta__text">{{ .WordCount }} 字</span>
</div>
</div>
</header>
六. 代码块复制
当前使用的主题是没有代码块复制的功能的,自己觉得这个还挺重要的,一键复制很方便,从网上找了几个链接进行了尝试,最终参考的是这个大佬的 如何在 Hugo 中添加复制代码按钮 ,按钮功能是能够直接实现的,主要是按钮的位置不太对,发现是按钮添加的路径不对,所以把 js 代码提供给了 GPT,让其做了修改顺利把按钮位置固定在了右上角。
具体步骤
首先在目录 theme/你的主题/static/js 目录下,新建 clipboard.js 文件,相较于原作者的代码,变化在第3步,把按钮位置添加的代码做了改动
// buttons
const svgCopy =
'<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg>';
const svgCheck =
'<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true"><path fill-rule="evenodd" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path></svg>';
// add button function
const addCopyButtons = (clipboard) => {
// 1. Look for pre > code elements in the DOM
document.querySelectorAll("pre > code").forEach((codeBlock) => {
// 2. Create a button that will trigger a copy operation
const button = document.createElement("button");
button.className = "copy-code-button";
button.type = "button";
button.title = "Copy";
button.innerHTML = svgCopy;
button.addEventListener("click", () => {
clipboard.writeText(codeBlock.innerText).then(
() => {
button.blur();
button.innerHTML = svgCheck;
setTimeout(() => (button.innerHTML = svgCopy), 2000);
},
(error) => (button.innerHTML = "Error")
);
});
// 3. Append the button after the highlight div and before the pre tag
const highlight = codeBlock.closest(".highlight");
highlight.insertBefore(button, codeBlock.parentNode);
});
};
// trigger function
if (navigator && navigator.clipboard) {
addCopyButtons(navigator.clipboard);
} else {
const script = document.createElement("script");
script.src =
"https://cdnjs.cloudflare.com/ajax/libs/clipboard-polyfill/3.0.3/promise/clipboard-polyfill.promise.min.js";
script.integrity = "sha512-O9Q+AhI1w7LT1/tHysPWDwwrgB1fKJ/nXPNLC30i8LF6RdSz4dGZyWB9WySag3DZMdGuK5yHJEdKXMKI2m5uSQ==";
script.crossOrigin = "anonymous";
script.referrerpolicy = "no-referrer";
script.onload = () => addCopyButtons(clipboard);
document.body.appendChild(script);
}
在 /theme/你的主题/layouts/partials/footer.html, 在 footer 标签里面追加 js 的引用
<footer>
...
<!-- copy code -->
{{ if (findRE "<code" .Content 1) }}
<script src="{{"/js/clipboard.js" | relURL}}"></script>
{{ end }}
</footer>
在 /theme/你的主题/assets/css 目录里, 可以在现有的主题的 css 文件末尾把复制的样式增加进去
/* 代码块复制按钮 */
.highlight {
position: relative;
}
.copy-code-button {
color: var(--white);
background-color: rgba(255,255,255,50%);
border: none;
border-radius: 6px;
padding: 0 5px 5px 5px;
font-size: 1rem;
position: absolute;
z-index: 1;
right: 0;
top: 0;
margin: 10px;
transition: .1s;
opacity: 0.5;
}
.copy-code-button > svg {
fill: var(--white);
}
.copy-code-button:hover,
.copy-code-button:focus,
pre:active ~ .copy-code-button,
pre:focus ~ .copy-code-button,
div.highlight:active > .copy-code-button,
div.highlight:focus > .copy-code-button {
cursor: pointer;
opacity: 1;
}