Monster的三种工作模式

Monster有三种工作模式generate、update和preview。可以通过Monster的第一个参数来指定,在第一个参数缺省时直接使用generate模式。例如:

# 下面两个指令是相同的
> monster --generate
> monster generate --generate

但Monster也有自己的--help参数,所以与generate模式下的--help参数不一致,后者显示的makesite.sh的帮助:

# 显示monster的帮助
> monster --help
# 显示generate模式(即makesite.sh)的帮助
> monster generate --help

工作模式preview是非常简单的,它只是调用python来开启一个web服务器,这样你就可以在本地预览生成的页面文件了。

# 可以指定端口地址(缺省为8000)
> monster preivew 8010
Serving HTTP on 0.0.0.0 port 8010 ...

generate与update模式的原理不同

generate工作模式定义了一个对“网站迁移的标准过程”的理解,亦即是分成四步:

  • generate: 调用wget生成静态页
  • reset-domain:重置页面中的domain地址(它有两个前置过程)
    • pick-sitemap:尝试下载sitemaps文件
    • patch-version:修补assets等目录中的文件名后缀中的版本号
  • short-path: 生成简短的网页路径
  • deploy-now: 部署到Github仓库(它有一个前置过程)
    • check-static:检查reset-domain过程之后的static目录

这个迁移并不是特指针对于Git Pages(xxxx.github.io)的,因此generate模式可以在非Ghost博客上正常工作,并且也可以将生成的静态网页Delpoy到非Git Pages的网站上去。所谓“Ghost -> Git Pages”只是上述过程的一个运用而已。

generate工作模式在网页抓取上并不“积极”,它只是使用wget对Site入口(/index.html)进行深度递归并下载所有页面以及图片等等其它附件与资源而已。相对于Buster,它最大的进步是定义和有效利用了上述的四个阶段。

工作模式update在原理上就与generate不同。update工作模式是直接依赖Ghost的数据库文件的,它必须位于Monster可访问的路径上。update工作模式并没有上述的四个阶段,它缺省就直接读取数据库中最新的条目,并根据其title直接使用wget下载该页面和可能的资源。

update工作模式只有fetchdeploy两种行为。其中fetch行为是默认总是进行——除了在使用--deploy-only参数的情况下,而deploy行为是由--deploy-now--deploy-only来触发的。

update工作模式的deploy行为是直接调用generate模式来实现的,所以事实上二者在Deploy功能上完全一致——只是在调用时,update模式会把--pick-sitemap--short-path置为false,因为这两个步骤已经在update工作模式中处理过了,不需要generate模式去处理。

在update工作模式之内,--pick-sitemap--short-path缺省是打开的,并且总是“推荐”使用short path——这在update工作模式中是更佳的选择。

generate模式的缺省行为

下面的代码将直接调用generate模式的缺省行为:

> monster generate

在缺省情况下,Monster相关的配置如下:

# GENERATE过程
GENERATE=false

# RESET_DOMAIN过程
PICK_SITEMAP=true
PATCH_VERSION=true
RESET_DOMAIN=true

# SHORT_PATH过程
SHORT_PATH=false

# DEPLOY过程
CHECK_STATIC=true
DEPLOY_NOW=false

因此generate模式缺省会跳过GENERATE过程,然后:

  • 判断Static path(例如缺省的./static)是否有效

如果./static不存在,那么直接退出并提示:

Abort because have not './static' directory.

否则接下来处理:

  • 首先根据PICK_SITEMAPPATCH_VERSION的配置来处理RESET_DOMAIN的前置过程;然后,
  • 将检查生成文件的SITE值与发布到的DOMAIN地址,如果不一样(例如想从本地site生成文件并发布到domain),重置Static目录中所有文件中的domain值(RESET_DOMAIN)。

最后跳过SHORT_PATH过程,并:

  • 检查一次Static目录中的文件是否都重置过domain(CHECK_STATIC)。

update模式的缺省行为

下面的代码将直接调用update模式的缺省行为:

> monster update

