ghost develop

此文是ghost开发记录。从官网文档开始,了解整个ghost文件结构,程序模块,建筑风格,从源码理解到自定义功能再到主题开发。彻底了解ghost,毕竟Node.js越来越火了。

文档

首先,开发嘛,自然是要先熟悉熟悉这个项目嘛,没什么比官方的更好的啦。当然主要是google了一遍也没找到一些大神关于这方面的文章,就只有自己老实的看官方文档啦。

ghost的文档:

DO的文档:
由于使用DO一键部署的ghost,所以对于DO的文档也是要注意的。 https://cloud.digitalocean.com/support/suggestions?article=how-to-use-the-digitalocean-ghost-application&page=0&query=update%20ghost

环境配置与安装

直接使用在线部署环境,https://C9.IO. 我感觉自己要写篇文章来介绍C9了。搜索了下,没有写C9网站使用教程的,看来我的。

目前在我的本机环境下,grunt init 不了,貌似是Npm上次出问题后,升级改版造成的依赖的问题。在C9的云端下,也是有问题。真是尴尬啊,还没开始就出现大问题了。等待ghost的下个版本吧。反正也忙。 说完就好了。。。但是DO的安装后的文件系统与ghost标准安装后的有不同。不得不说DO把我坑了。直接把DO的文件下下来,我还一直看代码,就说有问题,原来真的有问题,built是构建以后的文件。每次都要重新编译,也还是有点麻烦的啊。

目前在C9下手动安装,很多服务需要配置,所以也是比较麻烦的。

grunt

ghost要用grunt,所以我也就必须去学习学习grunt了。有了webpack,还要啥grunt啊。所以对于grunt就做简单的了解,不深入了。

http://gruntjs.com/

Codebase

到这里不得不说说前端的发展,全是模块啊,几十个依赖,依赖里又有依赖。 https://github.com/TryGhost/Ghost/wiki/Codebase-Overview 代码库

  1. JSON API
  2. 用Ember构建的客户端管理面板
  3. 服务端以当期主题渲染博客内容

Codebase*

+-----------------------------------------------------------+
|                                                           |
|   +---------------------------------------------------+   |
|   |                                                   |   |
|   |                   JSON DATA API                   |   |
|   |                                                   |   |
|   +---------------------------------------------------+   |
|                   ^                    ^                  |
+-------------------|-------------+      |                  |
                    |             |      |                  |
               HTTP |             |      | require()        |
                    |             |      |                  |                                                                                                                                
+-------------------|------+      |      |                  |
|                   |      |      |      |                  |
|         Client    |      |      |      |   Server         |
|                   v      |      |      v                  |
|   +-----------------+    |      |    +----------------+   |
|   |                 |    |      |    |                |   |
|   |   Admin Panel   |    |      |    |      Blog      |   |
|   |   (Ember.js)    |    |      |    |     (theme)    |   |
|   |                 |    |      |    |                |   |
|   +-----------------+    |      |    +----------------+   |
|                          |      |                         |
+--------------------------+      +-------------------------+

Tech architecture

主题开发与配置

一切从官方文档开始:http://themes.ghost.org/

没有用GIT服务进行部署代码,每次都用Nano,还是有点烦的。

sudo service ghost restart  // 记得重启服务  

handlebars: 模板不清楚,post.hbs加入脚本,不能在默认模板的末尾加入。全局加载导致首页的白屏时间过长。 需要做白屏分析。 我的首次打开页面的白屏时间太长。

自定义页面模板

总的来说,文档还是挺清晰的。

归档页面与标签云类似:fetch所有的内容。如下代码所示:

{{#get "posts"   limit="all"}}
     <ul id = "archives" class= "post">
        {{#foreach posts}}
            <li class="{{date format="YYYY-MM"}}">
                <a href="{{url}}"> {{{title}}} </a>
                <span class="archives-item">
                    <time datetime="{{date format='YYYY-MM-DD'}}">
                        {{date format="YYYY-MM-DD"}}
                    </time>
                </span>
            </li>
        {{/foreach}}
    </ul>
{{/get}}

TOC配置

在post.hbs模板页配置TOC插件。然而这种模块式的方式,继承了默认模板,不能让额外加载的脚本在文档最后加载,有点折腾,那么就直接写进去。

为生成的TOC创建一个放置的位置。

<section id="putToc">  
        <h3>TOC</h3>
</section>  

接下来就是脚本了:

window.onload = function() {  
                    function toc(get, n, put) {
                        var node = document.querySelector(get);
                        var nodes = node.querySelectorAll(n || 'h1,h2,h3,h4,h5');
                        var position = document.querySelector(put);
                        // h太少 || 屏幕太小 == 不加载TOC
                        if (nodes.length < 4 || document.body.clientWidth < 1366) {
                            position.innerHTML = "";
                            return true;
                        }
                        if (nodes[0].id !== "") {
                            var id0 = nodes[0].id
                        } else {
                            var id0 = 'toc' + 0;
                            nodes[0].id = 'toc' + 0;
                        }
                        var out = '<ul><li>' + '<a href=#' + id0 + '>' + nodes[0].innerHTML + '</a>';
                        for (var i = 1; i < nodes.length; i++) {
                            var a = nodes[i].nodeName.charAt(1) - nodes[i - 1].nodeName.charAt(1);
                            for (var j = 1; j < a; a--) {
                                out += '<ul><li>';
                            }
                            for (var k = -1; k > a; a++) {
                                out += '</li></ul>';
                            }
                            var nodeId;
                            if (nodes[i].id !== "") {
                                nodeId = nodes[i].id
                            } else {
                                nodeId = 'toc' + i;
                                nodes[i].id = 'toc' + i;
                            }
                            switch (a) {
                                case 0:
                                    out += '</li><li>' + '<a href=#' + nodeId + ' >' + nodes[i].innerHTML + '</a>';
                                    break;
                                case -1:
                                    out += '</li></ul><li>' + '<a href=#' + nodeId + ' >' + nodes[i].innerHTML + '</a>';
                                    break;
                                case 1:
                                    out += '<ul><li>' + '<a href=#' + nodeId + ' >' + nodes[i].innerHTML + '</a>';
                                    break;
                            }
                        }
                        out += '</li></ul>';
                        position.innerHTML += out;
                        $('#putToc').css({
                                'display': 'block',
                                'position': 'absolute',
                                'left': '3rem'
                            })
                            // TOC元素位置改变
                        $(document).scroll(function() {
                            var a = document.querySelector('.post-title').getBoundingClientRect().top;
                            if (a < 80) {
                                $('#putToc').css({
                                    'position': 'fixed',
                                    'top': '80px'
                                })
                            } else if (a > 80) {
                                $('#putToc').css({
                                    'position': 'absolute',
                                    'left': '3rem',
                                    'top': 'initial'
                                })
                            }

                        })
                    }
                    toc('.post-content', 'h1,h2,h3,h4,h5', '#putToc');
                }

对于获取元素相对浏览器窗口的位置:最好使用:x.getBoundingClientRect()。其他CSSOM视图模块(CSS Object Model View)见:css cssom

DONE

  • 评论 :已完成:使用多说部署评论系统
  • CDN :使用bootcdn.cn,速度超快啊,还支持https
  • 字体库直接去掉,默认全微软雅黑;360的太慢了,有空部署自己的字体库。
  • 文章归档页面
  • 标签归档页面
  • Table of content

TODO

nothing