Results tagged “Movable Type”

通常、MTのパッケージはシステムレベルにインストールされません。そのため、lib/ とextlib/ へのパスを実行時に追加する必要があります。
例えば、EntryオブジェクトをDumpするワンライナーは以下のようになります。

$ perl -Ilib -Iextlib -MMT -MData::Dumper -e 'MT->new; print Dumper(MT->model("entry")->load(42))'

また、プラグインごとのlibディレクトリへのパスは、MTのインスタンス作成時に動的に追加されます。そのため、MTのプラグインを開発中、コンパイルチェックをしたい時などに直接実行する事ができません。

$ perl -Ilib -Iextlib -Iplugins/MyPlugin/lib -c plugins/MyPlugin/lib/MyPlugin.pm

長いですね。

そこで、以下のようなモジュールを、perlのパスの通った場所に設置します。

package T;
use strict;
use warnings;
use lib qw( lib extlib );
use MT;
BEGIN { MT->new };
1;

名前は、T.pmです。これで

$ perl -MT -MData::Dumper -e 'print Dumper(MT->model("entry")->load(42))'
$ perl -MT -c plugins/MyPlugin/lib/MyPlugin.pm

などと、perlにMT専用オプションが追加されたような錯覚を覚える事が出来ます。

少し説明を追加、アップデートしました。

小粋空間さんで、プラグインのファイル構成について解説されている記事が公開されています。

その中で、自分の過去の発表で YAML ファイルでの perl コードの実行について話した内容に触れられていたのですが、それを読んで、自分の発言が誤解されるような言い方になっていたようなので、整理してみます。

要点を順に書くと、こんな感じになります。

  1. Movable Type の registry では、サブルーチンが期待されているなら、文字列を自動的に perl コードとして展開する場合がある
  2. plugin の定義ファイルである config.yaml ファイルではこの機能を最大限利用することで直接 perl コードを埋め込める(ようになっている設定値が多数用意されている)
  3. ただし、テーマの定義ファイルである theme.yaml ファイルを扱う際には、セキュリティ向上を目的に、基本的にこの機能を使わないよう開発している

ですから、plugin のスタートポイントがfoo.plである場合と、config.yamlである場合に、セキュリティ的な安全性の差は(現在の所)ありません。小粋空間さんのところで触れられた安全性の話は、plugin と theme の違いの話だとご理解ください。