对于update模式来说,以下参数是缺省置为true值的:

PICK_ROBOTS_TXT=true
PICK_SITEMAP=true
SHORT_PATH=true
RESET_DOMAIN=true

前面说过:update与generate的行为逻辑很不一样。update模式的fetch行为看起来总是更“贪婪”的:

  • 它将尝试获取全部更新文件(依赖.sqlitedb中的信息来分析),并且如果发现有新的post创建,就会尝试获取全部列表文件——例如作者文章列表,以及首页文章索引等(包括PICK_ROBOTS_TXTPICK_SITEMAP等等)。
  • 一旦上述过程完成,fetch行为将进一步地检查Static目录,由于SHORT_PATH为true,所以它会尝试将Url中的路径变短。
  • 最后,update模式会进入RESET_DOMAIN过程,并传入参数--generate=false --pick-sitemap=false --short-path=false以避免makesite.sh模块重复操作。

update模式缺省并不Deploy(除非你在命令行上指定了--deploy-now,它缺省是false值)。

你无法让update过程什么也不做,这一点也与generate不同。唯一可算作例外的,是如果上一次update之后在Ghost中什么变化也没有(没有添加、删除或更新post),那么在update时就不会获得什么更新数据,也不会创建./static目录:

> monster update
Pick updated or new files ...

Try refresh author's pages ...
> Skiped.
Abort because have not './static' directory.

开始构建你的网站

你可以从一开始就选择两种工作模式之一。generate模式每一次总是做全站生成,而update模式只在第一次调用时,读sqlite库中的全部post做一次全站生成——并且部署。

如果你使用过monster update --deploy-now一次,那么Monster会在当前目录下生成一个.sqlitedb文件,用于存储数据库状态的一个时间点——以便下次update增量。

如果已经在用monster generate来直接做全站生成和部署了,那么第一次使用update工作模式时,可以使用下面的命令:

> monster update --init
File .sqlitedb saved.

这并不真的部署和更新任何东西,只是将.sqlitedb对齐到当前数据库。——之后,无论是--deploy-now还是--deploy-only,update模式每次都会更新.sqlitedb

generate模式下的参数

除了需要显式地用monster generate --help显示帮助信息之外,其它情况下都可以省掉第一个参数generate。其它的参数包括:

#
# 参数开关,--paramName=true/false,只用--paramName相当于指定true
#

## 四个主要过程
# - 生成全站
--generate
# - 重置静态页中的domain(缺省为true)
--reset-domain
# - 生成短的Url路径
--short-path
# - 调用Git部署
--deploy-now

## 'RESET_DOMAIN'的前置操作(缺省为true)
# - 下载sitemap文件
--pick-sitemap
# - 修正文件名中的版本信息
--patch-version

## 'DEPLOY_NOW'的前置操作(缺省为true)
# - 检查Static目录中的静态页是否已经重置过domain
--check-static

## 在generate过程中是否显示更详细的信息(缺省为false)
--generate-info

#
# 传入其它配置值(字符串)
#

## 部署到的domain
--domain="..."

## 下载静态页的Site,支持https
--site="http://..."

## 存放静态页的目录
--static-path="..."

#
# 其它
#

## 显示帮助
--help

## 显示版本号
--version

update模式下的参数

可以用monster update来按缺省配置运行udpate模式。其它的参数包括:

#
# 参数开关,--paramName=true/false,只用--paramName相当于指定true
#

## 与Fetch和Deply行为相关
#- 是否调用reset-domain过程(缺省为true)
--reset-domain
#- 是否使用短路径(缺省为true)
--short-path
#- 在Fetch行为中,尝试为remove post行为而更新所有索引页
--sync-removed
#- 直接部署
--deploy-now
#- 不fetch文件,只部署Static目录
--deploy-only


## 特定文件获取
#- 总是下载/tag-cloud
--pick-static-tagcloud
#- 总是下载/profile-xxx
--pick-static-profile
#- 总是下载/archive-post
--pick-archive-post
#- 总是下载/robot.txt
--pick-robot-txt
#- 总是下载sitemap文件
--pick-sitemap
#- 强制下载上述--pick-xxxx和索引页等文件
--force


