Ghost 1.0.0 调教指南

Ghost 1.0.0 已经 RC1 了,我用着比之前的版本舒服多了。不过嘛,既然是候选版本,问题肯定还是有的(主要是新版 Casper 主题样式上的),结合我目前体验发现的一些 BUG 做个汇总。

表格中内容太长导致表格超出屏幕范围

这个问题我已经在 github 上提了 issue,希望能早日解决吧。
解决办法:手动修改content/themes/casper/assets/built/screen.css,找到.post-full-content table,将里边的white-space: nowrap去掉,重启 ghost。

代码高亮

默认是没有代码高亮显示的,添加方法也简单:
进入 ghost 后台,在 Code injection 里,在 Blog Header 里添加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!--  加载highlight.js样式 -->
<link href="//cdn.bootcss.com/highlight.js/9.9.0/styles/tomorrow-night-eighties.min.css" rel="stylesheet">
<!-- 加载google字体 -->
<link href="https://fonts.googleapis.com/css?family=Lato|Oleo+Script" rel="stylesheet">

<style type="text/css">
/* 设置字体、代码高亮 */
body,p,code,h1, h2, h3, h4, h5, h6,.hljs {
font-family: 'Lato', "PingFang SC", "Microsoft YaHei", sans-serif;
}
.nav {
font-family: 'Oleo Script', cursive;
}
.hljs {
font-size: 0.8em
}
</style>

然后再在 Blog Footer 添加

1
2
3
<!--  执行highlight.js -->
<script src="//cdn.bootcss.com/highlight.js/9.9.0/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>

保存后刷新即可看到效果

图片超出文章宽度

默认的 CSS 会导致图片超过文章的总图宽度,而且会带动图片上面一段文字和图片等宽,看起来很不舒服。
解决办法:在 Code injection 的 Blog Header 添加

1
2
3
4
5
<style type="text/css">
.post-full-content img {
max-width: 100% !important;
}
</style>

在移动设备中文章超出屏幕宽度

有时候在手机上浏览文章,会发现同一篇文章的某些段落的宽度会比较宽,超出屏幕宽度无法正常浏览。
解决办法:在 Code injection 的 Blog Header 添加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<style type="text/css">
.post-full-content p,
.post-full-content ul,
.post-full-content ol,
.post-full-content dl,
.post-full-content pre,
.post-full-content h1,
.post-full-content h2,
.post-full-content h3,
.post-full-content h4,
.post-full-content h5,
.post-full-content h6,
.footnotes {
max-width: 100%;
}
</style>

Disqus 评论框的宽度比正文宽

这个属于个人喜好吧,我喜欢同宽的,看起来比较和谐。默认的.post-full-commentsmin-width: 100%;

1
2
3
4
5
<style type="text/css">
.post-full-comments {
min-width: 50%;
}
</style>

修改分享按钮(Twitter→微博,FB→微信)

效果不多说了,你看下我右上角的分享按钮就知道了。
改动的地方比较多
先去百度分享获取分享代码,只选择“页面分享功能”就行了,获取到的代码大概是这样:

1
2
<div class="bdsharebuttonbox"><a href="#" class="bds_more" data-cmd="more"></a><a href="#" class="bds_tsina" data-cmd="tsina" title="分享到新浪微博"></a><a href="#" class="bds_weixin" data-cmd="weixin" title="分享到微信"></a></div>
<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>

