あと味

たくさん情報を食べて、たくさん発信すると、あとになって味わい深い。

Perlでメソッドチェーンのメソッドを動的に決定する

Perl でメソッドを呼び出す時、

$class->$method;

みたいな呼び出し方できるのは知ってたけど、

$class->${ \'method' }

みたいな感じで、文字列のスカラーリファレンスをデリファレンスすることでも同じことができることを知った。

これを用いることでメソッドチェーンのメソッドを動的に決定することができる。

上記のように pass とかいうメソッドを用意しておけば、不要なメソッドはスキップするということもできるので、そのチェインを実行するかどうかも動的に決定できる。

コードは結構キモい感じだけど、それなりに実用性はありそう。

MTDDC 2013の感想文

感想文書くの遅くなりましたが、先日、MTDDC 2013に参加しました。

LTについて

Data APIをさわるキッカケを作りたいなと思って、さわる前にLT応募したんですけど、実際にさわってみるのはギリギリになってしまって、焦ってたんですが、5分だったのでなんとかなりました。

とりあえず、できることを確認して、サンプルアプリ作ってみて、ファーストインプレッションをまとめた感じです。

下記にLTのスライドを置いておきました。

LT用に作ったサンプルアプリケーション

Movable Type Data APIは、結構ポテンシャルが高いなと思っていて、スライドにも書きましたが、MTの管理画面を作るだけじゃなくて、JSONを使ったフロントエンドアプリが普通に作りやすくなりますねってことを紹介するために、ToDoアプリケーションを作りました。

とは言え、作ったというと大げさで、下記の記事にあるチュートリアルそのままで、CoffeeScript + Data APIで少し書き直しただけです。

作ったサンプルは下記に置いておきました。

Data APIはURLの設計キレイだし、JSON/REST APIなので、Backbone.jsとの親和性がとても高いと思いました。バックエンドはMTをセットアップしただけで利用できるので、Backbone.jsでフロントエンドのアプリを書くだけで済みます。アプリのプロトタイプ作るのに活用するのもいいなと思いました。

後、フロントエンドの人達も活用しやすいと思います。フロントエンド技術だけでも、Data APIを使って、Webアプリを作れるとおもいますし、DBのデータの管理アプリケーションにMTが使えます。

MT6について

やはりData APIに注目が集まっているようです。

自分もData APIは、MTの静的ファイル出力やMTML、Perlなど、MTのアイデンティティになる要素を一切排除できる仕組みなので、かなり大胆な機能追加だなと思いました。

今後Data APIがどのような使い方をされていくのか楽しみではあります。

あと、長谷川恭久さんを中心にMTがどのようにリデザインされていくのかも注目です。

新しいMTはSimple, Smart, Speedyがキーワードとのことですが、今のMTは残念ながらどのキーワードもしっくりとマッチしていないように思うので、これからそのキーワード通りに変化していくことを期待しています。

MTがStyleDoccoに対応したっぽい

developブランチのcommitログ見てたら下記のコミットを見かけた。

StyleDocco 形式のStyleGuideを整備したようで、StyleDoccoを使ってスタイルガイドが出力できるようになってた。これによって既存のスタイル探すのにソース見て調べなくても良くなりそう。developブランチの話なので確定ではありませんが。

出力結果

f:id:jdg:20130729235752p:plain

あと、話は変わりますが、MTDDCにてLTをすることになったので、今週は頑張ってスライド作ります。

Perlのデータ構造を意識しつつ、常にmt:loopタグを使う話

案件で試したわけではなく、かと言って試せる機会もないので、あくまで一つの提案です。

mt:loopタグの良い文書がGithubのmovabletype/Documentation Wikiにあります。

特筆すべき箇所が、以下のように書かれた説明です。

Movable Typeの再構築の処理を行う場合、データベースへのアクセスが多くなります。

例えばブログ記事のタイトル一覧をページ内で複数個所で利用するケースの場合、 タグを何箇所にも書くと、その個数分データベースへアクセスしに行く事になり再構築時にオーバーヘッドが多くなります。

そこで、一旦データを配列やハッシュに格納し、ループを各所でまわす事でデータベースへのアクセスを減らす事が可能となります。

データを配列やハッシュに格納すれば、あらゆるコンテナタグと呼ばれる類のタグは、mt:loopの共通のインターフェイスによって利用でき、非常にわかりやすくなると感じました。

mt:loopのインターフェイスを利用することで、もれなく、__first__, __last__, __odd__, __even__, __index__, __counter__などの特殊変数が利用できるのも大きいです。

