把 blog 从 Movable Type 迁移到了 Hugo
花了些时间把 blog 从 Movable Type 迁移到了 Hugo。
说起来 Movable Type 已经用了有十七年之久了,不过 Movable Type 商业化以后便基本没有更新了,
由于它是 Perl 写的,因此我也没什么动力去持续维护。
由于 Movable Type 自己就是一个输出模板的引擎,因此考虑使用它来直接输出一套 Markdown 的格式的文本应该就可以了。
不过,我发现没有什么特别好的 Perl HTML -> Markdown 逆向转换的现成的库,那么比较明显的办法便是仍然让它正常输出 HTML,
然后用自己的脚本来把 HTML 转换成 Markdown。
第一步是做一个叫 Markdown 的页面(Entries)模板。
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
29
30
31
32
33
34
35
36
37
| ---
title: "<mt:entryTitle encode_php="qq" replace="\$","$">"
date: <$MTEntryDate format_name="iso8601" utc="1" $>
lastmod : <$MTEntryModifiedDate format_name="iso8601" utc="1" $><mt:EntryIfTagged>
tags: [<mt:EntryTags glue=', '>"<$mt:TagName$>"</mt:EntryTags>]</mt:EntryIfTagged>
categories: [<mt:EntryCategories glue=', '>"<$mt:CategoryLabel$>"</mt:EntryCategories>]
aliases:
- <$mt:EntryPermalink replace="https://blog.delphij.net",""$>
- /archives/<$mt:EntryID pad="6">.html
---
<mt:MarkdownOptions>
<mt:If tag="EntryBody">
<$mt:EntryBody$>
</mt:If>
<mt:If tag="EntryMore">
<!--more-->
<$mt:EntryMore$>
</mt:If>
<mt:IfCommentsActive>
<hr>
<mt:Comments lastn="1000">
<mt:CommentsHeader><h4>Archived: <$mt:EntryCommentCount singular="1 Comment" plural="# Comments" none="No Comments"$></h4></mt:CommentsHeader>
<$mt:CommentAuthorIdentity$><b><mt:IfCommentParent><$mt:CommentAuthorLink$> replied to comment from <mt:CommentParent><$mt:CommentAuthor$></mt:CommentParent> | <$mt:CommentDate$><mt:Else><$mt:CommentAuthorLink$> | <$mt:CommentDate$></mt:IfCommentParent></b>
<$mt:CommentBody$>
</mt:Comments>
</mt:IfCommentsActive>
<mt:IfPingsActive>
<hr>
<h4>Archived: trackbacks</h4>
<mt:Pings>
<b><a href="<$mt:PingURL$>"><$mt:PingTitle$></a> from <$mt:PingBlogName$> on <a href="#ping-<$mt:PingID$>"><$mt:PingDate$></a></b>
<p><$mt:PingExcerpt$> <a href="<$mt:PingURL$>">Read More</a></p>
</mt:Pings>
</mt:IfPingsActive>
</mt:MarkdownOptions>
|
这里把目前的回应全部转换成了页面的一部分。这个也不算特别理想,但是因为还没想好把回应弄到什么里面去,加上大部分回应已经是很久以前的了,索性就先这么做吧。
接下来就是把 HTML 转化为 Markdown 了。我使用的是一个叫 html2markdown 的 Python 库,为了满足迁移的需要,我自己做了少量的修改。
脚本本身非常简单:
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
29
30
| import html2markdown
import os
import sys
import html
def mdify(input_name):
if not input_name.endswith('.html.md'):
raise ValueError("Bad name: %s" % input_name)
lines = open(input_name).read().split('\n')
# Find out the second ---
location = [i for i,x in enumerate(lines) if x == '---'][1]
# Get the YAML
yaml = '\n'.join(lines[:location+1])
# Get the HTML
html_content = '\n'.join(lines[location+1:])
# markdownify
md = html.unescape(html2markdown.convert(html_content))
output_name = input_name[:-8] + '.md'
output_file = open(output_name, 'w')
output_file.write(yaml)
output_file.write('\n')
output_file.write(md)
output_file.close()
os.remove(input_name)
for file in sys.argv[1:]:
print("Processing: %s\n" % (file))
mdify(file)
|
最后直接用 find . -name '*.html.md' -type f -exec python3 ~/convert.py {} +
转换就可以了。
在迁移过程中,主要遇到了以下一些问题:
- 很多曾经存在的网站都已经没有了。这个问题没有太好的解决方法,只能有时间慢慢整理了。目前的想法是如果有
互联网档案馆 的副本,则尽量使用这些副本;如果没有的话,就只能这么算了。
- 一些原有的内部链接损坏。在某次 Movable Type 版本升级的过程中,一些旧的链接被破坏掉了,
这次迁移的过程中吸取了这一教训,一部分其他网站链接本blog的链接将会提供一个永久性转向。
- 原有的内部图片丢失。我之前使用 Gallery3 做了一个相册并在 blog 中使用了其中的内容,由于 Gallery3
在几年前停止维护,于是我也把 Gallery3 的服务停掉了。这次搬移的过程中发现了这些图片死链,
目前的做法是直接粗暴地改为静态图片,令其看上去大致上还可以看。
一些留待后续解决的问题:
留言板。目前的打算是使用 isso。之前考虑过使用 Disqus
或是 Gitalk,但前者的免费版本对用户的追踪过于猛烈,而后者则依赖第三方
(GitHub)服务,并不是真正的self-hosting。如果您有更好的建议,欢迎给我发 email(考虑到这个 blog 已经长了多年的草,
我相信能看到这个并给出建议的都是认识的朋友了),或者直接在下面留言。- 一些其他毛边。迁移过程中短暂地丢失了 Atom feed 和 Sitemap,这两个我都重新做了一份,其中 Sitemap 做了一个 XSLT
来呈现一个对人类比较友好的形式。