2) について補足しておくと、registry 内でサブルーチンが期待される場合(例えばテンプレートタグの登録での、実行ルーチンの指定部分)、「sub {」で始まる文字列を直接指定する事で、perl として実行させる事が出来ます。
以下は、実際にプラグインとして動作するconfig.yamlファイルの例です。

tags:
    function:
        Foo1: sub { return "Hello foo1" }

ActionStreams + AnyEvent

  • Posted on
  • by

ActionStreamsで更新チェックする時に、AnyEvent::HTTPを使って並列ダウンロードするようにしてみました。sixapart / mt-plugin-ActionStreamsからforkして、anyeventブランチを切ってゴニョゴニョしてます。

AnyEventが見つかれば自動的に利用するようにしてありますので、特別な設定は不要です。

10程度のストリームの処理で、ベンチマーク(ストップウォッチで目視)では約三倍ほど速くなってます。ストリームの数が増えれば、もっと差が出るかもしれません。

Include Map という名前のプラグインです。

なにが起こるの?

  • テンプレートの編集画面に、そのテンプレートをインクルードしているテンプレートの一覧を表示します。
  • 以下のような依存関係の一覧画面を追加します。

include_map.png

どこでダウンロードするの?

ダウンロードはgithubからお願いします。画面右上、上から3段目の「Download Source」ボタンから、最新のパッケージをダウンロードできます。

使い方は?

IncludeMapプラグインは、テンプレートの編集を監視し、内部的に依存関係の記録を行います。ですが、現在のところプラグインのインストール時にはこの記録は作成されません。
運用中のMovable Typeにこのプラグインを追加して利用する場合、事前にブログ/ウェブサイトの一覧画面からPlugin Action > Rebuild Include Mapを実行してください。

インストールに成功すると、メニューの「デザイン > Include Map」から、各ブログごとのテンプレートの依存関係表を開くことが出来ます。この画面はIEでは動作しないかもしれません。

ご利用は計画的に

このプラグインはMTのデータベースに変更を加えます。また、開発途中のため、今後大きな変更が加わる可能性もあります。実運用中の環境へのインストールはお勧めしません。テスト用途でのご利用をご検討ください。

MT形式のエクスポート用に出力をエスケープする - 刺身☆ブーメランのはてなダイアリー

そうか。MTのエクスポート形式って業界標準なのか。。。

エスケープ結果を復元するコードが無かったので自分で書こうとしたが、もとのコードだとエスケープ後のデリミタと同じパターン(-----<>など)が元の文字列に存在した時に、正確に復元できないという問題に気づいたが、あきらめて風呂に入っているうちに解決策を思いついた。
文字列中のすべての「-」のみの行を3倍とかに変更してしまえば、安全にエスケープでき、かつラウンドトリップ可能となるはずです。3倍なのは本来のデリミタ( '-' x 5 || '-' x 8 )と重複しないためで、彗星と直接の関係ありません。

実際には、後方互換性が必要になる(このエスケープ形式に対応していないインポーターでも違和感無く読み込めるのが理想)ので、実戦投入は無理でしょう。
元記事のほうでは、HTML表示した場合に見た目変化が無いように空タグっぽい<>を末尾に追加したのだと思うのですが、MTなんかでは最終的な出力先がHTMLとは限らないので、良く無い事が起こりそうな気もします。デリミタと重複する行の末尾にスペースを一個追加してしまう、というあたりが落としどころになるのでしょうか。

TagOverride

  • Posted on
  • by

勢いで書きました。後悔はしてません。
MTML自身で、既存のMTタグの動作を上書きする事ができるプラグインです。使い道はちょっと未知数ですが、なんとなく役に立つ使い方も出来るのでは無いかと言う気がします。役に立つと良いなあ。。。

現在の所、MT5.x 専用です。最新版は、以下のページからダウンロードできます。

「$pkg = '$Core::MT::CMS::'」と宣言されているから、 「${pkg}Dashboard::dashboard」というのは「$Core::MT::CMS::Dashboard::dashboard」 のことだと思う。

で、この「$Core」というのが何なのかわからない。

カレントのComponentをFooにセットしてから、Bar::buzを実行してくれ、という意味になります。
上の例で言えば、カレントのComponentとして'Core'を設定した上で、MT::CMS::Dashboardパッケージのdashboardメソッドを実行しろ、ということです。

[MT]コールバックの実行順序

  • Posted on
  • by

今日はコールバックの発生順序に関して大はまりしたので個人的に思ったことをメモ。

MTやMTのプラグインから利用可能なコールバックには大きく分けて以下の3つがある。


  • 1) 通常のMTのコールバック(cms_post_saveなど)

  • 2) Data::ObjectDriver(D::OD) が Class::Trigger のトリガーを実行した際に同期して呼ばれる、オブジェクト操作関係のコールバック(MT::Entry::post_saveなど)

  • 3) D::ODが実行する Class::Trigger のトリガー

ちなみに(3)は、以下のように指定/実行できます。

MT::Comment->add_trigger(
    post_save => sub {
        my $comment = shift;
        # do something here... 
});

このうち、(1)と(2)はMTのコールバックとして実行されるため、優先順位を指定できるが、(3)はMTのコールバックではないので、どのような順番で処理されるか分からない。そのためドハマリしました。

結局、現在のMTの実装として(恣意的に)

  • Class::Trigger の「pre_****」は常にMTの「pre_****」コールバックより先に呼ばれる
  • Class::Trigger の「post_****」は常にMTの「post_****」コールバックより後に呼ばれる

となっているが、(多分)アンドキュメンテッドな仕様なためこの順序が変更されない保証は無い。ということだと思います。

とりあえずの結論としては、基本的に(3)の方法は使わずに必ず(2)の方法で指定する、必要ならpriorityをきちんと登録する、というのがベストプラクティスなのかなと思いました。