上边的那段 div 的可以不要,要保留下边的 script 部分。
将代码添加到 Code injection 的 Blog Footer 中,保存。
修改content/themes/casper/partials/floating-header.hbs
未修改前的 header.hbs 是这样的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<div class="floating-header">
<div class="floating-header-logo">
<a href="{{@blog.url}}">
{{#if @blog.icon}}
<img src="{{@blog.icon}}" alt="{{@blog.title}} icon" />
{{/if}}
<span>{{@blog.title}}</span>
</a>
</div>
<span class="floating-header-divider">&mdash;</span>
<div class="floating-header-title">{{title}}</div>
<div class="floating-header-share">
<div class="floating-header-share-label">Share this {{> "icons/point"}}</div>
<a class="floating-header-share-tw" href="https://twitter.com/share?text={{encode title}}&amp;url={{url absolute="true"}}"
onclick="window.open(this.href, 'share-twitter', 'width=550,height=235');return false;">
{{> "icons/twitter"}}
</a>
<a class="floating-header-share-fb" href="https://www.facebook.com/sharer/sharer.php?u={{url absolute="true"}}"
onclick="window.open(this.href, 'share-facebook','width=580,height=296');return false;">
{{> "icons/facebook"}}
</a>
</div>
<progress class="progress" value="0">
<div class="progress-container">
<span class="progress-bar"></span>
</div>
</progress>
</div>

修改后的是这样的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<div class="floating-header">
<div class="floating-header-logo">
<a href="{{@blog.url}}">
{{#if @blog.icon}}
<img src="{{@blog.icon}}" alt="{{@blog.title}} icon" />
{{/if}}
<span>{{@blog.title}}</span>
</a>
</div>
<span class="floating-header-divider">&mdash;</span>
<div class="floating-header-title">{{title}}</div>
<div class="floating-header-share bdsharebuttonbox">
<div class="floating-header-share-label">Share this {{> "icons/point"}}</div>
<a href="javascript:void(0)" class="bds_tsina floating-header-share-tw" data-cmd="tsina">
{{> "icons/weibo"}}
</a>
<a href="javascript:void(0)" class="bds_weixin floating-header-share-fb" data-cmd="weixin">
{{> "icons/wechat"}}
</a>
</div>
<progress class="progress" value="0">
<div class="progress-container">
<span class="progress-bar"></span>
</div>
</progress>
</div>

并向content/themes/casper/partials/icons/里放两个 svg 图标,后缀改名为 hbs,我这里放的是 weibo.hbs 和 wechat.hbs

这时重启后再看下页面,雏形已经出来了,不过样式还需再调整一下。
Code injection 的 Blog Header 添加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<style type="text/css">
/* 取消百度分享的样式 */
.bdsharebuttonbox a{
background-image: none !important;
padding-left: 0px !important;
height: -webkit-fill-available !important;
margin: 0px !important;
}
div[class*="bdshare-button-style"]:after {
content: "" !important;
}
/* 让 svg 永远不会成为鼠标事件的target */
svg{
pointer-events: none;
}
/* 改分享按钮的背景色 */
.floating-header-share-fb {
background: #51ca52;
}
.floating-header-share-tw {
background: #e66b57;
}
</style>

保存后再刷新看一下,是不是和原有的 tw、fb 差不多了。其实不用百度分享也能自己搞分享,微信分享就是将当前网址生成一个二维码然后呈现出来;微博自己去设置 url 就行了,不过谁让我懒呢,哈哈。

手动指定摘要位置

修改current/core/server/data/meta/excerpt.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var downsize = require('downsize');

function getExcerpt(html, truncateOptions) {
truncateOptions = truncateOptions || {};
// Strip inline and bottom footnotes
var excerpt = html.replace(/<a href="#fn.*?rel="footnote">.*?<\/a>/gi, '');
excerpt = excerpt.replace(/<div class="footnotes"><ol>.*?<\/ol><\/div>/, '');
// Strip other html
excerpt = excerpt.replace(/<\/?[^>]+>/gi, '');
excerpt = excerpt.replace(/(\r\n|\n|\r)+/gm, ' ');
/*jslint regexp:false */

if (!truncateOptions.words && !truncateOptions.characters) {
truncateOptions.words = 50;
}

return downsize(excerpt, truncateOptions);
}

module.exports = getExcerpt;

修改为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var downsize = require('downsize');

function getExcerpt(html, truncateOptions) {
truncateOptions = truncateOptions || {};
// Strip inline and bottom footnotes
var excerpt = html.replace(/<a href="#fn.*?rel="footnote">.*?<\/a>/gi, '');
excerpt = excerpt.replace(/<div class="footnotes"><ol>.*?<\/ol><\/div>/, '');
// Strip other html
excerpt = excerpt.slice(0, excerpt.search('<!-- more -->'))
excerpt = excerpt.replace(/\s*<\/?code>\s*/g, ' ')
excerpt = excerpt.replace(/<\/?[^>]+>/gi, '');
excerpt = excerpt.replace(/(\r\n|\n|\r)+/gm, ' ');
// windmt.com
excerpt = excerpt.replace(/^(<br>)+/gm, '');
/*jslint regexp:false */

if (!truncateOptions.words && !truncateOptions.characters) {
truncateOptions.words = 50;
}

return downsize(excerpt, truncateOptions);
}

module.exports = getExcerpt;

以上增加的代码是为了增加<!-- more -->支持, 以及摘要分行显示.

全站 SSL

SSL 用免费的 Let’s encrypt 来实现。可以参考我之前写的「Let’s Encrypt 试用手记」或者直接使用这个脚本
至于之前用的百度分享不支持 https,可以参考百度分享不支持Https的解决方案
config.production.json中的url改为https://your.domain.com,重启 ghost。
可能会遇到TOO_MANY_REDIRECTS这个错误。解决办法是在 nginx 里添加proxy_set_header X-Forwarded-Proto https;。参考这个 issue
另外建议在config.production.json配置中添加"forceAdminSSL": true以使后台也实现 https

未备案引起的一些问题

微信分享之“分享给朋友”

现在微信自定义图片、文案分享,只能通过它的 js-sdk 接口,相关文档在这。它需要你在一个微信公众号里边设置“JS接口安全域名”,而微信要求这个安全域名是已备案的。那我没备案怎么办?比如像我这样用的国外空间的,肯定是无法通过备案的。好在它有个测试用的平台,微信公众平台接口测试帐号申请,剩下的就不用说了吧😄
不晓得测试账号获取 jsapi_ticket 和 access_token 有没有总数的限制,微信文档的说的是1w:“目前为了方便测试提供了1w的获取量,超过阀值后,服务将不再可用,请确保在服务上线前一定全局缓存access_token和jsapi_ticket,两者有效期均为7200秒,否则一旦上线触发频率限制,服务将不再可用”

微信分享之“分享到朋友圈”

微信很奇怪,分享给朋友的链接不会被它重新排版,而分享到朋友圈的链接,可能会被它重新排版(主要是去除了 js)导致非常难看甚至无法正常浏览。我试过直接把网址贴在正文里也不行。最后发现一种不是办法的办法,把网址生成二维码,然后 po 图上去。别人扫你的这个二维码打开的链接不会被重新排版。