今天心血來潮的,把以前在 CSsula 機房寫的文章全部搬到現在的 Octopress 了。我覺得比較麻煩的地方在於文章標題出現中文的時候,又沒有設定 post_name 時,就會以 yyyy-mm-dd-中文字.markdown
的格式儲存。而這個當然無解,只好手動一個一個改檔名了Orz
Wordpress 的的文章全部存在 wp_posts table 裡,如果要對應到,Octopress 的 yaml 設定的話,需要用到 post_title、post_date、post_content 這三個 column。其中 post_date 的資料型態是 datetime,我原本以為是字串導致運作時出了一點差錯:P
我寫了一個程式完成這項工作,他可以作到三件事情:
- 把所有在資料庫中屬於我的文章,轉成檔案存至 _posts 資料夾
- 在轉換過程中 wordpress 用到的圖片,下載下來,存至 images/cssula-blog 資料夾
- 在轉換過程中將所有的
<img src="">
轉成![](/images/cssula-blog)
這是我粗糙的程式碼,程式碼中大寫的部份可以改成別的資料,這東西可以寫得更完善,達到無痛搬家。我想如果網路上沒有開源項目,也許考慮奉獻看看(總之得先看看其他人怎麼寫吧)。
# Ruby code to migrate from Wordpress to Octopress.
require 'mysql2'
require 'open-uri'
def create_post datetime, title, content
date = datetime.strftime("%Y-%m-%d")
time = datetime.strftime("%H:%M:%S")
File.open("YOUR_OCTOPRESS_ROOT/source/_posts/#{date}-#{title}.markdown", "w"){|f|
yaml = <<eos
---
title: "#{title}"
date: #{date} #{time}
categories:
---
eos
content.gsub!(/<img[^>]*src="([^"]*)"[^>]*>/i){|match|
# open the image
filename = nil
open($1){|ff|
filename = $1[/\/([^\/]*)$/, 1]
# save image
File.open("YOUR_OCTOPRESS_ROOT/source/images/cssula-blog/#{filename}", "wb"){|fff|
fff.write(ff.read)
}
}
# replace image tag into plugin style
"![](/images/cssula-blog/#{filename})"
}
f.write(yaml+content)
}
end
client = Mysql2::Client.new(
:host => "YOUR_HOST",
:username => "YOUR_USERNAME",
:password=>"YOUR_PASSWORD",
:database=>"YOUR_DATABASE_NAME"
)
client.query("select * from wp_posts where post_type='post' && post_author=3 && post_status='publish';").each do |row|
begin
create_post row["post_date"], row["post_title"], row["post_content"]
rescue
create_post row["post_date"], "Unknown title", row["post_content"]
end
end
我在這邊提示一下我下的 query:
select * from wp_posts where post_type='post' && post_author=3 && post_status='publish';
post_type='post'
一定要加上去,否則 page 和 revision 都會被挖出來post_status='publish'
則表示已發布的文章,如果你的草稿也想一起導入,就把這個拿掉,如果只想導入草稿則改成draft
post_author=3
表示只導出某個作者的文章。