かずぽんブログ
kt-msgpackを改造してKyotoTycoonを操作できるProcedureを便利にしてみた

KyotoTycoon では.so.dylibといった共有ライブラリによるプラグインをサポートとして、プラグインとして、memcachedプロトコルを実装したプラグインや、msgpack-rpcで使えるようにした kt-msgpack がある。 kt-msgpack では、msgpack-rpc を利用しているので、同期的なProcedureの呼び出しはもちろん、非同期なProcedureの呼び出しや、レスポンスを返さない通知的なProcedureの呼び出しでKyotoTycoonのデータをいじれるようになっている。 ですがですが、ソースを見てみると、KyotoTycoonで提供しているProcedureがあまりにも少ないことが分かったので、git にあるプロジェクトをforkしてちょっと充実させてみた。

充実させたProcedureたち

今回の改造で、充実&追加したProcedureは以下な感じ。

  • ping
  • echo
  • status
  • add
  • set
  • get
  • remove
  • append
  • seize
  • clear
  • replace
  • cas
  • increment
  • increment_double
  • match_prefix
  • match_regex
  • set_bulk
  • remove_bulk
  • get_bulk
  • vacuum
  • synchronize

データ操作系や検索系、そしてバルク操作系があるので、これぐらいあれば何とかことは足りるかと。 pingという変な名前のProcedureがありますが、これはvoidに相当し、msgpack-rpcの制約(というかIDLからC++のコードを生成するツールの制約?)でProcedureが別名にしています。 詳細はここのProceduresの一覧をご覧ください。

サポートしなかったProcedureたち

今回諸事情サポートしなかったProcedureは以下な感じ。

  • report
  • play_script
  • tune_replication
  • cur_jump
  • cur_jump_back
  • cur_step
  • cur_step_back
  • cur_set_value
  • cur_remove
  • cur_get_key
  • cur_get_value
  • cur_get
  • cur_seize
  • cur_delete

reportplay_scripttune_replication はちょっと作りこみ(場合によってはKyotoTycoonをいじる必要があるかも)が必要なので今回は対応していない。

cur_xxx系は、KyotoTycoonのアーキテクチャとmsgpack-rpc(mpio)のアーキテクチャが異なっているので、実装するのはちょっとしんどい。KyotoTycoonではセッション毎にローカルストレージにcursorオブジェクトを保持することで対応できているのだが、msgpack-rpc(mpio)では、KyotoTycoonのような感覚でセッションを使える仕組みがないので、同じ機能の実装はmsgpack-rpcを改造でもしない限りちょっと辛いところだ。(というより、自分がmsgpack-rpcに同じような機能があるのを知らないだけ?)

そもそも、cursorの操作については、KyotoTycoonの作者のブログに書いてある意見と同じく、ネットワーク越しに長期間リソースを占有するようなものは、サーバのリソースの無駄遣いだと思う。そのようなことをしたい場合はplay_scriptのようなストアドプロシジャ的なスクリプトでcursor操作をして、さくっと用を足してしまえばいいと個人的に思っている。 なので、今後は、cur_xxx系のProcedureは対応しない方向で考えている。

パフォーマンス測定

せっかく、Procedureを充実させたんで、一番気になるバルク系のデータ操作のパフォーマンスを測ってみた。 計測は5回行い、平均値を計る。サーバ、クライアントは同じマシン上で測定した。

測定プログラム

KyotoTycoon をインストールした際にバンドルされてくるktremotetestとそれをkt-msgpackを向けに改変した、ktmpremotetestによって行う。 また、比較のためktremotetestで、KyotoTycoonのHTTPとBinaryも計測する。 ちなみに、ktmpremotetestは今回改造したこちらからgit cloneしてインストールすると、kt-msgpackといっしょにインストールされる。

マシン環境

マシン環境は以下のとおり。

  • Macbook (13-inch, Early 2009)
  • OS: Mac OS X Lion 10.7.3
  • CPU: 2 GHz Intel Core 2 Duo
  • Memory: 4 GB 667 MHz DDR2 SDRAM
  • HDD: 256GB (FUJITSU MHZ2250BH FFS G1 Media SATA)

