一直把Blog當作紀錄一些事情用的地方, 想法, 或是學習過的一些東西, 雖然不是很頻繁的在寫, 不過也寫了好幾年了, 從以前到現在, 換過好幾次平台, 從自己架的wordpress, 到posterous, blogger, 一直到現在用的Tumblr, 這中間最喜歡的還是posterous, 不過它已經不存在了, 而Tumblr也用了好一陣子了, 雖然加減湊合著用好像還OK, 不過編輯上也一直不是那麼順手, 尤其是貼source code, 因此也一直想把它換掉
那 medium 呢? medium我還沒很有動力去搞懂它, 會在上面看一些文章沒錯, 但把Blog移到上面去, 好像也沒啥動力
考慮了好一陣子, 不過最後還是把整個Blog遷移了, 反正現在有一個自己的domain (blog.jln.co), 搬家不用改地址!
遷移之前, 想了幾個我的需求:
需求
- 有方便的編輯器可以用, 最好可以支援mark down, 打html有點麻煩, WYSIWYG編輯器通常效率也不高
- 貼code好貼, 也方便閱讀
- 模版好編輯, 至少我要能知道怎麼改模版
- 好預覽
- 能同步到各個social network, 至少Facebook, Twitter, 也能同步到我原本的Tumblr和blogger
- 要能夠友善支援Open graph和Twitter card, 對每次share的FB的醜醜文字版型實在不喜歡
- 好轉移, 好備份, 有版本控制更好!
解決方案
現成的blog service, 好的什麼都要錢(ghost, wordpress), 免費的大概也都被我用過了, 自己架, 又得管server, 後來想想, blog都是靜態的網頁, 也真的不需要一個很複雜的系統, 這時候就想到一個解決方案, 那就是Github
Github有一個Github pages的服務, 可以讓你host你的靜態網頁, 所以只要有一個方法可以把Blog轉成靜態網頁就可以了, 這個還蠻Geek的方式感覺就蠻適合我的
找到了幾個方法轉blog:
Octopress是已經完結不再維護了, 所以就Jekyll和Hexo兩個在抉擇, 兩者都有蠻多的主題跟模版功能, 也有不少plugins
Hexo是台灣精品, 而且是nodekjs寫的, 語言上我比較熟, 要改比較好改,而Jekyll是Ruby寫的, 我跟Ruby很不熟, 但它跟Github pages結合緊密, 而且已經有tool可以從Tumblr移轉內容過來了, 最後我選擇了Jekyll, 選擇Jekyll的原因是
- Github page直接原生支援, 只要把md檔push上去後, 就會自動產生網頁(不過後來我還是先在自己電腦產生完再push, 後面再說原因)
- 找到一個適合的也不太難改的theme, 就懶得去翻Hexo的了, 而且找到的那個對Open graph和Twitter card的支援也不錯, 不用改太多
- 原生的Tumblr import tool
不過整個也花了不少個晚上修改, 又花了一個晚上才能寫完這篇紀錄 @@
安裝Jekyll
網路上可以找到很多安裝Jekyll的文章, 這邊就不說太多, 我試了兩個不同的作法:
作法 1
這是最基本的作法
- 先用
gem install jekyll
安裝jekyll - 用
jekyll new myblog
在myblog目錄產生一個基本的網站 - 用
jekyll s
會在 localhost:4000 開啟一個服務, 這時就透過browser可以看看你的blog長怎樣了
這方法的缺點是, 套用主題時, 還得改一堆東西, 有點麻煩
作法 2
- 一樣先裝jekyll
- 找到一個人家做好的theme (我是用hpstr這個), clone下來改, 因為大部分的都已經把他用的plugin之類的都先寫好在config了, 就省不少事, 建議找theme要注意其對應的Jekyll版本, 像我裝的Jekyll是3, 所以找的是適合3的
- 用
gem install bundler
安裝bundler - 用
bundle install
來安裝相關的plugins - 用
jekyll s
看結果
我後來採用的是作法2, 踩在人家的肩膀上比較快 :P
設定github pages
這部份沒什麼難度, 創建一個專案名稱叫做 你的名字.github.com , 把相關檔案放到這邊去就行了
Github pages支援兩種方式, 一種是純粹的靜態網頁, 就是把html跟其他相關檔案丟到這邊就好(master branch), 另一種方式就是Jekyll, Jekyll的部分只要把前一個動作的檔案放進來就好, 它會自己幫你產生對應的靜態網頁
不過第二種方法的缺點是因為Github pages只支援幾種Jekyll plugins, 而且不支援自訂的plugins(放在 _plugins 目錄下的), 就算你在你自己電腦裡面跑完把產生後的 _site 目錄一起放上去也是沒用的
從Tumblr匯入之前文章
這部份沒太複雜, 是透過jekyll-import
安裝jekyll-import一樣可以透過gem install
來安裝, 但建議不要這樣做, 是因為他用的Tumblr API是JSONP但程式卻將它當一般JSON在解碼, 會出錯, 這部份在最新版的code有解決(害我還去追了source code), 所以抓source回來自己build比較安全
裝好之後執行:
#!/bin/sh
ruby -rubygems -e 'require "jekyll-import";
JekyllImport::Importers::Tumblr.run({
"url" => "http://blog.jln.co",
"format" => "html", # or "md"
"grab_images" => true, # whether to download images as well.
"add_highlights" => false, # whether to wrap code blocks (indented 4 spaces) in a Liquid "highlight" tag
"rewrite_urls" => false # whether to write pages that redirect from the old Tumblr paths to the new Jekyll paths
})'
它就會把文章抓回到 _post的目錄下
Open graph & Twitter card
如果把內容分享到Facebook或是Twitter上只有短短的文字, 不是很好看, 所以希望在這部份能夠至少加上一張圖
hpstr這個theme已經有在 ** _includes/head.html ** 寫好OG跟Twitter card相關的tag了, 圖片(og:image)的部分, 他的規則/順序是:
- Front matter 裡面設定的
- _config.xml 裡的logo設定
我希望是更自動一點, 而不是自己去設定, 所以找到一個plugin : jekyll-auto-image, 這個plugin聰明一點, 他的順序是:
- 內文內出現的第一張圖
- _config.xml 裡面設定的圖
但這樣還稍嫌單調一些, 我想要達成的是:
- 內文內出現的第一張圖
- 根據標籤選的對應的圖(比如說把我go語言相關的設成Gopher的圖片), 這樣不會每個都一樣, 比較有變化一點
- 預設的圖
再加上auto image裡面關於image的設定跟我用的theme有所衝突, 這就需要把原本的auto image改一下了
我新增一個rb檔, 放在 ** _plugins **目錄下, 內容如下:
require "jekyll"
module Jekyll
class AutoImageGenerator < Generator
def generate(site)
@site = site
site.pages.each do |page|
img = get_image(page)
page.data['image1'] = img if img
end
# Now do the same with posts
site.posts.docs.each do |post|
#puts "hola"
#puts Jekyll::VERSION
#puts post.class
#puts post.inspect
#puts post.data.inspect
#puts "-----"
#puts post.output
#puts "----"
img = get_image(post)
post.data['thumb'] = img if img
end
end # generate
def get_image(page)
if page.data['thumb']
return page.data['thumb']
end
# convert the contents to html, and extract the first <img src="" apearance
# I know, it's not efficient, but rather easy to implement :)
if page.class == Jekyll::Document # for jekyll 3.0 posts & collections
htmled = Jekyll::Renderer.new(@site, page, @site.site_payload).convert(page.content)
else
htmled = page.transform # for jekyll 2.x pages
end
img_url = htmled.match(/<img.*\ssrc=[\"\']([\S.]+)[\"\']/i)
return img_url[1] if img_url != nil
tags = page.data['tags']
imagemap = @site.config['imagemap']
if tags != nil && imagemap != nil
tags.each do |t|
if imagemap[t.downcase] != nil
url = imagemap[t.downcase]
if !url.match(/^http/)
url = '/images/' + url
end
return url
end
end
end
return @site.config['logo'] if @site.config['logo'] != nil
return nil
end
end # class
end # module
這版就有達到我想要的目的, 但這不代表問題解了, 反而是問題的開始, 前面有說過github只支援特定的plugins, 所以怎樣這段改過的plugin都不會被它執行到, 唯一能做的解法就是改用靜態網頁的方式
jekyll產生的靜態網頁都放在 _site 目錄下, 所以真的要進master branch只有這裡面的, 其他都不用, 所以要先在本地端用 jekyll b
去產生相關的靜態網頁到 _site裡再上傳
那怎測試呢? 一開始為了測試方便我都以本地端的server做測試, 但如果要測試Facebook share的話則需要能夠讓Facebook 連過來抓取網頁來分析, 但這點在區網不是很方便, 所以就帶入了 ngrok 這個工具, 這工具就是提供給你一個外部的網址, 你在本地端跑了ngrok這程式後, 就有一個可以對應你本地端的server, 還蠻好用的
自動發布到社群網站
這當然是用ifttt囉, 因為有用到jekyll-feed這個plugin, 所以會產生一個feed.xml的檔案, 所以就利用ifttt的feed channel來設定觸發
結語
本來明明不想花太多功夫的, 結果不但花了很多功夫, 還花了一頁來紀錄這篇 orz