2018年8月31日星期五

把我的个人网站推倒重来(Part 1 - 用 Harp 做模板引擎)

根据模板和数据生成静态网站的框架有很多,例如说 HarpJekyllHugo 等等。我对比了一下,最终选择了用 Harp,因为它是用 JavaScript 写的,如果我真的需要做什么改动我可以轻易地去改它的源代码。用 Harp 的坏处也很明显,这个项目在 GitHub 的源代码上已经很久没更新,搞不好将来不再有人维护。

安装 Harp 和用 Harp 编译生成静态页面很容易。因为 Harp 是「convention over configuration」的框架,所以每个页面在使用数据时会优先在里自己目录里的 _data.json 文件,然后看项目根目录里的 harp.json。然而有一个问题是 Harp 没解决的:本地化(多国语言文字)。

本地化

我用每种语言一个目录的方式解决本地化问题:

public/
  ├ _data.json
  ├ index.jade
  ├ _partials/
  │   ├ index.jade
  │   └ resume.jade
  ├ en/
  │   ├ _data.json
  │   ├ index.jade
  │   └ resume.jade
  └ zh/
      ├ _data.json
      ├ index.jade
      └ resume.jade

无论是哪个语言的 index.jade,调用的代码都是 public/_partials/index.jade,只不过把自己当前所拥有的 _data 传过去。无论是哪个语言的哪个文件,都调用 public/_partials/ 下的同名文件,因此所有这些特定语言特定文件都只有一行相同的代码

至于背后实际干活的那个 public/_partials/ 下的文件,它需要同时看 public/_data.jsonpublic/{locale}/_data.json 来进行渲染:前者为它提供语言无关的数据,后者为它提供语言相关的数据。

一开始的时候我严格执行 public/_data.json 只放语言无关数据,后来我发现这样编辑起来很麻烦,因为一个模板往往同时涉及两种数据,我需要修改两个 _data.json 文件。于是我把英文数据和语言无关数据都放到了 public/_data.json 里面,写文档时专注于写英文版。英文版完成后再翻译为其他语言,这时候 public/{locale}/_data.json 里的翻译就会覆盖 public/_data.json 中的同名数据,语言无关的数据自然不会被覆盖。

为了实现「覆盖」这一项功能,我还专门实现了一个 deepCopy 函数用来深复制 JSON 数据。我希望 Harp 能够内置这个功能:_data.json 从文件所在目录开始层层往上覆盖,一直覆盖到 harp.json 为止。在 Harp 支持这个功能之前,我只能自己先实现一个版本来方便我做本地化。

调试技巧

有时候我们实在想看一下 Harp 可访问的数据结构。我们知道 public 对象是任何页面都能访问的,public/ 目录下每一个子目录都会产生一个同名子对象,每一个文件的文件名会以字符串形式出现在对应子目录对象的 _content 中,每一个 _data.json 文件的内容都会展开在对应子目录对象的 _data 中。说这么多,还不如直接把整个 public 打印出来看看!

为此我专门做了一个 debug.jade 的 partial,需要打印 Harp 运行时变量的话就调用一下 != partial('debug', { data: public }),变量立即从 JavaScript 中打印出来。(其中 public 可以被替换为任何我想要查看的变量。)

关于 Harp 的部分到此结束,虽然我还没有把所有改重写的页面都写完,但我觉得 Harp 应用上的问题都已经解决完了。在下一篇文章里,我开始要解决页面布局问题了,如果你喜欢跟着我一起折腾的话,欢迎通过邮件RSS/Atom 订阅我的博客。

没有评论:

发表评论