配置
三种配置。一个是config页面的全局配置,一个是每篇文章头的单页配置。格式接受toml,yaml,json。
文章头配置的part有名字,叫front matter。
还有一个是archetypes/文件夹,设置.md文章的样式,尤其是头部front matter的样式。
结构
hugo结构有两个概念,模版和页面,模版就是html,页面就是文档.md,这两者是一一对应的。
页面内容存在content/
中,在此写出内容,通过存在layout/
下的默认或指定模版,渲染成最终展示在浏览器的页面,存在public/
中。
类型,英文名kind。又分模版类型,和页面类型。
模版
模版,通常有通用的样式,也可以单独定制,就是写前端代码的意思。写的html模版都存在layout/
文件夹里。
layout/_default
/文件夹存基础的、一类的页面模版。
其中的layout/_default/baseof.html
定义页面最基本结构。
模版类型
hugo将模版分成两种类型,一种是正常的文章单页,叫signal.html,一种是文章的集合页,好比归档、首页,不展示文章内容,叫list.html。相当于定义世界,需要物品本身,和装物品的框。
此外还有一个特殊的单页,首页,叫home。
layout/_default/signal.html
就定义了单页的结构,将来渲染每一篇博文。layout/_default/list.html
定义了文章集合页的结构,将来渲染归档列表页,只要没单独设置,list.html 的渲染范围还包括tags、pages、tags集合下每个tag的页面,因为它们都是一个“类”,装此类文章的框。
当然也可以指定渲染模版。比如想开一页,全是图片的,图片.md
,可以单独写个模版,比如叫layout/partials/image.html
,在图片.md
的头部注释处可以设置 layout: layout/partials/image.html
,以后渲染图片.md
页面就指定用这个模版。
如何识别哪个页面是单页用signal,哪个是集合用list渲染呢,带_index.md的(文件夹页)就是集合,不带的文件夹下的每篇文章就是单页。
term模版
在list.html和term.html都存在的基础上,**kind为taxonomy类型的才会用term.html渲染,比如总tags页,而类型为term(即具体莫哥tag)和section的都会用list.html渲染。
页面
页面就是写的文章,存在content/
中,要配合类型说。
页面类型
页面类型可以用 {{ .Kind }} 查看,kind类型有:home, page, section, taxonomy, taxonomyTerm, RSS, sitemap, robotsTXT 以及 404。
后面的先不看,第一个就唯一页面,也不看。page,就是正常的单页面,section是自己定义的按模块的list类型页面(框),taxonomy是按标签、系列、话题等方式分类的list类型页面(框)。
taxonomy是属性,这种分类方式的名字,它的值统称做term,具体可能有tags、category这些分类。
如何生成section,有两种方式。1是content的一级目录,都是section,2是带 _index.md的文件夹,则为section。
如何生成taxonomy,定义在config中,可以自己指定。
[taxonomies]
tag = "tags"
series = "series"
category = "categories"
year = "years"
分级是 taxonomy(类)— [ tags, series 等项目] — [ css,redis 等值]
具体讲,即,基础知识
是一个tag,它的kind是term,type是tags;而tags
是一个种类,它的kind是taxonomy,type是tags。
相应的页面分配,点开基础知识
这个tag,默认通用模版是baseof/list.html(即便有baseof/term.html),它的url是 域名/tags/基础知识
;点开tags
这个大类,如有term.html则用,如果没有就用list.html,它的url是 域名/tags
此外,进入content/,有posts文件夹,当posts/有_index.md(注意带 _
)时,posts本身(而不是它里面的单篇文章)的kind成为section,type为posts,它的url(被我在 _index.md 的头部设置了 url: archive重定向了)为域名/archive
(没有懂为什么在menu处设置没用,非要在 _index.md 头部改)。
带 _index.md的文件夹里(即 一个section下)的正常文章,type为此文件夹名字(即section名),kind为page。比如content/posts/试试就试试.md
的url默认为content/posts/mytitle
,mytitle为 _index.md头部设定的title。当然也可以自定义,like:
[permalinks]
posts = "/posts/:slugorfilename"
如果文件夹下不带 _index.md,比如content/posts/建站记/index.md
,则此时建站记的type则为posts,kind不为section而是page,即index.md 为此文件夹同名正常文件,而建站记/
下其它文章都不是正常文章,消失了。
此特性可以用来存.jpg,即将文章变成同名文件夹,正文放index.md,旁边放点此文配图,方便归档。
各种分类的区别
section我理解的意思,比按tag分类大,相当于,想开发不同的大类,不一定是文章,比如搜集书影音,新闻?之类别的大类的东西,也需要写字和页面,或者在文章中分为技术/非技术,就这两大类,而分出的东西。type意思就是某一个section名字。每个section有单独的url分支。
.kind是页面展现的类型,单页,还是列表集合,还是tags分类。
.Type
是当前页所属 Section
简单看了一下douban和bilibili的设置。只有很大类才set进path里。比如豆瓣单栏有group/,相当于一个section,各个组首页为 group/topic/组名,相当于一个子section。但各个组都不会在组名后面拼贴帖子id,而是越过组名,直接统一设为group/topic/帖子id。而和topic并列的是explore,探索页。b站也是一样,所有视频都在video下,不分各个区。这里各个区,各个组有点按taxonomy分的意思。
这样做的好处是只要知道帖子/视频id就可以搜到内容,不用知道它在哪个组、哪个区。
路由和url设置
定义
- baseURL:
在config首段设置的路径。默认为/
, 一般设为服务器地址,比如要用github page架博客,就设为baseURL = "https://<your github name>.github.io/"
然后开发的时候,默认就是去掉baseURL后开始的。
也可以用相对路径。
-
permalinks:
config里的[permalinks]
可以动态配置每个页面的路径。
参数有 section、title、slug。 -
url:
单页头部注释的url,指除baseURL以外的path -
aliases:
aliases:[‘a’, ‘b’] 可以把链接a重定向为链接b。
各名词关系
url = section + slug
permalink = baseurl + url = baseurl + section + slug
url ("/posts/my-first-hugo-post/")
⊢------------^----------⊣
baseurl section slug
⊢--------^--------⊣⊢-^--⊣⊢-------^---------⊣
permalink
⊢--------------------^---------------------⊣
https://example.com/posts/my-first-hugo-post/index.html
* config设置permalink中动态的section是动态的,比如有很深的section文件夹嵌套,设一个就可以展示全部
* slug默认为title,具体输出可以在archetypes里设置
疑惑点
hugo有一些默认设置:
- 直接的css、js默认路径就是static,所以在html的head定义的时候,路径可以直接省略static名字,从static内开始。
- 默认压缩路径为assets,所以想用管道,或者用ts、scss写路径同样可以省略assets,从assets内开始。
- hugo识别路径挺智能的,末尾有没有
/
都可以识别
Go Template
变量
组合按层的,全站变量为.Site,当前页为.Pages,所以全部页就是.Site.Pages。
下面就只介绍单级的,要变成全站就自动加.Site在前面
.Pages 是指所有类型的页面,包括列表页,tags,这种
.RegularPages (当前section的)正常页面,是指所有单页,即kind=page,不包括列表页
.RegularPagesRecursive 所有section的正常单页,包括它descendant的section里的单页。
.Paginator.Pages 分页器组织下的页,如果使用这个变量,就会翻页,即便不设置翻页间隔,也会默认按10条一翻页。
之前首页和归档页用的遍历代码
/*此选择器意思是,设定type为文件夹名字。因为之前把posts/改成了blog/ */
{{- $paginator := .Paginate (where .Site.RegularPages "Type" $.Site.Params.folder) }}
{{- range $page := $paginator.Pages }}
内容
{{ end }} {{ end }}
.Section 当前内容属于的section。如果是一个nested sections(即嵌套的多层),这个值会是第一层path,posts下面的section里的文章的section会始终是posts
link: Permalink = BaseURL + RelPermalink
找了一下没有 nested section 多层section下,子section的定义方法,只能拿.CurrentSection.RelPermalink
注释
- Go 注释 {{/* {{ add 0 + 2 }} */}}
- HTML 注释 {{ “” | safeHTML }}
注意:Hugo 首先加载的 Go 代码,然后渲染 HTML
如果HTML注释包含了 Go 模板代码,可能导致构建失败
参数
可以使用两种参数:
具体页面的头部注释,只能写死,不能写函数。本来想动态将title关联至文件夹名,起名废就不用不停改名字还要改两次了。但是不能写成动态的。
全局 & 单页参数调用
之前疑问,如果在全局定义了参数,在单页又覆盖,怎么调用怎么区分?
- 全局和单页变量似乎不相干,不是复制关系,调用的代码也不同。
- 全局没定义的参数,单页前面可以直接定义。调用的时候用
{{ .Params.myValue }}
。多层的我还没研究。这时候单页没设置的此参数不存在,但可以用{{ if .Params.myValue }}
判断。 - 全局定义参数,只能放在
[params]
下面,其它地方不能自己初始化参数。调用全局参数用{{ .Site.Params.myValue }}
高级功能
见下一篇