KyotoTycoonの起動オプション

KyotoTycoonの起動オプションは以下で起動する。

$ ktserver -th 8 -lz -plsv /opt/local/libexec/libktmsgpack.dylib -plex "port=18801#thread=8" "casket.kct#bnum=2000000#opts=ls#ktopts=p"
  • バケット数は100万レコードの2倍値(bnum=2000000)
  • データベースオプションは、4バイトアドレッシング、線形リスト(opts=ls)
  • パフォーマンスをちゃんと計測するために、KyotoTycoon側のスレッド数とkt-msgpackプラグインのスレッド数を同じ値に設定(-th 8, thread=8)
  • ログ出力はなし(-lz)
  • データは永続化(ktopts=p)

測定内容

KyotoTycoonの作者のこの記事と同じことをする。サーバに対して、「00000001」「00000002」といった文字列のキーと値を持つレコード合計100万件の読み書きを行う。 以下のコマンド、set系9パターン、get系9パターン、計18パターンを計測する。

  1. ktremotetest bulk -th 4 -set -bulk 1 250000
  2. ktremotetest bulk -th 4 -set -bulk 10 250000
  3. ktremotetest bulk -th 4 -set -bulk 100 250000
  4. ktremotetest bulk -th 4 -set -bin -bulk 1 250000
  5. ktremotetest bulk -th 4 -set -bin -bulk 10 250000
  6. ktremotetest bulk -th 4 -set -bin -bulk 100 250000
  7. ktmpremotetest bulk -th 4 -set -bulk 1 250000
  8. ktmpremotetest bulk -th 4 -set -bulk 10 250000
  9. ktmpremotetest bulk -th 4 -set -bulk 100 250000
  10. ktremotetest bulk -th 4 -get -bulk 1 250000
  11. ktremotetest bulk -th 4 -get -bulk 10 250000
  12. ktremotetest bulk -th 4 -get -bulk 100 250000
  13. ktremotetest bulk -th 4 -get -bin -bulk 1 250000
  14. ktremotetest bulk -th 4 -get -bin -bulk 10 250000
  15. ktremotetest bulk -th 4 -get -bin -bulk 100 250000
  16. ktmpremotetest bulk -th 4 -get -bulk 1 250000
  17. ktmpremotetest bulk -th 4 -get -bulk 10 250000
  18. ktmpremotetest bulk -th 4 -get -bulk 100 250000

-thは、起動スレッド数を意味する。 -setset_bulkによるレコード設定を意味する。 -getget_bulkによるレコード設定を意味する。 -bulkは、バルク操作で一度に設定/取得するレコード数を意味する。 ktremotetest-binはBinaryプロトコルによるバルク設定/取得を意味する。このオプションがない場合は、HTTPプロトコルによるバルク設定/取得になる。

測定結果

100万件のバルク操作の計測結果は以下のようになった。

計測1 計測2 計測3 計測4 計測5 average
1.HTTP set 1 bulk 124.643 126.641 119.626 125.788 140.967 127.533
2.HTTP set 10 bulk 20.731 17.873 15.776 16.058 15.281 17.1438
3.HTTP set 100 bulk 7.052 6.719 8.246 6.54 6.778 7.067
4.Binary set 1 bulk 70.699 71.705 66.925 70.883 70.841 70.2106
5.Binary set 10 bulk 8.44 9.193 8.939 9.877 8.776 9.045
6.Binary set 100 bulk 4.449 4.923 4.341 4.412 4.309 4.4868
7.msgpack-rpc set 1 bulk 78.078 85.017 79.846 77.657 87.636 81.6468
8.msgpack-rpc set 10 bulk 16.943 14.585 13.157 13.645 17.013 15.0686
9.msgpack-rpc set 100 bulk 7.261 7.19 6.894 7.659 10.003 7.8014
10.HTTP get 1 bulk 117.963 124.22 122.057 120.705 132.164 123.4218
11.HTTP get 10 bulk 16.756 19.225 18.153 18.522 21.171 18.7654
12.HTTP get 100 bulk 8.068 8.733 11.251 9.193 9.028 9.2546
13.Binary get 1 bulk 61.831 72.635 74.087 70.9 75.88 71.0666
14.Binary get 10 bulk 9.883 10.741 11.739 10.249 13.278 11.178
15.Binary get 100 bulk 5.861 7.47 6.11 6.061 6.048 6.31
16.msgpack-rpc 1 bulk 79.438 89.539 74.367 92.129 91.659 85.4264
17.msgpack-rpc 10 bulk 18.262 19.146 16.453 20.083 19.446 18.678
18.msgpack-rpc 100 bulk 11.175 10.415 10.667 10.95 14.237 11.4888

