Ghost 一个简洁、纯粹的内容创作与发布平台,目由非盈利性组织 Ghost Foundation 和一群优秀的独立贡献者共同维护。她是基于 Node.js 构建,具有易用的书写界面和体验;官方提供 Docker 镜像,部署颇为简单;本篇文章在于分享,如何为 Ghost 博客添加归档页。

用过 Ghost 博客的朋友知道,她具有一个非常强劲好用的后台,丰富的编辑功能,让你触手可及;允许注入代码,结构化数据,自定义 Facebook 和 Twitter 的社交媒体共享卡,使您能够为社交媒体添加自定义图像,标题和说明,十分利于 SEO;并且集成大量外部服务,允许您创建和自定义各种连接的应用程序;并且支持自定义主题,允许多人协作等等等等,更多功能可以参见强大如斯,Ghost 开源博客平台;另附 Ghost 文档地址。── 参见 Ghost | 倾城之链接

故此,可以借助其强大的后台,来配置一个归档页;具体的做法是,通过 Pages 创建一个页面;在这页面各注入一段 htmljscss 即可(标题、Url,也是需要填写,可分别写归档、archives),以下是对应的代码:

备注:以下代码是基于 Ghost 2.* 版本;使用最新 3.* 的朋友,略有些不同,在后面会单独做下说明。

页面内容中,通过 HTML 功能选项,向页面注入以下 html 内容,用以挂载后续 js 生成列表内容:

<div class="archives"></div>

页面设置中,通过 Code Injection 注入以下 JS 代码(注意是 Page Footer 代码区),用以向 Ghost 服务端,发起请求,拿到对应的文章数据,并拼接成列表,挂载于 class 为 archives 的节点下;

// <!-- 注入到Post Footer中 -->
<script type = "text/javascript">
jQuery(document).ready(function() {
    // 获取所有文章数据,按照发表时间排列
    $.get(ghost.url.api('posts', {
        limit: 'all',
        order: "published_at desc"
    })).done(function(data) {
        var posts = data.posts;
        var count = posts.length;
        // 展示总共有写的博文篇数;
        var blogHtmlCount = `<p class="blog-count">截止目前,共书写✍️博文 ${count} 篇</p>`;
        $(blogHtmlCount).appendTo(".archives");
        for (var i = 0; i < count; i++) {
            // 由于 ghost 默认是 CST 时区,所以日期会有出入,这里消除时区差;
            var time = moment(posts[i].published_at).utcOffset("-08:00");
            var year = time.get('y');
            var month = time.get('M') + 1;
            var date = time.get('D');
            if (date < 10) date = "0" + date;
            var title = posts[i].title;
            var url = posts[i].url;
            var img = posts[i].feature_image;
            // 首篇文章与其余文章分步操作;
            if (i > 0) {
                var preMonth = moment(posts[i - 1].published_at).utcOffset("-08:00").get('month') + 1;
                // 如果当前文章的发表月份与前篇文章发表月份相同,则在该月份 ul 下插入该文章
                if (month == preMonth) {
                    var html = "<li><time>" + month + "/" + date + "</time><div style='background-image: url(" + img + ")' /><a href='" + url + "'>" + title + "</a></li>";
                    $(html).appendTo(".archives .list-" + year + "-" + month);
                }
                // 当月份不同时,插入新的月份
                else {
                    var html = "<div class='item'><h3><i class='fa fa-calendar fa-fw' aria-hidden='true'></i> " + year + "-" + month + "</h3><ul class='archives-list list-" + year + "-" + month + "'><li><time>" + date + "日</time><a href='" + url + "'>" + title + "</a></li></ul></div>";
                    $(html).appendTo('.archives');
                }
            } else {
                var html = "<div class='item'><h3><i class='fa fa-calendar fa-fw' aria-hidden='true'></i> " + year + "-" + month + "</h3><ul class='archives-list list-" + year + "-" + month + "'><li><time>" + month + "/" + date + "</time><div style='background-image: url(" + img + ")' /><a href='" + url + "'>" + title + "</a></li></ul></div>";
                $(html).appendTo('.archives');
            }
        }
    }).fail(function(err) {
        console.log('Something Error: ' + err);
    });
});
</script>

页面设置中,通过 Code Injection 注入以下 CSS 代码(注意是 Page Header 代码区):

<script src="//cdn.bootcss.com/moment.js/2.14.1/moment.min.js"></script>
<!-- CSS 样式定义 -->
<style type="text/css">
.archives .blog-count {
	text-align: center;
}
ul.archives-list li {
  display: flex;
  margin-bottom: 8px;
  background-color: #e5eff5;
  padding: 8px;
  transition: all 0.3s;
}
ul.archives-list li:hover  {
  filter: drop-shadow(0px 0px 20px lightgrey);
}
@media (prefers-color-scheme: dark) {
    .post-full-content .archives .archives-list time,
    .post-full-content .archives .archives-list a {
        color: #15171a;
    }
}

ul.archives-list li time {
  margin-right: 16px
}

ul.archives-list li a {
  flex: 1;
}

ul.archives-list li div {
  margin-right: 16px;
  width: 60px;
  height: 40px;
  background-size: cover;
  background-position: center;
}
</style>

至此,归档页面已经添加完毕;更进一步,您可以在后台 Design 处,为归档页面添加一条导航,至此,所要做的工作就已彻底完成。当然,以上只是一个示例写法,您完全可以根据自己的需求,定制属于自己特色的归档页


正如上面所提及的,如果您正在使用 3.* 版本,那么有两处略有不同:其一,所请求的 API,改变了;其二,需要额外添加一个 key 字段:

对于 API 的变更, 因为新版本不在提供 Ghost 全局变量,可以使用所提供的新 api ;您需要将如上代码中 ghost.url.api('posts' 修改为:'/ghost/api/v3/content/posts/', 即可;具体可以参见 Ghost posts document

而所需要添加的一个 key 字段,是出于访问控制考虑而加,其官方文档给出这样的说明:

Access control is managed via an API key, and even the most complex filters are made simple with our SDK. The Content API is designed to be fully cachable, meaning you can fetch data as often as you like without limitation.

如何获取这个 key 呢?很简单,可在 Integrations 页面,通过 Add custom integration 按钮,添加一个自定义的 integration, 即可获得包活 Content API Key 在内的一些信息;而我们将这个 Key,在请求中带上即可。其具体请求的代码,如下代码示例:

...
$.get('/ghost/api/v3/content/posts/', {
    limit: 'all',
    key: '您所获得的 Content API Key',
    order: "published_at desc"
  }).done(function(data) {
.....

以上,就是“为 Ghost 博客添加归档页”的一些心得,也欢迎大家分享其他快捷方案;如果想看效果,可以分别参见这两个博客:静轩之别苑(基于 Ghost 2.x 版本),vivo 快应用博客(基于 Ghost 3.x 版本)。

于 2020 年 05 月 29,深圳.福田。