極端に言えば、mt:entriesやmt:pages等は、「mt:loopに渡すためのデータの構築のみに使うようにする」みたいな話です。

mt:entriesを例に考えます。

mt:entriesは、通常、以下のように使うでしょう。

<mt:entries>
title: <mt:entrytitle>
text: <mt:entrytext>
more: <mt:entrymore>
</mt:entries>

これをPerlのデータ構造で表すと以下のような形で考えるのが自然ですね。

my $entries = [
  {
    title => 'title1',
    text => 'text1',
    more => 'more1',
  },
  {
    title => 'title2',
    text => 'text2',
    more => 'more2',
  },
  {
    title => 'title3',
    text => 'text3',
    more => 'more3',
  },
];

これをそのままmt:loopで使えば、かなり楽にmt:loopを活用できそうです。mt:varでアクセスできる値は、実際にはPerlのデータ構造ですからね。

結果、以下のようにテンプレートを書くことで、先ほどのデータ構造を自然に作れることを確認しました。無名ハッシュリファレンスをどうやって表現するかが悩ましいところでしたが、割とスムーズにできました。

<mt:entries>
  <mt:sethashvar name="entry">
    <mt:entrytitle setvar="title">
    <mt:entrybody setvar="text">
    <mt:entrymore setvar="more">
  </mt:sethashvar>
  <mt:var name="push(entries)" value="$entry">
</mt:entries>

以下のようにmt:loopで利用します。

<mt:loop var="entries">
  <mt:if name="__first__">
    <div class="entries">
  </mt:if>
      <article class="entry<mt:if name='__first__'> first</mt:if><mt:if name='__even__'> even</mt:if><mt:if name='__last__'> last</mt:if>">
        <h1><mt:var name="title"></h1>
        <div class="entry-text">
          <mt:var name="text">
        </div>
  <mt:if name="more">
        <div class="entry-more">
          <mt:var name="more">
        </div>
  </mt:if>
      </article>
  <mt:if name="__last__">
    </div>
  </mt:if>
</mt:loop>

これであらゆるコンテナタグを、常にmt:loopで回せそうな気がして参りました。試してませんが、元のデータ構造がもう少し複雑でも、mt:loopのネストでうまくデータにアクセスできるように思います。

個人的には、上記のmt:ifの分岐すらお腹いっぱい感があるので、もう少しテンプレートを簡潔に書けるインターフェイスを作りたいなーと思ってはいます。

まとめ

共通のインターフェイスを使えて、DBアクセスも減らせるので、メリットが大きい気がしています。やたらめったらグローバルに変数を定義しているわけでもないので、お行儀も良いです。また、基本的に<mt:if name="foo">...</mt:if><mt:var name="foo">しか使わないので、シンプルにもなります。落とし穴あるかもしれませんが...。

おまけ

データ構造を逐一調べるために、下記のような単純なMTタグを定義して、あちこちにmt:dumpを散りばめながら動作を確認しました。

tags:
  function:
    Dump: >
      sub {
        use Data::Dumper;
        Dumper shift->stash('vars');
      }

config.yamlのみでプラグインのプロトタイプをサクッと作れるのは良いですね。

追記

コメント欄で同僚さんにコメントいただいたのですが、コレが自然に動くようになったのは、MT 5.2から だそうです。どおりで、今までサンプル見なかったわけだ。あと、「落とし穴あるかもしれませんが」の回答として、ダイナミックパブリッシングで挙動が異なるケースがあるそうです。ありそうですね...。

春のJAWS-UG 三都物語 2013でMTに関するLTしました

AWSを使ったこと、ほぼなかったんですけど、これをキッカケにして、今後は活用するようになりそうです。

発表内容をシェアするとともに、ちょっと考えることを書きます。5分という短い時間でしたが、伝えたいことは伝えられたんじゃないかと思います。

思ったこと

Wordpress界隈に比べて、MT界隈のAWSのノウハウは、ウェブを見る限りではまだ少ないように思います。

特に、Movable Typeは静的ファイル出力が前提のソフトウェアなので、S3やCloudFrontがもっと活用されるようになるといいなと思いますし、自分は今後活用しようと思います。

また、スライドの中では、管理画面なくてもいいじゃんみたいな話をしていますが、これは極端な話だったかもしれません。しかし、MTはPerlで書かれたソフトウェアなので、コマンドラインツールとの親和性は実際高いと思っています。CPANもあるし。

コードベースでMTを操作すること

ネタに走ってしまって、多分あまり伝わってないので、コードベースでMTを操作するということについては、本エントリでもう少し掘り下げることにします。