で、ここからが疑問なのだが、単なる数字(MTのコールバックの優先順位は0~11で指定される)では正直何より先or後に実行されるのか分からないんスよね。これって意味有ります?
こういった仕組み自体はよく有る汎用的な仕組みだとは思うのですが。なんか納得いかねえ。

曖昧模糊と「早いうちに」とか「遅い時間に」とか指定するよりも、名指しで「'hoge'プラグインの'mage'コールバックよりは先に実行してください」みたいに具体的に指定できるような仕組みのがベターなのかな、と妄想した一日でした。

とんだ出落ちですみません。会社の休みもらえたのが、締め切りの次の日だったんです。フライングで申し込んでおけば良かったと今になって思うも後悔先に立たず。

でまあ、結局一日家でUstreamに張り付いてずっと見ていたので、割と満足。ちょっとした感想くらいなら述べることも出来るというものです。


興味深かったのはやはり Beau Smith さんのパブリッシングに関する話。
アーカイブやインデックステンプレートごとに更新頻度とページビューを予想してパブリッシュの方法を決めろ、ただしサイトごとに傾向は違ってくるので頑張れ、という話だったと思います。

ただ、現実的に、そう簡単に最適解が出せるかというと難しいと思います。その一番の理由は、定量的に再構築の回数を観測出来ないからです。

これってでも、実現できそうですよね。
再構築の回数を記録してFileinfoテーブルにでも突っ込んでおくと、パフォーマンスの測定に役立つのでは無いか。
もっと突き進めれば、ページビューのデータも取得するようにして、View / Build Ratio みたいな値を定期的に算出し、ファイルごとに最適なパブリッシング方法をMTが自動的に設定してくれる、なんてことも出来るかも。という妄想をいたしました。


あとはLightingTalkが大変楽しそうでしたね。Ustreamの画面だと実動作のデモは視聴がちょっと辛くはありましたが、それでも、すごくいい雰囲気が伝わってきました。
変態テンプレート好きの自分としては、mt:EntryPreviousのネスト技の話が一番ツボにハマりました。今なら、mt:setVarTemplateを再帰させてゴニョゴニョしても面白いかも。という妄想をいたしました。


なにはともあれ、みなさんお疲れさまでした。参加できなくて残念でしたが、すごく楽しい時間をありがとうございました。おしまい。

小粋空間のyujiroさんの著書Movable Type 4.2 パーフェクトガイドが発売になりました。おめでとうございます!
しかも、一冊戴いてしまいました。ありがとうございました!

Movable Type 4.2 パーフェクトガイド
荒木 勇次郎
4839927790

時間を見ては目を通しているのですが、本当にすごいボリュームです。しかも、随所にコラムとして関連情報へのポインタが含まれていて、情報の密度も半端じゃないです。手に取った瞬間に、並大抵ではないエネルギーが費やされている一冊だと分かります。すばらしいです。
改めてyujiroさん、お疲れ様でした。

それでですね。なんと!パーフェクトガイド内で、当サイトで公開しているプラグインBuild Tracerが紹介されています。しかも、通常のプラグイン紹介とは別枠で、パーフェクトガイドのメインともいえるテンプレート解説の冒頭付近に一ページ強を割いて掲載されていました。見た瞬間変な汁が出ました。
あの超ニッチなプラグインを取り上げられるとは、これは、自分も頑張らなくちゃとやる気がたくさん出ました。ありがとうございました!

IndexContextプラグインもピックアップされてました。うぇーい。

TaggingHelper For MT4.2

そろそろ、当サイトで配布しているプラグインをMT4.2に対応させていく必要があるのですが、今回は色々動かなくなるものが多くて、頭を抱えています。

とり急ぎTaggingHelperを対応させました。まったくの暫定版なので、バージョン外とします。
Movable Type / MTOS 4.2 でのみ動作します。また、タグの使用頻度順でのソートが出来ません。

TaggingHelperForMT4_2.zip

今後の対応については、考え中です。

cremaさん作成の iPhoneテンプレート for MT を、このブログに導入してみました。iPod TouchやiPhoneをお持ちの方は、アクセスしてみてください。

blogaklaswadcomimage.png

