网站主题 Lime 抽取并开源
起初只有一个做内容分享的网站时,不存在主题的维护问题,但随着自己想法的增多再加上较好的执行力,各类型网站的数量「爆炸式」增长,为求快而施展「CV 大法」,导致了较为严重的维护和未来复用的问题……
是时候将使用多年的网站主题提取出来了,考虑到会有其他人喜欢且想用,打算把整理后的代码作为独立 Git 仓库开源;除了能在 Jekyll 中用之外,再增加对 Hexo 的支持,并可通过纯样式与交互的方式使用。
需求分析
要完成这个项目的需求,大概会经过如下几步:
- 将已存在各网站中「版本」最新的样式、交互与模板整理出来并存放在新开的独立 Git 仓库中;
- 合理划分可复用资源的文件目录结构并归一化相关配置以便于自动化操作及用户自定义;
- 用 Hexo 的机制实现一遍相关功能;
- 独立于静态网站生成器的纯样式与交互的使用方式。
除了功能方面,还需要编写较为详细的使用手册并搭建可演示的在线文档站。
以上工作完成后,先结合 KnoSys 把持有的网站中原本分布式维护的文件全部替换为集中式自动化及自定义扩展的方式;再对外适当宣传以吸引用户,为日后用户驱动的迭代方式做铺垫。
设计
目录结构
受不同静态网站生成器本身机制的限制,实际的目录结构会有些许差异;即便如此,亦可在一定程度上将结构固化下来,在此将可固化结构的「根节点」用 [CURABLE_ROOT]
的形式表示——
静态资源
先按照资源类型去划分「根节点」:
资源类型 | 根节点 |
---|---|
字体 | [FONT_ROOT] |
图片 | [IMAGE_ROOT] |
样式 | [STYLE_ROOT] |
脚本 | [SCRIPT_ROOT] |
再根据功能类别去拆分文件夹:
功能类别 | 文件夹 | 所属资源类型 | 说明 |
---|---|---|---|
组件 | components |
样式、脚本 | 可被组合,按需引用 |
页面 | pages |
样式、脚本 | 可被组合,按需引用 |
供应商 | vendors |
字体、样式、脚本 | - |
头图 | banners |
图片 | - |
初始化 | initializers |
脚本 | - |
补丁 | polyfills |
字体、样式 | 只在 Hexo 中使用 |
动态模板
片段:
|
布局:
|
页面:
|
模板片段
即「partial」,是对 HTML 进行拆分后的一部分结构,有些是可复用的。
常规
每个页面顶多会用到一次的非功能性片段,存放于 [PARTIAL_ROOT]/partials
文件夹:
名称/路径 | 说明 |
---|---|
meta/seo |
SEO 相关标签 |
meta/render |
页面渲染及兼容性相关标签 |
meta/feed |
Feed 订阅相关标签 |
meta/brand |
网站品牌相关标签 |
head |
<head> 内非样式与脚本内容 |
header |
页面头部 |
footer |
页面底部 |
组件
多次使用的一般性可复用片段,通常会传入参数,存放于 [PARTIAL_ROOT]/components
文件夹:
名称 | 说明 |
---|---|
link |
用于站内或站外链接的 <a> 标签 |
brand-link |
网站品牌链接 |
nav-list |
导航菜单条目列表 |
copyright |
版权声明文本及链接 |
doc-toc |
用于使用指南、API 文档等的文档目录树 |
部件
为完成特定业务功能的片段,没有传入的参数,存放于 [PARTIAL_ROOT]/widgets
文件夹:
名称 | 说明 |
---|---|
disqus |
Disqus 评论框 |
comment |
综合评论框 |
share |
分享到 SNS |
toc |
页内目录树 |
插槽
对下文中所描述的「内容插槽」的使用及默认处理,存放于 [PARTIAL_ROOT]/slots
文件夹:
名称 | 说明 |
---|---|
banner |
头图,对应插槽 banner |
header |
头部,对应插槽 header 、title 和 meta |
footer |
底部,对应插槽 footer |
aside |
侧边栏,对应插槽 aside |
布局模板
名称 | 说明 |
---|---|
default |
作为其他布局的基础结构,包含了 <head> 及其内容,继承该布局的其他布局的内容会被渲染在 <body> 内 |
page |
衍生自 default ,用于常规页面 |
post |
衍生自 page ,用于文章 |
doc |
衍生自 default ,用于使用指南、API 文档等 |
blank |
没有任何 HTML 标签,完全空白 |
hack |
只在 Hexo 中使用,用于支持通过页面配置默认值指定的动态布局 |
内容插槽
为提高用户自定义页面的扩展自由度,布局中的部分区域除了可通过全局或页面的配置对预置功能进行控制,还可添加内容区域自定义的内容块:
名称 | 说明 |
---|---|
banner |
头图 |
header |
头部 |
title |
标题 |
meta |
作者、标签等信息 |
content |
正文 |
footer |
底部,大尺寸设备中视觉上是正文右侧 |
aside |
侧边栏 |
实现方案有以下几种:
- 在布局中通过模板片段的方式引用页面配置中以
ksio_slot_[SLOT_NAME]
形式定义的文件路径; - 通过静态网站生成器的机制将页面中定义的内容块设置为构建流程中的某个变量,再在布局中判断并输出。
其中,第一个方案实现成本低很多,不需要深入了解静态网站生成器的相关机制。
内置页面
名称 | 说明 |
---|---|
index |
首页 |
404 |
未找到资源 |
posts |
文章列表 |
全局配置
将用于控制主题模板中预置渲染逻辑的配置项通过 TypeScript 的类型定义 ThemeConfig
进行表示:
|
页面配置
即定义在 Front Matter 中的变量,除了会用到静态网站生成器预定义与约定俗成的变量之外,主题内也自定义了一些——
SEO
影响生成 SEO 相关信息的变量:
变量名 | 值类型/可选值 | 说明 |
---|---|---|
ksio_seo_title |
string |
显示在 <title> 中的页面标题,不指定则使用 title |
ksio_seo_role |
`’writer’ | ‘developer’` |
资源注入
除了整站共用的个别静态资源会写死在 </head>
与 </body>
前方之外,有些只跟特定布局和页面绑定的静态资源得按需注入,可与设置页面配置默认值的能力相结合:
变量名 | 值类型/可选值 | 说明 |
---|---|---|
ksio_asset_js |
`string | string[]` |
ksio_asset_css |
`string | string[]` |
布局插槽
详见上文中对「内容插槽」的描述。
功能开关
变量名 | 值类型/可选值 | 说明 |
---|---|---|
ksio_shareable |
boolean |
是否显示分享按钮 |
生成适配
为了主题预置功能可以正常运作而针对不同的静态网站生成器进行适配,在实际使用时很可能会受具体环境限制而有所差异。
文件路径
无论是 Jekyll 还是 Hexo,主题所提供的文件都放在 ksio
或 _ksio
文件夹(中的某个子孙文件夹)内;上文中定义的形式化的「根节点」具体分别为:
根节点 | Jekyll | Hexo |
---|---|---|
[FONT_ROOT] |
_assets/fonts/ksio |
source/fonts/ksio |
[IMAGE_ROOT] |
_assets/images/ksio |
source/images/ksio |
[STYLE_ROOT] |
_assets/stylesheets/ksio |
source/stylesheets/ksio |
[SCRIPT_ROOT] |
_assets/javascripts/ksio |
source/javascripts/ksio |
[PARTIAL_ROOT] |
_includes/ksio |
layout/_ksio |
[LAYOUT_ROOT] |
_layouts/ksio |
layout/_ksio/layouts |
[PAGE_ROOT] |
_pages |
layout/_ksio/pages |
主题配置
在 Hexo 中,可通过指定方式为主题进行全局配置;而 Jekyll 并没有指定的配置方式,故主题的全局配置都挂在配置文件中的 ksio
下面:
|
在 Jekyll 中可按匹配规则为页面配置设置默认值,而 Hexo 不具备此机制,需要利用过滤器实现下:
|
这个方式有局限——
改变 page.layout
并无法影响 Hexo 所要渲染的布局模板,即与文件页面配置中的 layout
不等效。先通过主题内置的布局模板动态调整下,过后了解 Hexo 的内部流程后再实现个完美的。
另外,不知什么原因,before_post_render
和 after_post_render
这两个过滤器都不起作用,在了解 Hexo 机制时顺便排查下。
组件片段
在 Jekyll 和 Hexo 中并没有「组件」相关支持,但通过它们所提供的片段复用机制可以进行一定程度上的模拟——
在 Jekyll 中是 include
标签,片段中用到的变量在使用时可不必显式传入:
|
在 Hexo 中是 partial
函数,片段中用到的变量在使用时必须显式传入:
|
为保持使用时的一致性,在 include
标签和 partial
函数中的片段路径是基于各自指定目录结构的相对路径,即相对于 _includes
的 ksio/components/link.html
或相对于 layout
的 _ksio/components/link
。
代码高亮
假如是要在文章中展示,无论是 Jekyll 或是 Hexo,都需先自建一个 post.scss
文件,里面引入主题预置的样式片段:
|
若是使用 Jekyll,需在配置文件中设置 highlighter: pygments
,再在 post.scss
中添加高亮样式文件的引用:
|
在 Hexo 中则通过页面配置 ksio_asset_css
添加。
社媒优化
发布版本
新建 release
分支专门用于存放发版文件,根据使用场景将相关文件打包成压缩包后在发版页面提供下载。
使用方式
独立使用
任务
处理中 (1)
- 独立于静态网站生成器使用的样式与交互
未开始 (1)
- 发版自动化脚本
已完成 (10)
- 将个人网站与各 API 文档站的通用文件抽取出来
- 集中管理主题预置文件
- 使页头中的元素可配置并动态渲染
- 使页脚中的元素可配置并动态渲染
- 页头与页脚可使用用户自定义文件
- 统一主题相关配置定义与使用方式
- Hexo 模板适配
- Hexo 中用于设置 Front Matter 默认值的插件
- 字体文件引用适配
- 代码高亮适配