やっぱり、Binaryがパフォーマンスいいですね。msgpack-rpcも結構いい感じパフォーマンスでています。この計測結果からみると、パフォーマンスとしては、

Binary > msgpack-rpc > HTTP

といった感じでしょうか。まあ、bulk操作で扱うデータ数を増やせば、まあそれなりの速度で処理することができるので、どれを利用しても実運用上特に問題ないかあと。同期、非同期の通信を柔軟に選択できつつ、パフォーマンスが確保できるっていうのがメリットなのかもしれない。(まあ、Node.jsを利用すれば、それできますけど。。。)

まとめ

kt-msgpackをforkして、KyotoTycoonで提供するProcedureを充実させました。この改造により他の言語でもmsgpack-rpcを利用することで、set、getによるデータ操作、バルク一括操作、検索、そしてcas、incrementが利用できるようになりました。msgpack-rpcのバルク操作のパフォーマンスも、HTTPとBinaryの間なので、通信機能で柔軟にロジックを制御したいっていう場合には、KyotoTycoonを使うユースケースでは、kt-msgpackを選択するのはいいかもしれません。

Jadeのテンプレート継承を使ってみた

node.jsの数あるテンプレートエンジンのうちJadeというのものがあり、expressで使っているのですが、0.16辺りでテンプレート継承をサポートしてたみたいなので使ってみた。

使い方

extendsblockを使うことによってテンプレート継承を行う。

継承元となるテンプレートはこんな風に書く。ファイル名は base.jade としておく。

//- base.jade
!!! 5
html
  head
    h1 My Site
    block scripts
      script(src="/jquery.js")
  body
    block header
      header
        p some header content
    block content
    block footer
      footer
        p some footer content

blockには名前をつけることができる。このコード例は、Webサイトでよく見かけるレイアウトである、headercontentfooterという風に名前を付けて、それぞれにHTMLのコンテンツを書いてある。blockという書き方は、python の jinja や django を触ったことがある人には馴染みがある書き方であろう。

次にこの base.jade を継承したテンプレートはこんな感じになる。ファイル名はextend.jadeとしておく。

//- extend.jade
extends ./base

block scripts
  script(src="/underscore.js")

block content
  h1 title
  p hello world

継承するにはextendsに元となるテンプレートファイルのパスを指定する必要がある。このコード例では、このテンプレートファイルと同じカレントにあるパスを指定している。

extendsの指定がすんだら、後はblockのコードを書くだけ。継承元のblockの内容を上書きしたい場合は、block xxxという風な感じで書いていくだけ。継承元のblockの内容を上書きしない場合は継承先のテンプレートでは特にも何も記載しない。上記のテンプレートファイルをjadeコマンドでHTMLファイルを生成するとファイルの中身はこんな風になる。

$ jade -o {pretty:true} extend.jade 

  rendered extend.html

$ cat extend.html
<!DOCTYPE html>
<html>
  <head>
    <h1>My Site
    </h1>
    <script src="/underscore.js"></script>
  </head>
  <body>
    <header>
      <p>some header content
      </p>
    </header>
    <h1>title
    </h1>
    <p>hello world
    </p>
    <footer>
      <p>some footer content
      </p>
    </footer>
  </body>
</html>

