基于Jekyll的博客文章「标签化」
立泉重构之后博客开始支持标签
,每一篇文章都会被标记一些关键词作为内容侧重点,不同文章也通过标记相同标签
建立关联性。标签
固定显示在文章顶部,点击会弹出包含相关文章的Dialog
,是非常好的写作分类机制。
Jekyll驱动的静态站点借助Liquid模版语言实现标签
并不复杂。
静态页面
首先在文章Front Matter里添加Jekyll
原生支持的tags
,可以添加多个,用空格隔开:
---
layout: post
categories: original
title: "基于Jekyll的博客文章「标签化」"
author: 立泉
date: 2021-09-01 +0800
tags: Code Blog Jekyll GitHub Liquid
---
然后找到把Markdown
文章转换成HTML
页面的_layout
布局文件,用Liquid
语言获取当前文章的tag
列表和标记该tag
的文章列表:
<!-- 遍历当前页面标记的 tag 列表 -->
{% for tagInPage in page.tags %}
<!-- 遍历整个站点的所有 tag 列表 -->
{% for tagInSite in site.tags %}
<!-- 从站点 tag 列表中找到当前页面的tag -->
<!-- 站点 tag 是一个数组,tag[0] 为该 tag 的名字,tag[1] 为标记该 tag 的所有文章列表 -->
{% if tagInPage == tagInSite[0] %}
<!-- 遍历标记此 tag 的所有文章列表 -->
{% for post in tagInSite[1] %}
<!-- 把文章列表填充到 HTML 中,点击 tag 弹窗显示 -->
{{ post.title }}
{{ post.date | date: "%Y.%m.%d" }}
{{ post.url | prepend: site.baseurl }}
{% endfor %}
{% endif %}
{% endfor %}
{% endfor %}
这样编译时标签
和对应文章列表会被写入到生成的静态HTML
页面里,一般先隐藏,在合适的时机(比如点击标签
时)以对话框形式弹出来。
但是当我接入Google
搜索后发现,它在解析内容生成索引时会把页面内的那个文章列表误认为是文章内容,导致搜出一些完全不相干的文章,仅仅是因为它们都标记了某个相同标签
,而文章列表又恰好包含要搜索的关键字。所以直接把文章列表嵌入页面并不是一个好方案,而且模版语言Liquid
相比真正的编程语言JavaScript
在灵活性上也逊色很多。
动态加载
解决方法十分明确,不把文章列表写入静态页面而是在需要时动态加载,借助Jekyll-Archive插件可以为每个tag
都生成一个包含相关文章列表的HTML
文件,到时候读取它显示出来即可。
可是花一天时间做完Push
到GitHub Pages
上却没有生效,明明本地运行是正常的。搜索一圈才知道并非所有Jekyll
插件都能在GitHub Pages
上使用,受支持的只是少部分,而Jekyll-Archive
并不在这个列表里。
插件
是对Jekyll
原生功能的封装,如果不要求为每个tag
都生成独立的文章列表文件,而是把它们都写入同一个文件中,那么不借助插件API
用普通遍历就可以实现。
工程目录下创建api/tags.txt
文件,写入以下内容:
---
layout: none
permalink: /:path/:basename.json
---
{
"tags":[
{% comment %}遍历整个站点的所有 tag 列表{% endcomment %}
{%- for tag in site.tags %}
{
"tag":"{{ tag[0] }}",
"posts":[
{% comment %}遍历标记此 tag 的所有文章列表{% endcomment %}
{%- for post in tag[1] %}
{
"title": "{{ post.title }}",
"date": "{{ post.date | date: "%Y年%m月%d日" }}",
"url": "{{ post.url | prepend: site.baseurl }}"
}{% unless forloop.last %},{% endunless %}
{%- endfor %}
]
}{% unless forloop.last %},{% endunless %}
{%- endfor %}
]
}
依照Liquid
语法,这段代码的作用是遍历所有tag
,将每个tag
和相关文章列表组合为JSON
格式。如果以上配置正确,执行Jekyll
的build
指令会把内容输出到_site/api/
目录的tags.json
文件中:
{
"tags": [
{
"tag": "标签_01",
"posts": [
{
"title": "标题_01",
"date": "日期_01",
"url": "url_01"
},
{
"title": "标题_02",
"date": "日期_02",
"url": "url_02"
}
]
},
{
"tag": "标签_02",
"posts": [
{
"title": "标题_01",
"date": "日期_01",
"url": "url_01"
},
{
"title": "标题_02",
"date": "日期_02",
"url": "url_02"
}
]
}
]
}
获得映射JSON
后,点击tag
加载对应文章列表并显示出来就可以逐步轻松实现。额…好吧,如果不熟悉JS
的话也不是很“轻松”…比如我,感觉并不是“难”,思路非常清晰,只是对语法和类库陌生,以至于编码步履蹒跚。
不过“久病成良医”,即使不系统性学习整个Web
技术栈,长期从边角接触也足以让我把这个博客站点的空想设计慢慢变为现实。