把 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来呈现一个对人类比较友好的形式。