block headerblock footerは、extend.jadeでは上書きしていないので、base.jadeの内容で。block scriptsについては、extend.jadeの内容で上書き。そしてblock contentについては、extend.jadeの内容で生成されていることが分かるかと思う。

jadeによるテンプレート継承の基本的な使い方はこんな感じ。

append/prepend

jadeは基本上書きによるテンプレート継承なのだが、blockの直後や直前に追加するようなテンプレート継承もできる。

あるblockの直後に追加する継承はappendを利用する。ここでのファイルは、extend-append.jadeとする。

//- extend-append.jade
extends ./base

block append scripts
  script(src="/underscore.js")

このコード例では、scriptsに対してscriptタグを追加するようにしている。書き方としては、block append xxxという風な感じになる。これを実際にjadeコマンドでHTMLファイルを生成するとこんな感じになる。

$ jade -o {pretty:true} extend-append.jade 

  rendered extend-append.html

$ cat extend-append.html
<!DOCTYPE html>
<html>
  <head>
    <h1>My Site
    </h1>
    <script src="/jquery.js"></script>
    <script src="/underscore.js"></script>
  </head>
  <body>
    <header>
      <p>some header content
      </p>
    </header>
    <footer>
      <p>some footer content
      </p>
    </footer>
  </body>
</html>

extend-append.jadeで書いたblock append scriptsの内容がextend.jadeblock scriptに対して追加されていることが分かるかと思う。

逆に、あるblockの直前に追加する継承はprependを利用する。ここでのファイルは、extend-prepend.jadeとする。

//- extend-prepend.jade
extends ./base

block prepend scripts
  script(src="/underscore.js")

extend-append.jadeの例と同じく、このコード例では、scriptsに対してscriptタグを追加するようにしている。書き方としては、block prepend xxxという風な感じになる。これを実際にjadeコマンドでHTMLファイルを生成するとこんな感じになる。

$ jade -o {pretty:true} extend-prepend.jade 

  rendered extend-prepend.html

$ cat extend-prepend.html
<!DOCTYPE html>
<html>
  <head>
    <h1>My Site
    </h1>
    <script src="underscore.js"></script>
    <script src="/jquery.js"></script>
  </head>
  <body>
    <header>
      <p>some header content
      </p>
    </header>
    <footer>
      <p>some footer content
      </p>
    </footer>
  </body>
</html>

ちなみに、append/prependを利用する場合は、blockを省略することができる。

継承元を利用しながら前後に対して拡張ができるかと思ったら。。。

このappendprependを両方を使えば、jinja の superみたいに、継承元のコードを利用しつつ、その前後にコードを追加できるんじゃね?と思って、

//- extend-both.js
extends ./base

block append scripts
  script(src="/underscore.js")

block prepend scripts
  script(src="/hoge.js")

という風なコード書いてみて、できるかどうか確認したみたのだが、jadeコマンドでHTMLファイルを生成してみると、生成されたファイルの中身確認してみると、

$ jade -o {pretty:true} extend-both.jade 

  rendered extend-both.html

$ cat extend-both.html
<!DOCTYPE html>
<html>
  <head>
    <h1>My Site
    </h1>
    <script src="/hoge.js"></script>
    <script src="/underscore.js"></script>
    <script src="/jquery.js"></script>
  </head>
  <body>
    <header>
      <p>some header content
      </p>
    </header>
    <footer>
      <p>some footer content
      </p>
    </footer>
  </body>
</html>

とまあ、全然意図しない結果に。

うーん、includeyieldでやるしかない感じかなあ。

まとめ

  • jadeでテンプレート継承はextendblockを使うことができる
  • jadeでのテンプレート継承は基本上書き継承
  • 既存のコードを利用しつつ、継承したい場合は、append/prependを使う

コード

これまでのコードは、gistに置いておきました。

lessのエスケープ機能を使えばTumblrでもよりデザインが簡単に

前回のブログで、lessを使ってTumblrのテーマをカスタマイズするには、Tumblrのテンプレートのシンタックスとlessのシンタックスと相性が悪いため、

$ cat style.less
@mycolor: '__{color:Background}__';
body {
    background: @mycolor;
}