テンプレートは以下のページで配布されています。すばらしいです。
「iPhoneテンプレートfor MT」を公開いたします。|iPhone|東京Webデザイナー日記リターンズ|crema design

なお、 iPhoneテンプレートはブログURL内の「i」ディレクトリに出力する仕組みになっていますので、iPhoneでアクセスする時に専用のURLにアクセスする必要があります。
このブログでは、インストールの際に以下のようなカスタマイズを行って、PCでの閲覧時と同じURLになるようにしてみました。

  • 追加したiPhoneテンプレート内のトップページとブログ記事アーカイブへのリンクを、通常のものに書き直す。
    • 画像やcssファイルなどへのリンクは変更しない
    • アーカイブマッピングは、「i」ディレクトリ内へ出力する設定のままにする
  • ブログトップの.htaccessに以下を追加。
  RewriteCond %{HTTP_USER_AGENT} (iPhone|iPod)
  RewriteCond %{REQUEST_URI} !^/i/
  RewriteRule ^(.*)\.html$ /i/$1.html [L]

.htaccessの記述は、利用しているサーバーによっては上手く動かないかもしれません。またその場合、即座にサイト全体が500エラーになってしまうような事態も考えられます。.十分注意して作業を行ってください。

自分は、今見ているテストページがスタティックパブリッシングとダイナミックパブリッシングのどちらによる出力なのか、一目で分かるように、以下のような表示をさせておくことがあります。

このテンプレートは<mt:ifDynamic>ダイナミック<mt:else>スタティック</mt:ifDynamic>で構築されました。

