美文网首页前端开发工具学习前端都会去了解的前端进阶之路
手把手教你在 Github 上建立 Ghost 博客——来自《前

手把手教你在 Github 上建立 Ghost 博客——来自《前

作者: e5a6d1b60068 | 来源:发表于2015-11-01 17:53 被阅读6605次
    Ghost on Static.jpg

    2016 年 1 月 28 日更新:由于 Buster 频频失效,无法生成静态博文,已弃用 Buster 方案。博客《前端养成记》现托管在美国硅谷区的阿里云服务器上,该服务器运行着 Node.js 环境。

    在阿里云 ECS 云服务器上搭建 Ghost 博客,请参考《在阿里云 CentOS 7 系统上部署 Ghost 博客》

    平台选择

    本博客 “前端养成记” ( http://loyalsoldier.me )从计划到上线,前前后后应该有快一个月吧。一开始就决定托管在 Github Pages 上,自然会从静态博客入手遴选。一开始选定的是 Jekyll 静态博客,后来又喜欢上 Hexo 的简洁;最后的最后,看到了 Ghost 的默认主题 Casper,很是喜欢。无奈 Ghost 不是静态博客,感觉像是没戏了,遂开始想要找 Casper 的 Jekyll 或 Hexo 的移植主题,也确实找到了。

    Casper for Jekyll: https://github.com/rosario/kasper

    Casper for Hexo:
    https://github.com/MIKAGMR/hexo-theme-ghost-casper
    https://github.com/kywk/hexo-theme-casper

    跟静态博客不同的是,Ghost 这种轻量级的动态博客,有一个管理后台,可以直接写作和管理博客。本质上,跟 WordPress 是相通的,只是 Ghost 搭建在 Node.js 环境上,轻量,快速,简洁。

    不可否认的是,Ghost 的颜值是我相当看重的一点,也确实打动我了。

    所以我最终选择了 Ghost(确实一点都不 geek)。当然,前提是我找到了一套解决方案,我要做的是测试方案的可行性。

    Ghost 技术栈简要解析

    把 Ghost 的结构厘清,其实蛮简单,特别是使用官方已经编译好的 Ghost 压缩包解压后进行二次开发的话:

    Ghost 的页面使用的是 Handlebars.js 前端模板引擎,页面总数在 10 个左右。页面采用引入/调用方式,就是把常规的 HTML 结构,譬如 meta 头信息、headerfooter 等常用且可以复用的 HTML 页面结构,给独立成一个个模板文件,而在其他诸如单篇博文页博主个人主页等页面模板文件内,引用上面的独立模板文件。譬如在单篇博文页内引入 meta 头信息模板文件,就可以达到一处编写,N 处调用的类似变量调用/引入的概念。前端模板引擎的出现,给前端开发人员缩短开发周期起到了不可或缺的作用。

    不了解前端模板引擎工作原理的童鞋,请移步 Handlebars.js 官方文档。快速上手中文教程戳 这里

    动态→静态,how?

    所谓动态博客,需要服务器来支持数据输出。而静态页面,就是用诸如 HTMLXML 等标记语言写好结构,用 CSS 描述好表现样式,用 JavaScript 写好了交互逻辑的,理论上不再接受后端服务器数据输出而动态修改的页面。

    简而言之,静态页面是死的,动态页面是活的。对于 Github Pages 这样仅支持静态网站/页面的托管服务而言,怎么搞定 Ghost 的托管呢?

    这就不得不提到一个开源项目 Buster 了!

    Buster 是救命稻草

    Buster 的原理其实蛮简单:用 Python 语言写的一个文件路径遍历器。通过调用 Wget 把 Ghost 中用到的图片、字体、CSS、JavaScript 等静态资源统一复制到一个新的文件夹(同时此文件夹可以作为 Github Pages 的 repo),然后相应地修改 HTML 文件内引用的静态文件的路径,使之最终生效。

    Buster 也是个大坑

    然而,很不幸的是,Buster 这玩意最初始的项目贡献者已不再维护该项目。旧版的 Buster 对于新版的 Ghost 博客,有很多不如人意的地方(或者说,更多的是由于 Wget 的特性带来的问题),譬如:RSS 订阅功能失效博文题图无法成功获取并复制到新目录导致图片引用失效等等……

    支持新版 Ghost 的 Buster 是由 Misiur 提供的:

    Misiur's Buster Github Repo:https://github.com/Misiur/buster

    光是选择 Buster 的 fork 版本,折腾 Buster 的用法,给 Buster 找 bug,就耗了我将近 4 天的闲暇时间,估计将近 10 个小时。

    Don't BB, show the code

    软件/工具准备:
    1. Node.js:前端开发人员必备。建议使用版本 v0.12.7。
    2. git / Github Desktop:用于克隆项目到本地,部署、提交项目到 Github。建议都安装,前者用于命令行操作,方便其他前端工具和工作流调用;后者用于手动图形化操作,更简便。
    3. Python:用于运行 Buster.py 脚本文件。建议使用版本 v2.7.10.
    4. Chocolatey:Windows 平台软件包管理工具。本项目主要用它来安装最新版的 Wget。
    项目源码准备

    Ghost 中文版:由点云网提供的中文版 Ghost。
    Buster:由 Misiur 提供支持。

    由于本人使用 Windows 平台,还不熟悉 Linux 和 OS X。以下代码均基于 Windows 平台,望见谅。然而我坚信,Windows 这么奇葩的平台都能搞定,Linux 和 OS X 一点问题都木有。

    具体步骤:
    1. 软件/工具准备中安装的软件和工具添加到 Windows 的系统环境变量,并重启电脑;
    2. 在 Github Desktop 中创建一个名为 username.github.io 的项目,并提交到 Github(username 替换成自己的 Github 账户名,例如我的是:loyalsoldier.github.io);
    3. 下载 Ghost 中文版:https://github.com/diancloud/Ghost/releases
    4. 解压 Ghost 中文版压缩包到步骤 1 创建的项目的根目录下的 Ghost 文件夹(文件夹命名非必须 Ghost,只是方便分辨文件和之后操作而已);
    5. 把 Buster 克隆到项目根目录:在命令行提示符中输入git clone https://github.com/Misiur/buster.git,并回车;
    6. 进入 Ghost 文件夹并启动 Ghost:
    // 在命令行提示符中输入: 
    cd ghost // 进入 Ghost 文件夹  
    
    // 然后
    npm start // 进入开发环境的 Ghost,建议初次尝试时使用
    // 或
    npm start --production // 进入生产环境的 Ghost,建议熟悉 Ghost 的设置和部署后再使用。此命令用于把本地的项目和 Ghost 设置部署到 Github Pages 个人主页上
    
    // 此时将启动 Ghost 服务器,浏览器输入 http://localhost:2368 即可访问 Ghost 博客,输入 http://localhost:2368/ghost 进入 Ghost 博客后台管理页面
    
    1. 熟悉 Ghost 博客操作,包括新建博文修改博文修改个人主页等等……

    2. 熟悉操作后,可以在生产环境下进行操作了:

    // 修改 Ghost/config.js
    // 修改 Ghost/config.js
    // 修改 production 数组对象内的 url 为自己的域名或 github 项目的个人主页域名
    // 我的是这样的:
    
    production: {
         url: 'http://loyalsoldier.me',
    
    // 这下面还有很多选项和设置,都不用管
         ...............................
    }
    
    1. 保持 Ghost 服务器开启状态下,用 Markdown 写好你的博文

    2. 最重要的一步,用 Buster 把 Ghost 博文静态化处理:

    // 在命令行提示符中输入:
    cd buster/buster // 进入 Buster 文件夹里的 Buster 文件夹
    
    // 接着
    python buster.py generate // 使用 Python 打开 buster.py 脚本文件内的 generate 方法。此方法用于将 Buster 静态化
    
    // 然后
    python buster.py preview // 使用 Python 打开 buster.py 脚本文件内的 preview 方法。
    
    // 此方法打开了本地服务器,用于预览博客静态页面
    // 最后,在浏览器输入 http://localhost:9000 即可预览 Ghost 博客静态页面
    
    1. .gitignore 文件添加以下内容即可在向 Github 提交项目更改时,忽略掉该文件/文件夹:
    // 给 .gitignore 添加以下内容
    Ghost/
    Buster/
    
    1. 如果自己有一个域名,并希望访客输入 username.github.io 时,自动跳转到个性化域名上去,可在项目根目录新建一个 CNAME 文件:
    // 直接添加域名即可,不需要 http 或 https
    // 例如我的 CNAME 是这样的
    
    loyalsoldier.me
    
    1. 将项目提交到 Github。一两分钟后,访问 http://username.github.io 或 CNAME 文件中设置的个性域名,就可以访问自己的 Ghost 博客啦!

    Ghost 进阶使用教程

    添加“多说”评论
    1. 注册多说账号:http://duoshuo.com ,并填写相关设置;
    2. Ghost/content/themes/casper/post.hbs 模板文件的 {{#post}}{{/post}} 标签之间加入以下多说评论通用代码(建议放在 </footer> 标签前):
    <!-- 多说评论框 start -->
    <div class="ds-thread" data-thread-key="{{id}}" data-title="{{title}}" data-url="loyalsoldier.me{{url}}"></div>
    <!-- 多说评论框 end -->
    
    <!-- 多说公共JS代码 start (一个网页只需插入一次) -->
    <script type="text/javascript">
        var duoshuoQuery = {short_name:"这里替换为你的多说账号名"}; (function() { var ds = document.createElement('script'); ds.type = 'text/javascript';ds.async = true; ds.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + '//static.duoshuo.com/embed.js'; ds.charset = 'UTF-8'; (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ds); })(); 
    </script>
    <!-- 多说公共JS代码 end -->
    
    1. 配合 Ghost 蓝色的主题色,我定制了一套多说评论框的样式,供参考:
        /* 评论区块基本样式 */
        #ds-thread {
            margin-top: 7rem;
            padding-top: 6rem;
            border-top: 1px solid #ebf2f6;
        }
    
        /* 更改社交账号登陆 样式 */
        #ds-thread #ds-reset .ds-login-buttons .ds-more-services,
        #ds-thread #ds-reset .ds-login-buttons .ds-more-services:hover {
            color: #90bad3 !important;
        }
    
        /* 链接悬停样式 */
        #ds-thread #ds-reset a:hover {
            color: #90bad3 !important;
        }
    
        /* 分类悬停样式 */
        #ds-thread #ds-reset .ds-sort a.ds-current,
        #ds-thread #ds-reset .ds-sort a:active {
            color: #90bad3 !important;
        }
    
        /* 高亮悬停样式 */
        #ds-thread #ds-reset .ds-highlight {
            color: #90bad3 !important;
        }
    
        /* 评论区块底部 border 样式 */
        #ds-thread #ds-reset .ds-comments {
            border-bottom-color: #ebf2f6 !important;
        }
    
        /* 评论列表顶部 border 样式*/
        #ds-thread #ds-reset li.ds-post {
            border-top-color: #ebf2f6 !important;
        }
    
        /* 评论 body 文字的样式*/
        #ds-thread #ds-reset .ds-comment-body p {
            color: #3a4145;
        }
    
        /* 新浪微博浮沉的链接样式*/
        #ds-thread #ds-reset #ds-bubble a,
        #ds-thread #ds-reset #ds-bubble a:hover {
            color: #90bad3 !important;
        }
    
        /* Power By 字体颜色 */
        #ds-thread #ds-reset .ds-powered-by a,
        #ds-thread #ds-reset .ds-powered-by a:hover {
            color: #ddd;
        }
    
        /* 工具条的样式 */
        #ds-thread #ds-reset .ds-post-toolbar {
            border-bottom-left-radius: 0.8rem !important;
            border-bottom-right-radius: 0.8rem !important;
        }
    
    
        /* 发布按钮的样式 */
        #ds-thread #ds-reset .ds-post-button {
            border-bottom-right-radius: 0.8rem !important;
        }
    
        #ds-thread #ds-reset .ds-post-button {
            background: #90bad3 !important;
        }
    
        #ds-thread #ds-reset .ds-post-button:hover {
            background: #7381FE !important;
        }
    
        /* 头像的样式 */
        #ds-thread #ds-reset .ds-replybox .ds-avatar img,
        #ds-reset .ds-avatar img {
            border-radius: 50% !important;
        }
    
        /* 评论计算的样式 */
        #ds-thread #ds-reset li.ds-tab a.ds-current {
            border-radius: 5px !important;
        }
    
        /* 评论框的样式 */
        #ds-thread #ds-reset .ds-textarea-wrapper {
            border-top-left-radius: 0.8rem !important;
            border-top-right-radius: 0.8rem !important;
        }
    
        #ds-thread #ds-reset .ds-post-options {
            border-bottom-left-radius: 0.8rem;
            border-bottom-right-radius: 0.8rem;
        }
    
    
        /* 媒体查询 */
        @media only screen and (max-width: 500px) {
            /* base */
            #ds-thread {
                margin-top: 3rem;
            }
            /* 头像 margin */
            #ds-thread #ds-reset .ds-replybox .ds-avatar {
                margin: 0 !important;
            }
            /* 工具条的样式 */
            #ds-thread #ds-reset .ds-post-options,
            #ds-thread #ds-reset .ds-post-toolbar {
                border-bottom-right-radius: 0;
                border-right-width: 0;
            }
            /* 取消 评论数的背景和边框样式 */
            #ds-thread #ds-reset li.ds-tab a.ds-current {
                border: none !important;
                background-color: initial !important;
            }
            /* 增加评论数的边距 */
            #ds-thread #ds-reset li.ds-tab a.ds-current span {
                padding-left: 4px !important;
            }
            /* 工具条工具的边距 */
            #ds-thread #ds-reset .ds-post-options .ds-sync {
                left: 1.4rem !important;
            }
            /* 隐藏 PowerBy */
            #ds-thread #ds-reset .ds-powered-by a,
            #ds-thread #ds-reset .ds-powered-by a:hover {
                display: none !important;
            }
            /* 增加评论区的底部边距 */
            #ds-thread {
                margin-bottom: 4rem !important;
            }
        }
    
    添加 CNZZ 统计
    1. 注册 CNZZ:http://www.cnzz.com
    2. 命令行输入 npm start --production 开启服务器预览;
    3. 浏览器输入 http://localhost:2368/ghost 进入生产环境下的 Ghost 后台管理系统;
    4. 点击博客设置 - 自定义代码,在网页尾部输入框中输入 CNZZ 提供的统计代码;
    5. 为了让统计代码按钮不在页面内显示,可以在 CNZZ 提供的代码外套一层 div,例如这个站点的统计代码如下:
    // 这是 CNZZ 提供的代码
    <script type="text/javascript">
        var cnzz_protocol = (("https:" == document.location.protocol) ? " https://" : " http://");document.write(unescape("%3Cspan id='cnzz_stat_icon_1256670649'%3E%3C/span%3E%3Cscript src='" + cnzz_protocol + "s95.cnzz.com/z_stat.php%3Fid%3D1256670649' type='text/javascript'%3E%3C/script%3E"));
    </script>
    
     <!-- 这是修改后的代码,套上一层 div 并设置 display:none,从此页面上不会出现统计按钮 -->
    <div style="display: none">
        <script type="text/javascript">
            var cnzz_protocol = (("https:" == document.location.protocol) ? " https://" : " http://");document.write(unescape("%3Cspan id='cnzz_stat_icon_1256670649'%3E%3C/span%3E%3Cscript src='" + cnzz_protocol + "s95.cnzz.com/z_stat.php%3Fid%3D1256670649' type='text/javascript'%3E%3C/script%3E"));
        </script>
    </div>
    
    修复 RSS 订阅

    Ghost/content/themes/casper/partials/navigation.hbs 模板文件的 href="{{@blog.url}}/rss 修改为 href="{{@blog.url}}/rss/index.rss

    绑定个性化域名

    托管在 Github Pages 上的静态页面,都是以 username.github.io 为域名进行访问的。然而很多人肯定希望能使用自己的域名。具体步骤如下:

    1. 先完成上面的所有步骤,包括将博客静态化后,上传部署到 Github,然后使用命令行提示符,输入 ping username.github.io 获取你的 Github Pages 页面的 IP 地址(username 请替换为自己的 Github 账号名),如图:
    ping.png
    1. 打开你注册的个人域名的域名注册商网站,比方说国内的万网新网,国外的 GoDaddy,进入管理控制台,添加域名解析。在解析记录中加入一个 A记录(必须)、一个 CNAME 记录(非必须),大体如下:
    IP.png

    A 记录填写步骤 1 中 Ping 出来的 IP 地址,主机记录是 @;CNAME 记录填写你注册的个性化域名,主机记录是 www 或任何你能想到的前缀

    CNAME 里添加 www 的作用是,你输入 www.loyalsoldier.me,浏览器会自动跳转到 loyalsoldier.me。你也可以添加一条叫 blog 的 CNAME 记录,那么访问 blog.loyalsoldier.me 的时候,就会自动跳转到 loyalsoldier.me。·

    这里的 CNAME 跟提交到 Github 项目里的 CNAME 文件是相互跳转的功能:

    这里的 CNAME 的作用是:输入 loyalsoldier.me,浏览器会跳转到 loyalsoldier.github.io。

    Github 项目中 CNAME 文件的作用是:输入 loyalsoldier.github.io,浏览器跳转到 loyalsoldier.me。

    Ghost 相关资源推荐

    各种 Ghost 主题:http://www.allghostthemes.com
    官方主题市场:http://marketplace.ghost.org

    注意事项

    1. 每次撰写博文,都要通过 npm start --production 开启 Ghost 服务器进入 Ghost 后台;
    2. 博文撰写完毕后,都需要重新 python buster.py generate
    3. generate 完成后,都需要提交项目更改到 Github,博文才能生效。

    共同进步

    有疑问,可评论、留言,将尽力解答。
    如果博文存在错误,欢迎指出。我们共同进步!

    相关文章

      网友评论

      • 68697c739807:你好我想问一下啊,这个除了写博客可以用来实现把github仓库里面别人pull request的文件展示到前端页面上吗
        e5a6d1b60068:@Honeyfish 展示 Pull Request 需要自行写代码对接 Github 提供的 Pull Request 接口
        e5a6d1b60068:@Honeyfish 把 GitHub Pull Request 展示出来,需要使用到 GitHub 的 API
      • 胡静_Dada:能看一下Github上面的项目结构吗?
      • Alphazhu:楼主我想问一下,域名解析,A记录里面的你填的是23.235 好像并不是上面ping出来的地址啊,因为我是这方面的小白,我是把Ghost托管在daocloud的演示上的,域名解析填写ping出来的地址,跳转的就是daocloud的官网,要怎么解决。
        7cbbbd05059f:按照你的方法 已经搭建完成 http://xinweb.org
        e5a6d1b60068:@Alphazhu 用 DaoCloud 的话,它会有一个域名给你,应该是一个很长的没有什么规律的“项目”域名,你找一些。这时候,在解析里就不是填写 A 记录了,而是 CNAME 记录
        e5a6d1b60068:@Alphazhu DaoCloud 会有一个专门的网址给你啊。就是你这个应用自己的网址,应该不是 IP 地址。
      • Tom000000:我想问问sqlite3模块错误咋整...npm start根本没办法开...
        Tom000000:@Loyalsoldier '我真的不知道怎么做了,我研究这ghost前前后后也得3个月了....
        Tom000000:@Loyalsoldier 大神您好,我突破了sqlite3的包围圈,现在困在了undefined is not a function部分...
        e5a6d1b60068:@DJSETSUGEKKA 如果你没有翻墙的话,可以下载这个安装教程:http://www.ghostchina.com/download/ 里的“Ghost 中文集成版”
      • Se7ven:真是一篇好博客,,绝对一赞啊!动态的暂时没有时间搞,先弄个静态玩玩的。请问一下,哪里有关于设置https://github.com/MIKAGMR/hexo-theme-ghost-casper主题具体的博客呢,网上的好文章真是太少了!走了很多弯路啊
        e5a6d1b60068:@Se7ven 建议还是看 Hexo 的官方教程
      • 每日思考:这也太费事了吧。
        自己搭个本地blog,然后静态化,再提交到github上。要哭了。

      本文标题:手把手教你在 Github 上建立 Ghost 博客——来自《前

      本文链接:https://www.haomeiwen.com/subject/vvcqhttx.html