$ lessc style.less
body {
    background: '__{color:Background}__';
}

$ lessc style.less | sed -e s/\'__\{/\{/g -e s/\}__\'/\}/g > style.css

$ cat style.css
body {
    background: {color:Background};
}

っていう何か七めんどくさいHackっぽいことで、Tumblrのテーマに適用可能なCSSを生成していたと思います。 が、実は、lessのエスケープ機能を使えば、簡単にできるっぽい。

$ cat style.less 
@main_bg_color: ~'{color:Background}';
body {
    background: @main_bg_color;
}

$ lessc style.less 
body {
    background: {color:Background};
}

文字列の前にチルダ(~)をつければいいだけ。 これだけで、Tumblrのテーマのシンタックスにあう形のCSSを生成できるようになります。

このエスケープ機能、うーん、1.1.0のときに実装されていたんですね。。。ドキュメントの確認ってやっぱ大事ですわ。

4GというLTEでもない変なものに移行してみようかなと考えてみる

最近、ソフトバンクさんから話題になっていた ULTRA WiFi 4G が発売されたみたいだけど、そろそろこのPocketWiFi C01HWからアップグレードしたいなあと思ったので、ちょっと検討してみた。

端末の比較

今使っている Pocket WiFi C01HW と ULTRA WiFi 4G とをスペックで比較してみた。

Pocket WiFi C01HW ULTRA WiFi 4G
通信方式 下り最大7.2Mbps、上り最大5.7Mbps 下り最大76Mbps、上り最大10Mbps
接続端末数 5台 10台
バッテリー駆動時間 最大約4時間 最大約9時間

スペック的に、明らかに乗り換えた方がいい感じです。

データ通信料金の比較

続いて、ULTRA WiFi 4G に適用されるこれと今利用しているこれとのデータ通信料金を比較をしてみた。

データし放題 4Gデータし放題フラット
1,400(20,850パケット)〜4,380(91,800パケット)円/月 5,980円/月(5GB超は、最大通信速度は128kbps)

といった感じ。

4Gデータし放題フラットプランについては、今キャンペーンをやっているので、その期間中だと4,980円/月になる模様。また、ソフトバンクでiPhoneなどのスマートフォンを利用している場合は、さらにスマホセット割というのが効いて、3,880円/月になるみたい。しかも、4Gデータ通信基本料金は無料ときた。期間は2012/04/30までみたいなので、今、加入しておいた方がとかなりお得っぽい。

現状、データし放題プランで月々、Maxの4,380円払うぐらい使っているので、4Gのプランは、値段的に少し安くなるし、スピードも速くなると思うので移行してもいい感じ。データ通信量が5Gバイトを超えた場合、通信速度が128kbpsに制限されるのは、嫌ですが。。。まあ、キャリア的にはある程度制限しないといけないのは、回線品質を維持(ソフトバンクさんはまあ繋がらないことが多いですが。。。)するためには、しょうがないのかな。

現状の通信データ量を確認してみる

現状、利用しているデータし放題は、主にカフェなどの移動先の場所で作業するときに使ってるんですが、愛用のMacで常時接続で使う事が多いので、現状月にどのぐらい量のデータ通信しているかどうか気になるところ。確認もせずに4Gのデータ通信プランに移行してスピードが制限されてしまっては、今更128kbpsというスピードではちゃぶ台返ししたくなるほど、作業に支障がでそう。

移行するメリットがあるかどうか確かめるため、MySoftBankで直近3ヶ月間のデータ通信量を確認してみた。

2011月11月 2011月12月 2012月1月
パケット数 6,892,320 14,340,338 8,601,011
バイト数 882,216,960 1,835,563,264 1,100,929,408

5Gバイト(5,368,709,120バイト)の制限に届かないので特に大丈夫そう。

iPhoneも4G経由で大丈夫?

現状の利用では、5Gバイトの制限に引っかからないので、今自分が使っているiPhoneを4G経由で利用しても問題なさそうな気が。大丈夫かどうかこちらもチェックしてみた。