MT::Toolクラスのサブクラスを作れば簡単にコマンドラインツールを作ることができます。*1

管理画面経由にせよ、コマンドラインツール経由にせよ、使うのはMTのアーキテクチャです。MTのアーキテクチャは、管理画面に特化しているわけではなく、コードから利用することも可能です。コードから利用するのはWordpressより扱いやすいように思います。Perl製のソフトウェアということもありますが、こういう点がMovable Typeの方が弄っていて楽しいと思う理由なんだと思います。

MTは、ライブラリを直接useして利用できる作りにもなっています。*2

プラグインかtoolsスクリプトかの違いは、MTのオペレーションツールがブラウザかターミナルかの違いだけです。
自分は、コマンドラインツールが好きなので、今後、MTのコマンドラインツールをいろいろ作ることでしょう。コマンドラインツールをしっかり作ってしまえば、どうしても管理画面上から利用したい時には、ブラウザ用のインターフェイスを追加するだけで済むはずです。たぶん。

ついでなので、作りかけで途中になっていた、MTObjectImporterというプラグインをgithubに上げました。YAMLで記事をインポートしたいなと思って作り始めたら、JSONも構造にてるし、EntryとPageも構造似てるしってことになって、ひとつメタなプラグインにしました。

大したことは書いてありませんが、ライブラリをuseして利用できることを意識して作ってあります。こんな感じで、今後もまずはコマンドラインツール、必要に応じてブラウザ用のインターフェイスを用意する、みたいな感じで作ろうと思ってます。テストもしやすいですし。

まとめ

今後、MTらしさを生かしつつAWSを活用したいですね。

*1:perldoc MT::Toolしましょう

*2:githubのmovabletypeのtディレクトリを見よ

俺、今大阪におんねん

ごめんなさい、本当は関西弁まったく使えません。

昨年末から、アルファサード株式会社で働いています。今は主に製品サポートと製品開発を担当しています。

大阪勤務なので、大阪に引越しまして、今や大阪府民です。

これまでも、福井から関西の勉強会に参加することがありましたが、より参加しやすくなりますし、関西圏の方、仲良くしてください。

先日、Movable TypeのextlibディレクトリのCPANモジュールカタログ - あと味という記事の最後の方に、「来年はMovable Typeに本気で取り組みます。」と書いておりましたが、アルファサードPowerCMSというMovable Typeを拡張したCMSを開発している会社なので、嘘偽りなく、今年からはMTに本気で取り組むことになります。

Perlで仕事をしたいと思いつつ、Web制作で関わり弄ってて楽しかったMTと戯れながら、いちひよっこPerlプログラマとして頑張っていきたいと思う所存です。

今後はMTの記事やPerlの記事が増えることと思いますが、個人のライフワークとして、特に関数型言語には興味を持ち続けると思うので、そういう記事も継続的に書いて行きたいと思います。

ちょっとフロントエンドから離れた感はあるのはありますが、未だ興味の対象としては大きな要素なので、今後も勉強していこうと思います。

ということで近況報告でした。

サクッとPSGIなMTOSの開発環境を用意する方法

MTは5.2.2からPSGI対応したということで、今までPSGIアプリケーションをMojoliciousやMENTAで作ることもあった自分としては、かなり嬉しい出来事でした。

Mojoliciousなどは、開発用のPSGIサーバーも同梱されていて、ポータブルだし、サクッと開発環境を用意して、プログラム書き始めることができるのがとても良いですね。

どのCMSApacheの設定から始めて、DB作って、それらの開発環境を外に持っていく時も同じようなことをして云々かんぬんというのに辟易していました。Cartonなどを利用すれば、Perlの実行環境を除いて、アプリケーションディレクトリ配下にアプリケーションが動作するすべての条件を含めることができるのが快適で快適で。

これとなるべく近いことをMTOSでやってみようという試みです。基本的にPSGIで動かす話なので、CGIで動かす場合は、今までどおりメンドイですね。

MTOSを取得する

MTOSはGithubで公開されているので、とても助かります。

$ cd /path/to/yoursite
$ git clone https://github.com/movabletype/movabletype.git mt

これで取得完了です。特定のbranchや特定のtagのファイルが必要な場合は、以下のコマンドも適宜実行しましょう。

$ cd mt
$ git tag -l
$ git checkout -b mt5.2.3 origin/mt5.2.3

とか、

$ git branch -r
$ git checkout -b develop origin/develop

とか。

以降、すべての操作をmtディレクトリの中で行うので、cdコマンドは省略します。

