0x00 基础知识
弄了一天的主题,本身好久都没碰前端的东西,有点生疏,弄完之后感觉还不错,本文主要参考官方的函数文档:https://gohugo.io/functions/
文件结构:
├── 404.html
├── _default
│ ├── archives.html
│ ├── baseof.html #这个就是Hugo定义的mian文件
│ ├── index.json
│ ├── list.html
│ ├── search.html
│ └── single.html
├── index.html
└── partials
├── head.html
├── head_fonts.html
├── hook_head_end.html
├── pagination.html
└── sidebar.html
文件分析
这个mian就是baseof.html
,里面包含了head.html
和 sidebar.html
两个文件:
{{ partial "head.html" . }}
<body class="{{ .Site.Params.themeColor }} {{if .Site.Params.layoutReverse}}layout-reverse{{end}}">
{{ partial "sidebar.html" . }}
<main class="content container">
{{ block "main" . -}}{{- end }}
</main>
{{ if not .Site.IsServer }}
{{ template "_internal/google_analytics.html" . }}
{{ end }}
</body>
</html>
head.html
文件里面一般是加入各种基础的css文件和js文件:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"{{with .Site.LanguageCode}} xml:lang="{{.}}" lang="{{.}}"{{end}}>
<head>
<link href="https://gmpg.org/xfn/11" rel="profile">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
{{ hugo.Generator }}
<!-- Enable responsiveness on mobile devices-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{{ if .IsHome -}}
<title>{{ .Site.Title }}</title>
{{- else -}}
<title>{{ .Title }} · {{ .Site.Title }}</title>
{{- end }}
<meta name="description" content="{{if .IsHome}}{{ $.Site.Params.description }}{{else}}{{.Description}}{{end}}" />
<!-- CSS -->
<link type="text/css" rel="stylesheet" href="/css/print.css" media="print">
<link type="text/css" rel="stylesheet" href="/css/poole.css">
<link type="text/css" rel="stylesheet" href="/css/syntax.css">
<link type="text/css" rel="stylesheet" href="/css/hyde.css">
{{ partial "head_fonts.html" . }}
<!-- Icons -->
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="/apple-touch-icon-144-precomposed.png">
<link rel="shortcut icon" href="/favicon.png">
<!-- RSS etc -->
{{ range .AlternativeOutputFormats -}}
{{ printf `<link href="%s" rel="%s" type="%s" title="%s" />` .Permalink .Rel .MediaType.Type $.Site.Title | safeHTML }}
{{ end -}}
{{ partial "hook_head_end.html" . }}
</head>
主要文件的渲染是在index.html
开始,开头的时候包含了main
,也就是包含了baseof.html
:
{{ define "main" -}}
<div class="posts">
{{ $paginator := .Paginate (where .Site.RegularPages "Type" .Site.Params.PostDir) }}
{{ range $paginator.Pages }}
<article class="post">
<h1 class="post-title">
<a href="{{ .Permalink }}">{{ .Title }}</a>
</h1>
<time datetime="{{ .Date.Format "2006-01-02T15:04:05Z0700" }}" class="post-date">{{ .Date.Format "Mon, Jan 2, 2006" }}</time>
</article>
{{ end }}
</div>
{{- partial "pagination.html" . -}}
{{- end }}
0x01 添加搜索页面
首先这个主题是没有搜索功能的,为了平时搜索文章的时候方便,就添加了一个搜索的功能,
在_default
目录下添加search.html
文件:
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fuse.js/3.2.0/fuse.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1/jquery.mark.min.js"></script>
<script src="/js/search.js"></script>
{{ partial "head.html" . }}
<style>
input
{
-webkit-appearance: none;
display: block;
width: 80%;
padding: 8px;
margin-bottom: 10px;
font-size: 1rem;
line-height: 1.5;
border: 1px solid #ced4da;
border-radius: .25rem;
}
</style>
<body class="{{ .Site.Params.themeColor }} {{if .Site.Params.layoutReverse}}layout-reverse{{end}}">
{{ partial "sidebar.html" . }}
<main class="content container">
{{ block "main" . -}}
<section class="resume-section p-3 p-lg-5 d-flex flex-column">
<div class="my-auto" >
<form action="{{ "search" | absURL }}">
<input id="search-query" name="s" placeholder="输入关键词..."/>
</form>
<div id="search-results">
</div>
</div>
</section>
<!-- this template is sucked in by search.js and appended to the search-results div above. So editing here will adjust style -->
<script id="search-result-template" type="text/x-js-template">
<div id="summary-${key}">
<h2><a href="${link}">${title}</a></h2>
</div>
</script>
{{- end }}
</main>
{{ if not .Site.IsServer }}
{{ template "_internal/google_analytics.html" . }}
{{ end }}
</body>
</html>
在_default
目录下添加index.json
文件:
{{- $.Scratch.Add "index" slice -}}
{{- range .Site.RegularPages -}}
{{- $.Scratch.Add "index" (dict "title" .Title "tags" .Params.tags "categories" .Params.categories "contents" .Plain "permalink" .Permalink) -}}
{{- end -}}
{{- $.Scratch.Get "index" | jsonify -}}
在config.toml
文件下添加以下内容:
[outputs]
home = ["HTML", "RSS", "JSON"]
[outputFormats]
[outputFormats.HTML]
mediaType = "text/html"
[Menus]
main = [
{Name = "Search",weight = 1, URL = "search"},
]
在博客主目录的content
目录下新建文件search.md
:
---
title: "Search Result"
date: 2019-05-28
layout: "search"
---
0x02 添加分页页面
太多文章了,需要一个分页功能会比较方便。添加以下代码:
{{ $paginator := .Paginate (where .Site.RegularPages "Type" .Site.Params.PostDir) }}
{{ range $paginator.Pages }}
......
{{ end }}
在index.html
做修改,在后面包含pagination.html
文件:
{{- partial "pagination.html" . -}}
修改完后的index.html
文件:
{{ define "main" -}}
<div class="posts">
{{ $paginator := .Paginate (where .Site.RegularPages "Type" .Site.Params.PostDir) }}
{{ range $paginator.Pages }}
<article class="post">
<h1 class="post-title">
<a href="{{ .Permalink }}">{{ .Title }}</a>
</h1>
<time datetime="{{ .Date.Format "2006-01-02T15:04:05Z0700" }}" class="post-date">{{ .Date.Format "Mon, Jan 2, 2006" }}</time>
</article>
{{ end }}
</div>
{{- partial "pagination.html" . -}}
{{- end }}
在partials
目录下添加pagination.html
文件,内容如下:
{{ if gt .Paginator.TotalPages 1 }}
<nav class='pagination'>
{{ $.Scratch.Set "hasPrevDots" false }}
{{ $.Scratch.Set "hasNextDots" false }}
{{ range .Paginator.Pagers }}
{{ if eq . $.Paginator }}
<span class='pagination-item current'>
{{- .PageNumber -}}
</span>
{{ else if or (or (eq . $.Paginator.First) (eq . $.Paginator.Prev)) (or (eq . $.Paginator.Next) (eq . $.Paginator.Last )) }}
<a class='pagination-item' href='{{ .URL }}'>
{{- .PageNumber -}}
</a>
{{ else }}
{{ if and (not ($.Scratch.Get "hasPrevDots")) (lt .PageNumber $.Paginator.PageNumber) }}
{{ $.Scratch.Set "hasPrevDots" true }}
<span class='pagination-item dots'>…</span>
{{ else if and (not ($.Scratch.Get "hasNextDots")) (gt .PageNumber $.Paginator.PageNumber) }}
{{ $.Scratch.Set "hasNextDots" true }}
<span class='pagination-item dots'>…</span>
{{ end }}
{{ end }}
{{ end }}
</nav>
{{ end }}
分页的数量可以在congfig.tml
文件上添加参数:
Paginate = 4 #4代表每页4篇文章
0x03 添加目录(TOC)
这个功能我是在大佬博客https://ichochy.com/上面看到不错的滑动效果,然后借鉴进行修改:
在js目录下添加toc.js
文件,加入以下内容:
//文档加载后执行 fn
function ready(fn) {
if (window.addEventListener) {
window.addEventListener('DOMContentLoaded', function () {
//注销时间,避免重复触发
document.removeEventListener('DOMContentLoaded', arguments.callee, false);
fn(); //运行函数
}, false);
} else if (document.attachEvent) { //IE浏览器
document.attachEvent('onreadystatechange', function () {
if (document.readyState == 'complete') {
document.detachEvent('onreadystatechange', arguments.callee);
fn(); //函数运行
}
});
}
}
ready(function(){
let toc = document.getElementById("toc");
let title = document.getElementById("title");
let style = window.getComputedStyle(toc)["display"];
if(!toc || style == "none"){
return;
}
window.title = true;
window.addEventListener('scroll',
function (e) {
let scroll_height = window.scrollY;
if (scroll_height > 200 && window.title) {
window.title = false;
title.style.bottom = '100%';
toc.style.top = "1rem";
} else if (scroll_height <= 200 && !window.title) {
window.title = true;
title.removeAttribute("style");
toc.removeAttribute("style");
}
}
);
})
中间遇到absURL
这个函数,功能作用如下:
{{ "mystyle.css" | absURL }} → "https://example.com/hugo/mystyle.css"
{{ "mystyle.css" | relURL }} → "/hugo/mystyle.css"
{{ "http://gohugo.io/" | relURL }} → "http://gohugo.io/"
{{ "http://gohugo.io/" | absURL }} → "http://gohugo.io/"
在sidebar.html
文件做修改,TableOfContents
就是toc的内容:
<aside class="sidebar">
<div id = "title" class="container sidebar-sticky">
<div class="sidebar-about">
<a href="/">
{{if not .IsPage}}
<h1 class="title">{{ .Site.Title }}</h1>
{{else}}
<p class="title">{{ .Site.Title }}</p>
{{end}}
</a>
<p class="lead">
{{ with .Site.Params.description }}
{{.}}
{{end}}
</p>
</div>
<nav>
<ul class="sidebar-nav">
<li><a href="/">Home</a> </li>
{{ range .Site.Menus.main -}}
<li><a href="{{.URL | absURL }}"> {{ .Name }} </a></li>
{{- end }}
</ul>
</nav>
<p>© 2017 - {{ now.Format "2006"}} {{.Site.Params.copyright}}. </p>
</div>
{{if eq .Section .Site.Params.PostDir}}
<script defer = "defer" src="/js/toc.js"></script>
<div id = "toc" class="container sidebar-toc">
{{ .TableOfContents }}
</div>
{{end}}
</aside>
改变标题级数可以在congfig.tml
文件上做修改:
[markup]
[markup.tableOfContents]
endLevel = 3
startLevel = 1 #表示从一级目录开始
0x04 添加归档功能(Archives)
在_default
目录下添加archives.html
文件:
{{ define "main" -}}
<div class="post">
<h1>{{ .Title }}</h1>
{{ range (.Site.RegularPages.GroupByDate "2006") }}
<h3>{{ .Key }}</h3>
<ul class="archive-list">
{{ range (where .Pages "Type" "posts") }}
<li>
{{ .PublishDate.Format "2006-01-02" }}
->
<a href="{{ .RelPermalink }}">{{ .Title }}</a>
</li>
{{ end }}
</ul>
{{ end }}
</div>
{{ end }}
在config.toml
文件下添加以下内容,weight
代表权重,越小越靠前:
[Menus]
main = [
{Name = "Archives",weight = 1, URL = "archives"}
]
在博客主目录的content
目录下新建文件``archives.md`:
---
title: "Archives"
date: 2019-05-28
layout: "archives"
---
- 原文作者: F0rmat
- 原文链接: https://xxe.icu/hugo_theme_record.html
- 版权声明:本作品采用 署名 - 非商业性使用 4.0 国际 (CC BY-NC 4.0)进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。