> ## Content Index
> Fetch the complete content index at: https://blog.hinablue.me/llms.txt
> Use this file to discover other available public pages before exploring further.

# 搬家到 Octopress
- URL: https://blog.hinablue.me/move-to-octopress/
- Published: 2011-11-13T05:39:00.000Z
- Updated: 2026-06-25T09:32:18.000Z
- Author: Hina Chen
- Tags: Octopress

身為一個~~Geek~~工程師，用 VIM 來寫部落格應該也是很合理的。所以，我就這麼樣拋棄我長久以來維護的 TextCube 跳槽到 Octopress 了。不過，眾多（？）TextCube 的用戶也不用擔心，基本上我還是會維護的，只是官方那種趨於牛步的更新速度，實在讓人覺得很無力啊！官方最後一次的更新，在 svn 上面竟然已經是四月的事情了（眼神死

---

所以我就理所當然入主 [Octopress](http://octopress.org/?ref=blog.hinablue.me) 了！

網路上已經有很多教學，我就不再野人獻曝，請大家參考底下文章：

- [XDite, Why Octopress?](http://blog.xdite.net/posts/2011/10/07/what-is-octopress/?ref=blog.hinablue.me)
- [龍哥, How to install octopress on heroku](http://blog.eddie.com.tw/2011/10/11/how-to-install-octopress-on-heroku/?ref=blog.hinablue.me)
- [無為閣, 換到 octopress](http://hychen.wuweig.org/blog/2011/11/13/huan-dao-octopress/?ref=blog.hinablue.me)
- [鴉7, Octopress 搬家記 (1)](http://blog.yorkxin.org/2011/11/26/import-from-wpcom-to-octopress/?ref=blog.hinablue.me)
- [鴉7, Octopress 搬家記 (2)](http://blog.yorkxin.org/2011/11/26/my-octopress-workflow/?ref=blog.hinablue.me)
- [鴉7, Octopress 搬家記 (3)](http://blog.yorkxin.org/2011/11/26/octopress-redirect-to-old-site/?ref=blog.hinablue.me)
- [Github Custom Domain With Octopress in Ubuntu Oneiric 11.10](http://www.yodi.me/blog/2011/10/24/github-custom-domain-with-octopress-in-ubuntu-oneiric-11-dot-10/?ref=blog.hinablue.me)
- [Markdown 語法說明](http://markdown.tw/?ref=blog.hinablue.me)

### 我用 Octopress

簡而言之是一種~~Geek用~~純文字編輯的部落格系統。你需要有 git, ruby, markdown 等環境，對一般人來說可能不是那麼討喜。不過我拋棄 Windows 已經三年多了（除了 Canon RAW 要轉檔（眼神死），所以在 Ubuntu 底下有這些環境也是很合理的。

他是一個使用 Markdown 來撰寫文章的系統，透過 `rake generate` 來產生整個部落格所需要的檔案，然後在藉由 git 來將部落格給發佈到遠端，你可以使用 [gitHub](https://github.com/?ref=blog.hinablue.me) 或是 [Heroku](http://www.heroku.com/?ref=blog.hinablue.me) 這兩個服務商。

### 何不 TextCube

我也用了很久，打從他 0.96 版的時候我就開使用，只是人次沒破百萬而已（笑）。他是一套韓國開發的開放原始碼部落格系統，當 Wordpress 在台灣還不是那麼紅的時候，這個系統也曾經有許多使用者在用，**但是**，為什麼使用者流失的這麼快？原因出在於大幅度改版，與舊版不相容等問題，導致一堆人離家出走。

我之所以一直使用的原因，其實我並不覺得他難用，對我來說 Wordpress 反而很難用，我兩種都用過好一陣子，就**使用者親和力**來說，當初 TextCube 我覺得是比 Wordpress 好得多的。

嗯，其實我的 Textcube 還活著，在這裡 [http://tc.hinablue.me/](http://tc.hinablue.me/?ref=blog.hinablue.me)，其實我一直在等官方把 TC2.0 釋出，可是已經快兩年過去了，完全沒有消息，雖然偶爾還是會跟官方的開發者聯繫（大多都是 debug 就是），只是，就這樣了吧，等到他真的發佈再說了。

### TC to OC

說轉換無痛其實是騙人的（喂）。不過如果是 TC 1.6 以上的版本，要轉換其實並沒有太大的困難。Octopress 本身是使用 permalink 來當作網址，所以，在 TC 裡面就必須要有 slogan 的項目設定。一般來說，會使用數字當作是文章網址，除非你特別設定使用 slogan 當網址，否則預設都是數字。

數字也可以轉換到 Octopress 來，只是檔名就沒那麼好理解了。因為 Octopress 是以檔案來當作*草稿*，所以當你出現一堆 300.markdown, 301.markdown 的時候，鬼才知道裡面到底寫了什麼東西。所以不是不行，而是後續維護上可能會造成一些不必要得麻煩。

我有寫了簡單的兩隻程式幫我轉，資料庫是用 [Idiorm](https://github.com/j4mie/idiorm?ref=blog.hinablue.me) 這個套件，你可以自行去 gitHub 下載。底下的範例是使用我的網址，請不要照抄，另外，如果你有使用我的 HC\_Emoticons 外掛，也會一併轉換。

裡面會把原本部落格使用的圖片，轉去一個靜態網址 `[http://static.hinablue.me/blog](http://static.hinablue.me/blog?ref=blog.hinablue.me)`，然後 HC\_Emoticons 會轉去這個靜態網址 `[http://static.hinablue.me/blog/emoticons](http://static.hinablue.me/blog/emoticons?ref=blog.hinablue.me)`，這兩個網址請自行設定。

```php
#!/usr/bin/php -q 
<?php

require_once "idiorm/idiorm.php";

ORM::configure('mysql:host=localhost;dbname=tcback');
ORM::configure('username', 'root');
ORM::configure('password', 'CalineILoveYou');
ORM::configure('driver_options', array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));

$regx = "/<a href=\"http:\/\/www\.flickr\.com\/photos\/(?P<userid>[^\/]+)\/(?P<photoid>.*)\" title=\"(?P<title>.*)\" target=\"_blank\"><img src=\"(?P<src>(.*)\.jpg)\" border=\"0\"><\/a>/i";

// 依照類別將文章匯出
$posts = ORM::for_table('tc_Entries')
    ->where_in('category', 1)
    ->find_many();

// 請把 hinablue 改成你的 flickr username
function flickr_replace($m) {
    return '[!['.str_replace('_','\_',$m[3]).']('.$m[4].')](http://www.flickr.com/photos/hinablue/'.$m[2].')';
}

exec('mkdir -p entry');
exec('rm -rf ./entry/*.markdown');

foreach($posts as $post) {

    // 底下的 categoires 是自訂的分類
    // 你可以寫一個，像是 [Life]
    // 或是多個，像是 [Life, Chats]
    $data = '---
    layout: post
    title: "'.str_replace('"','\"',$post->title).'"
    date: '.date("Y-m-d H:i", $post->created).'
    comments: true
    categories: []
    ---

    ';

    $entry = $post->content;

    $entry = preg_replace("/<br>/i","\n",$entry);
    $entry = preg_replace_callback($regx, "flickr_replace", $entry);
    $entry = str_replace("[##_ATTACH_PATH_##]", "http://static.hinablue.me/blog", $entry);
    $entry = str_replace("http://blog.hinablue.me/attach/1/", "http://static.hinablue.me/blog/", $entry);
    $entry = preg_replace("/\[##_1(?|L|R)\|([0-9]+)\.jpg\|([^#]+)\|_##\]/i", '<img src="http://static.hinablue.me/blog\1.jpg" \2 />', $entry);
    $entry = str_replace("/plugins/HC_Emoticons/", "http://static.hinablue.me/blog/", $entry);
    $entry = preg_replace("/\[##_HCEMO_([^_#]+)_##\]/i", '\1', $entry);
    $entry = preg_replace('/longdesc="([^"]+)"/i', '', $entry);
    $entry = str_replace('http://blog.hinablue.mehttp', 'http', $entry);
    $data .= $entry;

    // 這裡是使用 $post->slogan 來當作檔名
    // 如果你要用數字，則改為 $post->id 即可
    $fp = fopen("./entry/".date("Y-m-d", $post->created).'-'.str_replace("_", "-", $post->slogan).'.markdown', "w+");
    if (!fwrite($fp, $data)) {
        echo $post->id." failed.\n";
    }

    fclose($fp);

    // 這邊會檢查檔案，如果有 ## 這種 TextCube 專用 replace 存在
    // 則會告訴你這些檔案，你可能有需要做修改
    if(preg_match("/##/i", $data)) {
        echo "./entry/".date("Y-m-d", $post->created).'-'.str_replace("_", "-", $post->slogan).'.markdown'." ";
    }

}
?>

```

這裡還有第二個檔案，他是將 .markdown 檔案*逐行取出*，然後做一些字串的過濾等等。

```php
#!/usr/bin/php -q 
<?php

exec('ls ./entry/*.markdown', $rst);

foreach($rst as $file) {

    $fp = fopen($file, "r+");
    $lines = 0;
    $data = '';
    $is_code = false;
    while(!feof($fp)) {
        // 逐行取出
        $line = fgets($fp);

        // 換掉 [code] 套件的原始碼區塊
        if(preg_match("/\[code ([a-z0-9]+)\]/i", $line)) {
            $is_code = true;
            $line = "\n";
        }
        if(preg_match("/\[\/code\]/i", $line)) {
            $is_code = false;
            $line = "\n";
        }
        if($is_code) {
            if(trim($line) != "") {
                $line = "\t".$line;
                $data .= $line;
            }
        } else {
            $data .= $line;
        }

        // 超過 20 行則插入 read more
        $lines++;
        if($lines == 20) {
            $data .= "<!-- more -->\n";
        }

        // HTML Code 替換
        $data = str_replace("&nbsp;", " ", $data);
        $data = htmlspecialchars_decode($data);
        $data = str_replace('<meta http-equiv="content-type" content="text/html; charset=utf-8">', '', $data);
    }

    fclose($fp);

    // HC_Emoticons 錯誤替換
    $data = str_replace('blog/emo','emo',$data);

    file_put_contents($file, $data);
}
?>

```

我用上面這兩個小程式轉完了五百多篇文章，當然不會完全沒有問題。不過，因為我用的外掛不多，加上圖片大多數都已經在 Flickr 上面了，所以轉換起來也沒有什麼太大的問題。而因為是使用 Markdown 的關係，有許多跳脫符號是必須要去留意的，這個可能就真的得土法煉鋼，~~用正規作掉~~慢慢看了。

### Generate too long

這是這個部落格系統唯一的問題癥結點吧。雖然龍哥有提過使用 `rake isolate` 跟 `rake integrate` 可以用於測試文章時使用，可以大幅簡短 `rake generate` 的運算時間。不過，當我要發佈的時候，還是得面臨一次全部重新運算的問題。所以，我就想到幾個比較~~垃圾~~取巧的方法來避開。

- 既然他要運算，那就給他算。
- 給他算的是新的文章，舊的文章我先搬走。
- 等他算完在把新文章蓋入舊的文章中。
- 搬回 public 之後就可以上線了。

由於我是放在 Heroku 上面，我寫得 shell-script 應該是只有我自己合用，如果想改的人請自便。

```bash
#!/bin/bash 

[ ! -f _config.yml ] && echo "You are not under octopress directory." && exit 0;

# 找出在 10 分鐘以內**沒有**修改過的 markdown 檔案，-mmin 單位是分鐘。
TIMESTAMP=10
# 利用 sed 把檔案洗出來並重新組合成 public 底下的結構
# 依照 _config.yml 所設定的 permalink: /blog/:year/:month/:day/:title/
# 所以這裡的輸出結果是 \/blog\/\1\/\2\/\3\/\4\/
# MAINPATH="blog"
# SUBPATH="\1\/\2\/\3\/\4"
# 如果你的 permalink 有另外做設定，請自行修改
# 例如我的 permalink: /entry/:title/
# 就設定為 entry\/\4
# \1 代表年
# \2 代表月
# \3 代表日
# \4 代表標題(title)
MAINPATH="entry"
SUBPATH="\4"

FILES=`find ./source/_posts/ -type f -name "*.markdown" -mmin +$TIMESTAMP | sed -e p -e "s/\.\/source\/_posts\/\([0-9]\{4\}\)-\([0-9]\{2\}\)-\([0-9]\{2\}\)-\([^.]\+\).markdown/\.\/public\/$MAINPATH\/$SUBPATH\//g" | xargs -n 2`

# 建立暫存資料夾
mkdir -p tmp
mkdir -p tmp/source/
mkdir -p tmp/public/

for (( index=0; index<${#FILES[@]}; index++ )); do
    while IFS=' ' read -ra FILE; do
        # 把 source/_posts 跟 public 的文章目錄移動到暫存資料夾
        cp "${FILE[0]}" "./tmp/source/"
        cp -r "${FILE[1]}" "./tmp/public/"

        TT=`echo "${FILE[0]}" | sed -e "s/\.\/source\/_posts\///g"`
        # 只取文章開頭八行的設定，回寫 source/_posts
        # 這個動作是很危險的！
        # 這麼做是為了確保 Archive 跟 Categories 能夠整正常產生。
        TS=`head -8 ./tmp/source/"$TT"`
        echo "$TS" > "${FILE[0]}"
    done <<< "${FILES[$index]}"
done

# 重新產生網站的檔案
rake generate

# 把檔案拷貝回去
find ./tmp/public/ -type d | xargs -n1 -I@ cp -r @ "./public/$MAINPATH/"
cp ./tmp/source/*.markdown ./source/_posts/

```

這個 shell-script 有個**非常危險的回寫動作**，要用之前，請確定你對 shell-script 有一定的認識，不然如果發生什麼意外，我可不能擔保喔！