关于使用hugo搭建博客过程中,遇到的一些小问题的解决方案…
该文档基于
hugo@0.124.0
版本
前言:安装配置Hugo
1、Homebrew
MacOS系统
$ brew install hugo
$ hugo version
2、下载指定版本的二进制文件
MacOS系统
注意:此方法适用于当你的包管理工具(如:Homebrew)升级过高,无法安装hugo历史版本,而你的本地项目又依赖旧版本时。
实例背景:Blogs项目中的模板语法依赖
hugo@0.124.0
,在我升级完homebrew后,主动升级了hugo@0.136.0
,导致大量语法冲突,项目无法启动。需要下载官方的二进制文件,安装指定版本的 Hugo。
i. 前往 Hugo Releases 页面。
ii. 找到你需要的版本,下载与 macOS 兼容的二进制文件(
hugo_extended_X.X.X_darwin-amd64.tar.gz
或hugo_extended_X.X.X_darwin-universal.tar.gz
)。- darwin 表示适用于 macOS 系统,而 universal 则意味着它支持在 Intel 和 Apple Silicon(M1/M2)架构的 Mac 上运行
iii. 解压缩文件,将
hugo
二进制文件复制到/usr/local/bin/
目录中(或其他包含在 PATH 的目录),以便可以直接运行hugo
命令:# 解压,生成一个hugo可执行文件 $ tar -xzf hugo_extended_X.X.X_darwin-universal.tar.gz # 将 hugo 可执行文件复制到 /usr/local/bin/ 目录中(或其他包含在 PATH 的目录),以便可以直接运行 hugo 命令 $ sudo mv hugo /usr/local/bin/ # 运行hugo命令,确认是否安装成功 $ hugo version
这样便可在 macOS 上使用指定版本的 Hugo 了。
一、配置项
1、高亮问题
关键步骤
将下载解压的
highlight
文件夹放置于static/js/
下
highlight.pack.js
决定那些语言的代码会根据语法进行高亮style
文件夹中选择喜欢的css样式文件,css文件决定代码高亮的颜色
最后我选择了 agate.css
然后需要在<head>
中增加:
// 主题可根据列表选择 - agate
<link rel="stylesheet" href="/js/highlight/styles/agate.css">
在<body>
结束前增加:
<script src="/js/highlight/highlight.pack.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
2、菜单问题
增加权重
3、目录(toc)问题
描述:最新版似乎有个bug:文章目录无法支持3级标题以下的显示 #240
Hugo (>=0.60.0) uses Goldmark as default renderer. You may add the following settings to your config.toml.
[markup]
[markup.tableOfContents]
endLevel = 3 # 最小标题
ordered = false
startLevel = 2 # 最大标题
See https://gohugo.io/getting-started/configuration-markup/#table-of-contents
二、语法问题
1、定制 head / footer
- 基本布局页:
layouts/_default/baseof.html
- 个性化配置页:
layouts/partials/head.html、layouts/partials/zhihu.svg
等
2、锚点:“back to top”按钮
个性化配置页 —— layouts/partials/footer.html
页面嵌入如下代码:
<script src="https://unpkg.com/vanilla-back-to-top@7.1.14/dist/vanilla-back-to-top.min.js"></script>
<script>
addBackToTop({
diameter: 56,
backgroundColor: 'rgb(255, 82, 82)',
textColor: '#fff'
})
</script>
3、站内搜索
- DuckDuckGo search
- google search
- 商业解决方案 Algolia
- 手动
Coding
解决 golang
暴力解法
手动Coding
解决核心思想
(1) 搜索框触发 search function
function search () {
$.getJSON(baseUrl + 'search.json', function(result){
// 拿到搜索结果
})
}
(2) search.json
{ "results": [
{
"url": "http://example.com/article3/",
"title": "Article3",
"content": "word3a word3b word3c"
},
{
"url": "http://example.com/article2/",
"title": "Article2",
"content": "word2a word2b word2c"
},
{
"url": "http://example.com/article1/",
"title": "Article1",
"content": "word1a word1b word1c"
}
]}
(3) 需要考虑的点
- 如何根据现有文章,执行HUGO命令,自动生成
search.json
文件 - 拿到搜索结果,以什么形式展示搜索拿到的文章列表(新的search page 或 下拉面板)
golang
暴力解法思路:
- 利用hugo生成的index.xml文件进行内容搜索
- hugo的content目录下的html文件会被编译到模板中去
- 利用以上特性使用js实现功能
- html 转文本
- 时间格式转换
实现代码
+++
title = "搜索"
menu = "main"
weight = 30
+++
<style>
/* 手机适配 */
@media screen and (max-width: 500px) {
.search{
padding-right: 25px;
}
.search input{
width: 100%;
}
.search button{
display: none;
}
}
/* 电脑适配 */
@media screen and (min-width: 500px) {
.search{
width: 500px;
}
.search input{
width: 444px;
}
}
/*
* @desc: 搜索页屏蔽page信息
* 1、头部 作者&分类信息
* 2、底部作者信息
*/
.post__meta, .authorbox {
display: none;
}
/* 通用样式 */
.search{
margin: auto;
}
.search input{
outline: none;
border: 1.5px solid #62a1d5;
height: 32px;
padding: 10px;
}
.search button{
outline: none;
border: 0px;
height: 32px;
width: 36px;
position:absolute;
background-color:#62a1d5;
margin-left: 0.8rem;
}
.search .icon{
width: 26px;
height: 26px;
}
.post__header .post__title {
display: none;
}
.post-title a {
color: #000;
}
.read-more {
margin: 4px 0 8px;
text-align: right;
padding: 0 0.8rem 0;
}
.post {
margin-bottom: 12px;
}
h3 {
margin: 0.2rem 0 1rem;
}
.utterances {
display: none;
}
</style>
<div class="search">
<input type="text" placeholder="请输入搜索内容..." id="search-key" />
<button onclick="search()">
<svg t="1583982313567" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1271"
width="200" height="200" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<style type="text/css"></style>
</defs>
<path d="M694.857143 475.428571q0-105.714286-75.142857-180.857142T438.857143 219.428571 258 294.571429 182.857143 475.428571t75.142857 180.857143T438.857143 731.428571t180.857143-75.142857T694.857143 475.428571z m292.571428 475.428572q0 29.714286-21.714285 51.428571t-51.428572 21.714286q-30.857143 0-51.428571-21.714286l-196-195.428571q-102.285714 70.857143-228 70.857143-81.714286 0-156.285714-31.714286t-128.571429-85.714286-85.714286-128.571428T36.571429 475.428571t31.714285-156.285714 85.714286-128.571428 128.571429-85.714286T438.857143 73.142857t156.285714 31.714286 128.571429 85.714286 85.714285 128.571428T841.142857 475.428571q0 125.714286-70.857143 228l196 196q21.142857 21.142857 21.142857 51.428572z"
p-id="1272" fill="#ffffff"></path>
</svg>
</button>
</div>
<h1 id="search-tip" style="color: #c05b4d;text-align: center;display: none;">搜索中,请稍后 ...</h1>
<br />
<div id="result"></div>
<script type="text/javascript">
// enter
window.onload = function() {
document.onkeydown = function(ev) {
var event = ev || event
if (event.keyCode == 13) {
search()
}
}
}
// search
function search() {
key = document.getElementById("search-key").value;
if (key === "") {
return;
}
document.getElementById("search-key").value = "";
// tip
document.getElementById("search-tip").innerText = "搜索中,请稍后 ...";
document.getElementById("search-tip").style.display = "block";
// clear
var el = document.getElementById('result');
var childs = el.childNodes;
for (var i = childs.length - 1; i >= 0; i--) {
el.removeChild(childs[i]);
}
// xml
xmltext = new XMLHttpRequest;
xmltext.open("GET", "/index.xml", false);
xmltext.send();
resp = xmltext.responseXML;
items = resp.getElementsByTagName("item");
// search
var i = 0;
haveResult = false;
while (i < items.length) {
txt = items[i].getElementsByTagName("title")[0].innerHTML + items[i].getElementsByTagName("description")[0].innerHTML
if (txt.indexOf(key) > -1) {
haveResult = true;
title = items[i].getElementsByTagName("title")[0].innerHTML;
link = items[i].getElementsByTagName("link")[0].innerHTML;
time = items[i].getElementsByTagName("pubDate")[0].innerHTML;
mark = items[i].getElementsByTagName("description")[0].innerHTML;
time = formatDate(time)
mark = xmlToTextString(mark);
addItem(title, link, time, mark)
}
i++;
}
if (!haveResult) {
document.getElementById("search-tip").innerText = "搜索完毕,未发现结果 ...";
document.getElementById("search-tip").style.display = "block";
}
}
// add
function addItem(title, link, time, mark) {
document.getElementById("search-tip").style.display = "none";
tmpl = "<article class=\"post\" style=\"border-bottom: 1px solid #e6e6e6;\" >" +
"<header class=\"post-header\">" +
"<h3 class=\"post-title\"><a class=\"post-link\" href=\"" + link + "\" target=\"_blank\">" + title + "</a></h3>" +
"<div class=\"post-meta\">" +
" <span class=\"post-time\">日期:" + time + "</span>" +
"</div>" +
" </header>" +
"<div class=\"post-content\">" +
"<div class=\"post-summary\">摘要:" + mark + "</div>" +
"<div class=\"read-more\">" +
"<a href=\"" + link + "\" class=\"read-more-link\" target=\"_blank\">阅读更多</a>" +
"</div>" +
" </div>" +
"</article>"
div = document.createElement("div")
div.innerHTML = tmpl;
document.getElementById('result').appendChild(div)
}
// html 转化 text()
function xmlToTextString(xmlStr) {
var htmlStr = xmlStr.replace(
/&/g, "&").replace(
/"/g, '"').replace(
/</g, "<").replace(
/>/g, ">");
var dd = htmlStr.replace(/<\/?.+?>/g, "");
var dds= dd.replace(/ /g, "");
return dds
}
// 1. 若小于10,前面加0
function isZero(m){
return m<10?'0'+m:m
}
// 将字符串转为Date格式,获取对应的年、月、日、时、分、秒。组合格式
function formatDate(DateStr) {
//时间戳是整数,否则要parseInt转换
var time = new Date(DateStr); // 需要使用Date格式进行日期转化,若是时间戳、字符串时间,需要通过new Date(..)转化
var y = time.getFullYear();
var m = time.getMonth()+1;
var d = time.getDate();
return y+'年'+isZero(m)+'月'+isZero(d)+'日';
}
</script>
最后, 希望大家早日实现:成为编程高手的伟大梦想!
欢迎交流~
本文版权归原作者曜灵所有!未经允许,严禁转载!对非法转载者, 原作者保留采用法律手段追究的权利!
若需转载,请联系微信公众号:连先生有猫病,可获取作者联系方式!