最後にmakeします。

$ make me

シェバンを書き換える

すべての.cgiのシェバンが、/usr/bin/perlになってますが、自分の開発環境で、そのPerl使うことは皆無ですし、CPANモジュールもまったく追加してないので、シェバンはワンライナーで書き換えます。

$ find . -name '*.cgi' -or -name '*.t' -o -name '*.pl' -o -name '*.psgi' | xargs grep -lE '^#!/usr/bin/perl' | xargs perl -p -i -e 's|^#!/usr/bin/perl(\s*(?:-w)?)$|#!/usr/bin/env perl$1|'

DBを作成する

これもSQLiteでできればなー・・・。という感じ。他はすべてアプリケーションのディレクトリに閉じ込めることができますが、ここばかりはどうにもなりませんね。

MySQLの設定 : Movable Type 5 ドキュメント

この辺は、今後、コマンドラインスクリプトで自動化しようと思います。

ディレクトリの配置

こんな感じにするのが良いと思います。

www (プロジェクトのルート)
├─ mt (MTのCGIPath)
├─ mt-static (MTのStaticPath)
└─ public (公開領域)

以下、このディレクトリの配置を前提に、設定ファイルにパスを書いています。

mt-config.cgiを用意する

最小限のmt-config.cgiは以下のような感じになりました。

CGIPath /mt/
StaticWebPath /mt-static
StaticFilePath /path/to/mt-static
ObjectDriver DBI::mysql
Database database
DBUser dbuser
DBPassword dbpassword
DBHost localhost
DefaultLanguage ja

/mt/foo.cgiが、それぞれ別個のPSGIアプリケーションになります。MTの管理画面は、/mt/mt.cgiです。

app.psgiを用意する

mt.psgiというものがあるのですが、書き換えたいのと、plackupでファイル名指定するのが面倒なので、mtディレクトリ配下にapp.psgiを用意します。ちなみに、コレが今回の肝です。

use strict;
use warnings;
 
use lib qw(lib);
 
use MT::PSGI;
use Plack::Builder;
 
builder {
    enable 'DirIndex',
        dir_index => 'index.html';
    enable 'Static',
        path => qr{^/(?:(?!mt/|mt-static/))},
        root => '/path/to/public';
    MT::PSGI->new()->to_app;
};

Plackミドルウェアを2つ使っています。mt.psgiは個別のPSGIアプリケーションを包括した大きなPSGIアプリケーションになっていて、中でMT標準のアプリケーションやら、プラグインで利用するアプリケーションやらをPSGIアプリケーションにして、マウントしてみたいな処理をしています。

外から、mt.psgiを拡張しようとすると、今のところ、Plackミドルウェアしかないのかなーと思っています。

とは言え、既存のPlackミドルウェアの資産が活用できるのは魅力です。
もしかしたら、今後、MTのプラグインだけではなく、mt.psgi用のPlackミドルウェアもいろいろ出てくるのかもしれませんね。

静的ファイルを配信するためだけに、Apacheを設定するのは流石にだるいので、PSGIサーバーさん(plackup)に、そこんとこも頼むことにします。

静的コンテンツを配信するミドルウェアであるPlack::Middleware::Staticと、特定のファイル名をApacheのDirectoryIndexのように設定できるPlack::Middleware::DirIndexを利用しています。

Plack::Middleware::DirIndexの方は、Plack::Middleware::Staticの正規表現をもうちょっと書いたら不要かもしれません。もしくは、インラインでミドルウェアを書くとか。

ちなみに、Plack::Middlewara::DirIndexの存在は、Plackのgithub上にあったIssueで知りました。

MTOSの起動

plackup

以上!

デフォルトでは、ポートが5000番で起動するので、http://localhost:5000/mt/mt.cgiがMTの管理画面、http://localhost:5000/がサイトルートになります。

まとめ

以上で、割とポータブルで、サクッと用意できるMTOSの開発環境が用意できたと思います。用意が楽な上に、今までより速いです。

一応、公式では、plackupの制約上、PSGIサーバーはStarmanの利用が想定されていて、plackupはあくまで開発用と割り切って使いましょう。プラグイン入れた時とかアップグレード後とか何かと再起動必要だし。

初期状態では、CPANモジュールがいろいろ足らないと思いますが、この辺の依存関係を書いたMakefile.PLを用意して、Cartonで管理するのが良いと思います。

公開サーバーにMTを置かないという選択肢があるなら、これだけでも、高機能な静的HTML生成器になるし、汎用的なテキストファイル生成機になりますね。