#
# 传入其它配置值(字符串)
#

## 部署到的domain
--domain="..."
#- 在使用'--sync-issue'功能时,在Issue body中写入的Url上使用的协议名,缺省为'https'
--protocol="..."

## 下载静态页的Site,支持https
--site="http://..."

## 存放静态页的目录
--static-path="..."

## 本地Ghost的数据库文件路径
--db="..."

## 本地Ghost登录帐号,可以用'monster --list user'查看
#- (帐号邮箱)
--email="..."

## 一个标记字符串,极少使用
#-(仅在update功能中用于检查特定文件中是否包含该字符串,以确保整个内容有效)
--ad-token="..."

此外,Monster还在update工作模式下提供了一些直接命令,它们与一个(类似上述的)更新和部署过程无关,例如—help。这些命令包括:

#
# 直接指令
#

## 生成.sqlitedb文件,对齐当前数据库
# - 'checksums'参数是仅仅由Monster内部使用的
--init [checksums]

## 将所有post的slug修改成'authorId-postId'格式
# - 这意味着生成的Url会是短路径名
--sync-slug

## 在对应的Github仓库中,为所有的post生成Gitment格式的Issue
# - Gitment需要用户为每个Post点一次创建Issue按钮,本功能可自动完成
# - 生成的Issue有两个标签:'${slug}'和'gitment'
# - 会忽略掉已经生成过的Issue,不会重复生成
--sync-issue

## 列出unment或user
# - unment是指“未创建Gitment格式Issue”的post
# - user是指Ghost库中的用户名
--list <unment|user>]

## 显示帮助
--help

## 显示版本号
--version

关于--sync-removed参数

Monster是通过记录数据库中的时间点的方法,来实现增量更新的。由于Ghost并没有在数据库中记录删除post的行为,也并不导致时间点变化,所以Monster也并没有办法简单确认当前Ghost环境中删除过post。

因此一旦用户只删除了post——而又没有任何其它添加或更新操作的话,那么就需要用下面的命令来提交一次update:

> monster --sync-removed --deploy-now

这个命令将会重建所有的索引页、标签页等,以便体现删除post这样的操作。

但是有一个小的问题:如果有“上一篇”、“下一篇”这样的导航,那么被删除post的链接仍然会出现在其它post页面上。——不过,由于是增量更新,所以这个链接仍然是可用的。换言之,被删除的post只是不再出现在各种列表页中,并没有真正移除。

很遗憾,目前这是无法直接解决的。

注1:你可以删除.sqlitedb文件再执行monster update,这样可以全站重新生成一次,就可以了。

注2:monster只是从Static目录中复制了文件覆盖你的git仓库,这意味着它并没有git rm …来删除仓库中的既有文件——例如你刚刚删除掉的那个post。也就是说,即使你重新全站生成并deploy,那个post已经上传的的静态网页也仍然需要你手工从git仓库中删除。

关于--force参数

这是一个用在update工作模式下的比较特别的参数。

前面说过,update工作模式是根据sqlite数据库的状况来实现的。这样一来,某些页面(通常是指定为static的、由特定模板或生成算法动态生成的网页)就不能被更新。在Ghost系统中,这些页面包括author和tag的索引页,以及手工定制的一些类似profile的页面。

当Monster发现有一个post新建的时候,它将认为所有上述页面都可能导致变化,所以就会主动(贪婪)地更新这些页面。但如果没有post新建——而只是更新了既有post,那么由于感知不到上述变化,所以就需要用--force来强制生成这些页面。

Monster不可能穷举所有类似的页面,所以在后续的版本中可能会提供一个机制来让用户定制这个页面列表。就目前而言,如果你有更多页面要处理,你只能手工修改updatesite.sh模块。这个文件位置在:

> brew list monster | grep updatesite
/usr/local/Cellar/monster/xxxx/libexec/updatesite.sh