いくらPerl弄っても動作が直らないと思ったらPHPのほうに問題があった。何を言ってい(ry等と言うことにならないためですね。

さて、ここでちょっとした罠があります。mt:ifDynamicと対になるようなテンプレートタグmt:ifStaticでは、このような書き方は出来ません。

このテンプレートは<mt:ifStatic>スタティック<mt:else>ダイナミック</mt:ifStatic>で構築されました。

上記テンプレートは、スタティックでは期待通りに動きますが、ダイナミックでは以下のような出力になってしまいます。

このテンプレートはで構築されました。

原因は、mt:ifStaticタグのPHPでの実装が、テンプレートタグとしてではなく、コメント(のような)扱いになっているためです。
<mt:ifStatic>・・・</mt:ifStatic>の部分が、再構築より前に強制的にテンプレートから削除されてしまうんですね。なので、その中に何個mt:elseを書こうが、全部消えてしまうわけです。mt:ignoreと同じですね。

これはおそらくダイナミックパブリッシングでは、ページビューごとに構築が行われるため、より細部の高速化を重視しているものかと思われます。mt:ifStaticとmt:ifDynamicで非対称な動作となっているのでちょっと違和感がありますが、上手く使い分けると良いと思います。

[mt.js]mt:tabを使ってみる

MT4の管理画面では、かなりしっかりした独自のJavaScriptライブラリ(mt.js)が用意されています。Transformerやalt-tmplでの管理画面のカスタマイズに応用できると良いのですが、残念ながら、今のところまとまったドキュメントも無く、応用するのが難しい状況です。

でもやっぱり、そんな使えるライブラリを放置するともったいないお化けが出るぞ、ということで、mt.jsの機能の中で一番簡単そうな、タブ機能の使い方を調べてみました。

TaggingHelperお試し版

Firefox限定ですが、プラグインをインストールせずに動作確認が出来るお試し版を用意してみました。
Movable Type のブログ記事を書く画面が開いている状態で、以下のコードを全選択コピーして、ブラウザのアドレスバーに直接貼り付けEnter、として実行してみてください。

MT4用。

こちらはMT3用。

動作が気に入ったら、是非プラグインをインストールして使ってみてください。

ちなみに、IEでは上手く動きませんでした。残念。
というか、Firefoxはbody中にscript経由で突っ込まれたlinkタグも読み込んでしまうんですね。試してみたら動いたのでびっくりしました。

TaggingHelperの新しいバージョンを公開します。久しぶりの更新となりますね。

主な更新内容はこちら。

  • タグ一覧を、使われている頻度順で表示するモードを追加した。
  • 本文に含まれる文言のタグを抽出して表示するモードを追加した。
  • シングルクオートを含むタグが扱えない問題に対応した。指摘してくれたTrackback(774)さんありがとうございます。
  • タグの途中で改行してしまう問題に対応した。

内部構造をちょっと変更した結果、どうやらSafari、Operaなどのブラウザでも利用可能となっているようです。Windows版のSafari3.1.1、Opera
9.24で動作を確認しました。やったね!

Pure MTML で NabeAzz

mixiのMTテンプレート大喜利大会(違う)に出したネタです。

NabeAzzというのは、えー、FizzBuzzの変形でー。
多分発祥はここだと思います。

そろそろ FizzBuzz に飽きた - にぽたん研究所

mixiでは文字数制限が怖かったのでコメント一切無しにしました。
ちょっとわかりづらいところもあると思うので、コメント付で再掲します。

自分の作ったテンプレートの目標は、ノープラグイン、ノースクリプト。MTタグのみでのNabeAzzです。

<mt:ignore><!-- 単純な線形合同法で乱数を生成。 --></mt:ignore>
<mt:setvarblock name="seed"><mt:date format="%S"></mt:setvarblock>
<mt:setvartemplate name="rnd">
    <mt:getvar setvar="seed" name="seed" op="*" value="13" />
    <mt:getvar setvar="seed" name="seed" op="+" value="5" />
    <mt:getvar setvar="seed" name="seed" op="%" value="24" />
    <mt:getvar name="seed">
</mt:setvartemplate>
 
<mt:ignore><!-- 配列の初期化はsetvar一発で。 --></mt:ignore>
<mt:setvar name="aho" value="www":"ktkr":"ぶーん":"だわよのさ":"へっぺふむーん">
<mt:setvar name="dog" value="ダワン":"キャイーン":"キャンキャン":"バウウウ":"ガルルル">
 
<mt:ignore><!-- 指定された配列からランダムに要素をとってくる。 --></mt:ignore>
<mt:setvartemplate name="get_suffix">
    <mt:setvarblock name="idx"><mt:getvar name="rnd" trim="1"></mt:setvarblock>
    <mt:setvarblock name="max"><mt:getvar name="$target" function="count"></mt:setvarblock>
    <mt:getvar setvar="idx" name="idx" op="%" value="$max">
    <mt:getvar name="$target" index="$idx">
</mt:setvartemplate>
 
<mt:ignore><!-- 以下、出力用ループ --></mt:ignore>
<ul>
<mt:for from="1" to="40">
    <li>
    <mt:getvar name="__counter__">
    <mt:unless name="__counter__" op="%" value="5">
        <mt:setvar name="target" value="dog">
        <mt:getvar name="get_suffix">
    </mt:unless>
    <mt:unless name="__counter__" op="%" value="3">
        <mt:setvar name="target" value="aho">
        <mt:getvar name="get_suffix">
    <mt:elseif name="__counter__" like="3">
        <mt:setvar name="target" value="aho">
        <mt:getvar name="get_suffix">
    </mt:unless>
    </li>
</mt:for>
</ul>

以前に公開していた(今もしている)CustomEditorButtonというプラグインを、ようやくMT4に対応させることが出来ました。

以前のバージョンとは異なり、ボタンは別プラグインの形で追加していきます。この辺はActionStreamsと同じ感覚ですね。
しばらく使ってみて不便であれば、以前のように、管理画面からもボタンの追加が出来るようにしてみます。

当面のToDo:

  • ボタンが増えすぎたときの対処。至急。
  • 画像なしでもボタンを作れるように。まあまあ急ぎ。
  • プラグイン側から、ブログにスタイル定義を追加できるようにする。ちょっとしたタグを書けば実現できそう。プラグインをインストールしてタグ一個書くだけでスーパーpreが使えるようになったりすると良いですね。
  • L10N

javascriptまわりでヒントをくださったYoshimatsuさんに感謝します。

使ってみて何かあったらコメントかtwitterで教えてください。では。

CustomEditorButton2

管理画面のブログ記事投稿画面に、任意の機能を持ったボタンを追加できるプラグインです。
以前に公開していたCustomEditorButtonのMT4対応版となります。