2011月11月 2011月12月 2012月1月
パケット数 9,081,766 7,654,447 4,092,876
バイト数 1,162,466,048 979,769,216 523,888,128

ほほう。以外と使っていると思ったら、それほどでも。まあ、動画とかはあまり見ないですからね。 直近3ヶ月の内でも、多い時で、1Gバイト超えてるといった感じでしょうか。これなら、4G経由で使っても問題なさそうです。

スマホ割引が適用されなくなるけど、iPhoneで契約しているパケットし放題フラットからパケットし放題Sに変更した方が、料金全体ではこちらの方が安くなりそうなのでこっちがいいかも。Maxで使ったとしても5,980円/月ですもの。

どうするか

というわけで、4Gの新しいプランは速度が今より速く、値段料金も今より安くできるので、移行してみたいところです。 ドコモさんのXiもいいんですけど、コストパフォーマンスに合わないかなあと。回線品質も良さそうなんですけどね。

個人的に、4Gに移行する上での気になる点は、

  • 月々の端末代はどのぐらいかかるのか
  • 現状のプランからの変更で解約金が発生するのか
  • エリア範囲外で利用したときの速度

ぐらいかな。 とりあえず、確認してみて問題なさそうだったら、移行してみます。

lessでTumblrのブログテーマをカスタマイズする

Tumblrでは、各ブログにある、[表示カスタマイズ] → [編集HTML] でテーマをカスタマイズすることができます。 カスタマイズにするに当たって、ここにある仕様というかTumblr独自のタグや変数を元にカスタマイズするわけですが、手がこんだデザインにしたい場合は、CSSをガリガリ書くことになるかと。

ただ、どんどんデザインの規模が大きくなってくると、CSSのコードがとんでもないことになり、lessとかsassといったCSS拡張したものを使いたくなるかと思います。 ここでは、愛用するlessでTumblrのブログのテーマのカスタマイズを試してみました。

lessの利用形態の選定

lessの利用方法としては、

  1. クライアント(ブラウザ)側で動的にCSSを生成する
  2. サーバ側で動的にCSSを生成する
  3. 静的なCSSを生成する

というパターンがあるかと。 それぞれのパターンについて簡単に説明すると、 1.は、headタグ内に

<link rel="stylesheet/less" type="text/css" href="styles.less">
<script src="less.js" type="text/javascript"></script>

という感じにすることで、lessファイルをlessのjavascritがコンパイルしてCSSを生成する方法。

2.は、クライアントからリクエストがあったときにサーバ(web)側でlessファイルを動的にCSSファイル(またはstyleタグ)を生成して、それをクライアント側に渡すという方法。 node.js (express) のコードを例にするとこんな利用イメージ。

app.get('/', function (req, res) { // request handler
    fs.readFile('./style.less', 'utf-8', function (err, data) {
        var parser = new (less.Parser);
        parser.parse(data, function (e, tree) {
            res.send('<html><head><title>index</title><style>' + tree.toCSS() + '</style></head><body><h1>hello world</h1></body></heml>');
        });
    });
});

3.は、lessファイルをlesscというコマンドによってCSSを生成し、それをCSSファイルかまたは、HTMLのstyleタグに設定して、従来どおりクライアントに渡すという方法。 lesscコマンドの基本的な使い方は、

$ lessc style.less > style.css

という感じで、lessファイルを指定すると、CSSを出力するので、それをリダイレクトで保存するようにする。 ちなみに、less はミニファイもサポートしてて、lesscコマンドでは、

$ lessc --compress style.less > style.css

という風に、--compressオプションを指定すると、ミニファイされたCSSが出力される。

1.〜3.のぞれぞれのメリット、デメリットについては調べたり、ちょっと考えれば分かると思うのでここでは説明しません。

で、Tumblrでは、どれでやったんだっていう話なんですが、3.でやりました。

