快速导航
上一次迁移博客系统还是在上一次。。。 哈哈,不开玩笑,上次迁移大概还是在七年前(2015.10), 不知不觉我的博客也建立快八年时间,如果算上动态博客可能都快十年了,虽然也没写多少篇(其实本地草稿都攒了快200篇了, 也没好好整理), 但好歹可以记录自己的生活和想法,之前使用的博客系统是基于
Python的Pelican, 此次将博客迁移至 snow —— 一个轻量,简洁的基于Go开发的静态博客生成器
迁移列表
-
[X]内容文件(.md、.org、.html) -
[X]静态文件(.css、.js、.scss等) -
[X]配置文件(pelicanconf.py -> config.yaml) -
[X]主题文件-
[X]分类功能(子分类) -
[X]搜索功能 -
[X]加密功能
-
内容文件
由于 Snow 是我自己开发的, 功能上的实现本身就基于我原有的文件内容, 比如 markdown 和 orgmode 的支持,所以迁移上也很简单,有的甚至不用修改原有的内容
文件头
原来的 Pelican 使用三种文件头形式:
.md 和 .org
-
.md1Title: 使用pelican搭建个人博客 2Author: honmaple 3Date: 2015-12-22 4Category: Python 5Tags: python,pelican 6Slug: 使用pelican搭建个人博客 7 8## pelican介绍 -
.org1#+TITLE: 私人密码库Bitwarden搭建 2#+AUTHOR: honmaple 3#+DATE: 2022-05-29 16:21:15 4#+CATEGORY: Tech 5#+PROPERTY: MODIFIED 2022-05-29 16:27:05 6#+PROPERTY: TAGS linux,bitwarden 7#+PROPERTY: SLUG 私人密码库Bitwarden搭建
在 Pelican 中的 Author 和 Category 是固定字段,如果需要指定多个可以使用英文逗号分隔,而在 Snow 中这两个字段是可选或者说是可配置的,无法知道指定的字段是一个列表还是一个完整的单词,所以这里需要修改为
1- Category: Linux
2+ categories: [Linux]
或者
1- #+PROPERTY: TAGS linux,bitwarden
2+ #+PROPERTY: TAGS [linux,bitwarden]
而在 markdown 中,因为 Snow 支持类似 Hugo 的文件头,如果想要一次性修改好,可以直接改成 yaml 或者 toml 格式
-
yaml1--- 2categories: 3 - Linux 4... 5--- -
toml1+++ 2categories = ["Linux"] 3... 4+++
除了修改原来的文件外,我还在 Snow 中内置了一个 pelican 插件,只要在配置里添加
1hooks:
2 - pelican
3...
就能将 Category 字段转成 categories 列表, Author 转成 authors 列表, Tags 转成 tags 列表, 这样就不用修改原来的文件
.html
1<html>
2 <head>
3 <title>Project</title>
4 <meta name="tags" content="随意写写" />
5 <meta name="date" content="2015-12-22" />
6 <meta name="category" content="Life" />
7 <meta name="authors" content="honmaple" />
8 <meta name="slug" content="project" />
9 <meta name="custom_css" content="/static/css/project.css" />
10 <meta name="custom_js" content="https://cdn.bootcss.com/geopattern/1.2.3/js/geopattern.min.js" />
11 <meta name="custom_js" content="/static/js/project.js" />
12 </head>
13 <body>
14 ...
15 </body>
16</html>
在 html 文件中,原来的 custom_css 和 custom_js 两个字段主要用于自定义css和js,也是利用我开发的一个pelican插件,把多条记录合并成一个列表,在 Snow 中,不用开发新的插件,但需要修改原来的内容
1- <meta name="custom_css" content="/static/css/project.css" />
2- <meta name="custom_js" content="https://cdn.bootcss.com/geopattern/1.2.3/js/geopattern.min.js" />
3- <meta name="custom_js" content="/static/js/project.js" />
4+ <link type="text/css" href="/static/css/project.css" rel="stylesheet"/>
5+ <script type="text/javascript" src="https://cdn.bootcss.com/geopattern/1.2.3/js/geopattern.min.js"></script>
6+ <script type="text/javascript" src="/static/js/project.js"></script>
这样就能得到两个类型为列表的变量 custom_css 和 custom_js
忽略文件
Pelican 可以单独指定 content/posts 和 content/pages, 而在 Snow 中 无法指定 content 目录下的部分目录,但可以设置忽略文件, 这有两种方式
-
在需要忽略的目录下新建一个
_index.md, 并指定ingore_files字段1--- 2# 忽略整个目录 3ignore_files: ["*"] 4# 忽略目录下的README.md和所有js文件 5ignore_files: 6 - README.md 7 - *.js 8--- -
在配置里设置
sections.{目录名}.ignore_files1sections: 2 drafts: 3 # 忽略{content_dir}/drafts目录 4 ignore_files: ["*"]
静态文件
favicon.ico
在 Pelican 中,类似 favicon.ico、robots.txt、CNAME 这些不需要修改的文件我原来是放到 content/extra 目录,但在 Snow 中,content 目录下的所有文件都会视为页面文件或者页面的资源文件, 所以需要把extra目录下的文件移动到static目录下,并设置
1statics:
2 static:
3 ignore_files:
4 # 排除所有static下的文件,不包括子目录的文件
5 - "^[^/]+$"
6 - "^images/"
7 static/CNAME:
8 path: "CNAME"
9 static/robots.txt:
10 path: "robots.txt"
11 static/favicon.ico:
12 path: "favicon.ico"
13 static/README.md:
14 path: "README.md"
15 content/pages/css:
16 path: "static/css"
scss/css/js
在 Python 中有一个专门处理静态文件的 webassets,在 Pelican 中也有一个插件https://github.com/pelican-plugins/webassets, 而在 Snow 中同样支持静态文件的处理, 比如编译并压缩scss文件
1params.assets.css:
2 files:
3 - "@theme/static/scss/common.scss"
4 - "@theme/static/scss/entry.scss"
5 - "@theme/static/scss/entry-tree.scss"
6 filters:
7 - libscss:
8 path: ["themes/snow/static/scss/"]
9 - cssmin:
10 output: "static/lib/css/style.min.css"
其中 filters 支持 libscss,cssmin,jsmin(js处理有些问题,不要使用, 可以使用)
然后就可以在模版里使用
1{%- assets "css" %}
2<link href="{{ config.site.url }}/{{ asset_url }}" rel="stylesheet">
3{%- endassets %}
配置文件
Pelican 使用 pelicanconf.py, 而 Snow 使用 config.yaml
1site:
2 url: "http://127.0.0.1:8000"
3 title: "紅楓吟"
4 subtitle: "风落花语风落天,花落风雨花落田."
5 language: "zh"
6 author: "honmaple"
7 logo_name: "楓"
8
9mode.publish:
10 site:
11 url: "https://honmaple.me"
主题文件
Snow 的模版系统使用的是 https://github.com/flosch/pongo2, 从 Pelican 使用的 jinja2 迁移到 pongo2 除了相关变量的修改和各种大写外,还有部分区别
-
loop: pongo2 使用的是
forloop, 计数使用的forloop.Counter, 从1开始 -
marco: pongo2 想要加载并调用文件内的函数,需要添加
export1{%- macro archive_list(pages) export %} 2... -
super: pongo2 使用的是
block.Super
分类功能
在 Pelican 中,可以使用 page.tags[0].url 获取标签路径,而在 Snow 中想要获取标签路径, 需要使用 get_taxonomy_url
1{%- for name in page.Meta.Get("tags") %}
2<a href="{{ get_taxonomy_url("tags", name) }}">{{ name }}</a>
3{%- endfor %}
子分类功能
原来的子分类是用我写的一个插件实现的,使用的是 . 作为分隔,如 Category: Life.Coding, 在 Snow 中原生支持子分类, 只需要把 . 改成 /, 比如 Python/Flask 和 Python/Ansible/Jinja2 会创建如下分类系统
1- Categories
2 - Python
3 - Flask
4 - Ansible
5 - Jinja2
我的博客导航栏的实现就是基于该功能
1{%- set categories = get_taxonomy("categories") %}
2{%- if categories %}
3 {%- for term in categories.Terms %}
4 {%- if term.Children %}
5 <li class="dropdown">
6 <a href="{{ term.Permalink }}">{{ _(term.Name) }}</a>
7 <ul class="dropdown-menu">
8 {%- for child in term.Children %}
9 <li><a href="{{ child.Permalink }}">{{ _(child.Name) }}</a></li>
10 {%- endfor %}
11 </ul>
12 </li>
13 {%- else %}
14 <li><a href="{{ term.Permalink }}">{{ _(term.Name) }}</a></li>
15 {%- endif %}
16 {%- endfor %}
17{%- endif %}
搜索功能
Snow 本身没有自带搜索,但可以输出 json 文件
-
search.md首先在{content_dir}目录下新建search.md文件1--- 2title: Search 3path: search.html 4template: search.html 5filter: type="posts" 6paginate: 0 7section: true 8formats: 9 json: 10 path: "index.json" 11 template: "search.json" 12---然后在字段
formats指定格式,路径和模版 -
search.json在{theme}/templates目录下或者templates(配置文件同级目录下) 建立1{{- scratch.Set("newjson", slice()) | slient }} 2{%- for page in pages %} 3{{- scratch.Add("newjson", dict("index", forloop.Counter - 1, "permalink", page.Permalink, "summary", page.Summary, "title", page.Title, "content", page.Content | striptags)) | slient }} 4{%- endfor %} 5{{- scratch.JSON("newjson") | safe }}当写入到
/index.json后就可以利用其它的搜索库比如lunr来进行搜索
加密功能
文章加密也是我不用 Hugo 的一个重要原因,我不希望使用 snow build 之前还需要使用另外的程序对内容进行一个预处理,所以在 Snow 中,我内置了一个名为 encrypt 的插件
1hooks:
2 - encrypt
3...
注册插件后就可以在内容文件里使用 encrypt 的 shortcode代码,或者在模版里使用 encrypt 函数
-
全局加密: 只要在文件头添加
passowd: xxx,hello world, 其中xxx是输入的密码,hello world是显示的描述信息 -
局部加密: 使用 shortcode 进行加密
1<shortcode _name="encrypt" password="xxx" description="hello world"> 2... 3</shortcode> -
模版加密:
1<div> 2 {{ page.Content | encrypt:"xxx" }} 3</div>
知识共享署名-非商业性使用-相同方式共享4.0国际许可协议