2.についてはサーバ側でテーマのレンタリングをカスタマイズ仕組みがTumblrにはないのでどう考えてもあり得ません。 1.についてはTumblrでは、ここで静的ファイルをアップロードできるのですが、lessファイルはどう見ても対象外みたいなのでこれも使えません。 3.については設定でHTMLをガリガリカスタマイズできるので、styleタグに生成したCSSを設定できるので、必然的にこれになります。

lessを使ってみたのだが。。。

ここにある内容を読んでみると分かると思うのですが、Tumblrでは独自のテンプレート?を使っているみたいで、なんかシンタックスが{Title}とか{block:Text}{/block:Text}とかMustacheに似たものを使っています。

lessが従来のCSSと違って便利なものとして、変数があります。lessの変数は、

@mycolor: #ff2233;

というような感じで使います。 Tumblrではテーマのカラー、フォントなどのカスタマイズをユーザーに提供する手段として、metaタグを使っており、カラー、フォント、画像などに対応する変数があります。 ですので、こういったCSSに関係する変数は、lessの変数としても使いたくなります。

ですが、ですが、Tumblrのテンプレートの変数は、

{color:Background}

というようなシンタックスであり、lessが変数として扱うことができないので、非常に相性が悪いです。

@mycolor: {color:Background};

のようにしてもlesscコマンドではエラーになります。 何らかの方法でマッピングが必要になります。

回避方法

いろいろと考えた結果、Tumblrのテンプレートを変数を文字列としてlessの変数に設定することでこの問題に対応することにしました。

lessの変数は、文字列を扱えるので、lesscコマンドでCSSの生成が可能になります。そして、生成されたCSSをsedコマンドで置換することでTumblrで利用可能なCSSに仕上げます。

$ cat style.less
@mycolor: '__{color:Background}__';
body {
    background: @mycolor;
}

を、lesscコマンドを通すと、

$ lessc style.less
body {
    background: '__{color:Background}__';
}

という風にCSSが出力されます。 これを下記のようにさらに、sedコマンドでフィルタすると

$ lessc style.less | sed -e s/\'__\{/\{/g -e s/\}__\'/\}/g > style.css
$ cat style.css
body {
    background: {color:Background};
}

となり、こちらで想定しているCSSが生成されるようになります。

実際にやってみる

では、実際にlessを使ってTumblrのカスタマイズをやってみましょう。ソースは、gistからgit cloneしてきましょう。

$ git clone https://gist.github.com/1873913
$ tree
.
|-- Makefile
|-- style.less
`-- template.html

カスタマイズしたテンプレートを適用する

TumblrのブログのHTML編集で、template.htmlの内容を下記コマンド等でコピー&ペーストします。

$ cat tempalte.html | pbcopy

ちなみに、pbcopyコマンドはMac OS Xで利用できるクリップボードにコピーするコマンドです。

CSSをジェネレートしてテンプレートに適用する

makeコマンドでCSSファイルをジェネレートします。

$ make
lessc ./style.less | sed -e s/\'__\{/\{/g -e s/\}__\'/\}/g > ./style.css
lessc --compress ./style.less | sed -e s/\'__\{/\{/g -e s/\}__\'/\}/g > ./style.min.css

このmakeでは、ミニファイ版(style.min.css)と通常版(style.css)のCSSファイルをlesscコマンドでコンパイル生成しています。

生成後、CSSファイルの内容を以下の画像のようにTumblerのテンプレートにコピー&ペーストします。今回はミニファイ版を使いたいと思います。

$ cat style.min.css | pbcopy 

CSSを適用すると以下のように右側のプレビューが変わると思います。

ちなみに、CSSを適用してもたまに変わらないときがあるみたい。なので、一旦表示のカスタマイズを閉じてから、再度カスタマイズのこの画面を開くと適用されているかどうか確認できます。

まとめ

ちょっとした工夫(Hack)をすれば、Tumblrでもlessを使ってCSSでブログのデザインをすることができるようになりました。Tumblrではモバイル用の表示も設定すれば、iPhone(androidも?)に最適化してくれますが、このやり方を応用すれば、CSS3 Media Queries を使えば自分でレスポンシブWebデザインにも対応した、独自のテンプレートが作れるので面白いかもしれませんね!