MT4.xプラグイン作成/MTのライブラリを利用した独自アプリを作る http://www.ark-web.jp/sandbox/wiki/306.html

MT4.xプラグイン作成/MTのライブラリを利用した独自アプリを作る

MT::Boostrapを利用してMTのライブラリ(とそれによって提供されるクラス、オブジェクト)を利用した独自アプリケーション(CGI)を構築することができます。

このエントリーではMT::Bootstrapを使うと何がうれしいのか、そして、MT::Bootstrapの簡単な使い方について説明します。

参照:Movable Type オブジェクト・リファレンス - MT::Bootstrap
MT::Bootstrap

[edit]

MT::Bootstrapを使うと何がうれしいのか?

MT::Bootstrapを使うことで次のようなうれしいことが!

なので、例えば、MTのユーザ別に記述したブログ数を出力する「ブログいっぱい書いた人ランキング」を表示するCGIなどが簡単に作れます。

[edit]

MT::Bootstrapの簡単な使い方

Step by StepでMT::Bootstrapの簡単な使い方を示します。

[edit]

1. 本体プログラムを作成する

WebブラウザでURLを指定されてアクセスされるスクリプトを作成します。このスクリプトがCGIアプリケーションの本体になります。コードは以下のようになります。

#!/usr/bin/perl -w

use strict;
use File::Basename;
use lib (dirname($0) . '/') . 'lib';
use lib $ENV{MT_HOME} ? "$ENV{MT_HOME}/lib" : (dirname($0) . '/../../') . 'lib';
use lib $ENV{MT_HOME} ? "$ENV{MT_HOME}/extlib" : (dirname($0) . '/../../') . 'extlib';
use MT::Bootstrap App => 'BlogPublisherRanking';

コードはこれだけです。本体スクリプトには詳細なコードは書かずに単にMT::BootstrapにアプリケーションのMainのロジックを記述したクラス名を与えるだけです。以下、このクラスをMainクラスと呼称します。Mainクラスのクラス名はBlogPublisherRankingとしました。

 use MT::Bootstrap App => 'BlogPublisherRanking';

このスクリプトを任意の名前で保存します。ここではblog_publisher_ranking.cgiとします。*1

保存したスクリプトに実行権限を与えておきます。

$ chmod a+x blog_publisher_ranking.cgi
[edit]

2. Mainクラスを作成する

Mainクラス、BlogPublisherRankingを以下のように作成します。

package BlogPublisherRanking;
use strict;

use MT;
use MT::App;
use MT::Blog;
use MT::Entry;
   :
   :     # 利用したいMTライブラリのクラス名を列挙する
   :

# MT::Appクラスのサブクラスとして定義する。
@BlogPublisherRanking::ISA = qw(MT::App);

sub init_request {
    my $app = shift;
    $app->SUPER::init_request(@_);
    $app->add_methods( BlogPublisherRanking => \&_BlogPublisherRanking );
    $app->mode('BlogPublisherRanking');
    $app->{requires_login} = 0;
}

sub _BlogPublisherRanking {
   my $app = shift;
   my $q = $app->param;

      :
      :   # 色々な処理
      :

   return '画面に表示したい文字列';
}

1;

このスクリプトをlib/配下など、blog_publisher_ranking.cgiがライブラリパスとして参照できるディレクトリにファイル名BlogPublisherRanking.pmで保存します。

Mainクラスにはアプリケーションの実際のロジックを記述していきます。
また、MainクラスはMT::Appのサブクラスとします。こうすることで、HTTPヘッダの出力、GET/POSTデータの受け取り、標準出力への出力といったCGIに特有の定型処理を自分で書く必要がなくなります。

sub init_request {
    my $app = shift;
    $app->SUPER::init_request(@_);
    $app->add_methods( BlogPublisherRanking => \&_BlogPublisherRanking );
    $app->mode('BlogPublisherRanking');
    $app->{requires_login} = 0;
}

のコードで、アプリケーションに対するリクエストの取り扱いを初期化しています。

具体的には、

  1. app_methodsでBlogPublisherRankingというモードとこれを処理するメソッド_BlogPublisherRankingを定義し
  2. modeメソッドでBlogPublisherRankingを指定することでアプリケーションのモードをBlogPublisherRankingに変更し
  3. requires_loginに0を指定することでMTのログインなしに実行されるアプリケーションであることを明示

しています。

これによって、おおざっぱにいうと、

blog_publisher_ranking.cgiにブラウザ等でアクセス
  -> BlogPublisherRankingのinit_requestが実行される
    -> モードがBlogPublisherRankingなので、そのモードに対応した_BlogPubliserRankingが呼び出される

という処理が走ります。

そして、_BlogPubliserRankingで何らかの処理を行って、文字列を返すとその文字列がブラウザ等の画面上に表示されます。HTTPヘッダを自分で出力する必要はありません。

また、_BlogPubliserRankingでは、第一引数にMT::Appの参照を受け取ることができ、MT::App->paramでGET/POSTデータを取り出すことができます。

このファイルを./BlogPubliserRanking.pmなどのパスで保存します。

参照:

[edit]

3. テンプレートのロードと出力構築

では、_BlogPublisherRankingの詳細を実装します。

sub _BlogPullisherRanking {
    my $app = shift;
    my $q = $app->param;

    # テンプレートファイルの格納ディレクトリを設定する
    $app->{plugin_template_path} = 'tmpl/BlogPublisherRanking';

    # 以下のデータ構造を取得する関数(_get_sorted_publishers)があるとする
    # (
    #   { name => 一番エントリー数の多いユーザ名, ... },
    #   { name => 次にエントリー数の多いユーザ名, ... },
    #        :
    #   { name => 一番エントリー数の少ないユーザ名, ... },
    # )
    my @publishers = &_get_sorted_publishers($app);

    my %param = (
        'publishers' => \@publishers,
    );

    # テンプレートにパラメータを適応して、結果文字列(ブログいっぱい書いた人ランキング)を生成して返す
    return $app->build_page('blog_publisher_ranking.tmpl', \%param);
}

まず、

    $app->{plugin_template_path} = 'tmpl/BlogPublisherRanking';

によってテンプレートファイルを置くディレクトリパスを指定します。
ここでは、スクリプト(blog_publisher_ranking.cgi)からの相対パスでtmpl/BlogPublisherRankingというディレクトリにテンプレートを置く指定をしています。

その後、必要なデータ構造(この場合、ブログを書いたランキングでソートされたMT::Authorの配列)を生成し、テンプレートに引き渡して結果文字列を生成します。

テンプレートファイルは

    my $html = $app->load_tmpl('blog_publisher_ranking.tmpl', \%param);

と指定しているので、先のplugin_template_pathの指定からtmpl/BlogPublisherRanking/blog_publisher_ranking.tmplと判断されます。

テンプレートファイルの中身は

<mt:loop name="publishers">
  <$mt:var name="name"$>
</mt:loop>

といった形になります*2

   return $app->build_page('blog_publisher_ranking.tmpl', \%param);

build_pageで結果を生成して返します。

MT::App build_page

[edit]

4. MT::Objectのロード

書いたエントリー数が多い順にユーザ名を返す_get_sorted_publishers関数は以下のようにできると思います。

sub _get_sorted_publishers {
    my $app = shift;

    # MT::Authorオブジェクトを全件ロードする
    my @authors = MT::Author->load();

    # author_idとユーザ名,書いたエントリー数からなるハッシュ { id => author_id, name => ユーザ名, count => エントリー数 }の配列を生成する。
    my @publishers = map { return { 'id' => $_->id, 'name' => $_->name, 'count' => MT::Entry->count({ 'author_id' => $_->id }) }; } @authors;

    # エントリー数でソート(降順)して返す
    return sort { $b->{'count'} <=> $a->{'count'} } @publishers;
}

MT::AuthorもMT::EntryもMT::Objectを継承しているのでloadメソッドで簡単に取得できるのが助かるところです。

参照:Movable Type オブジェクト・リファレンス(MT::Object)

投稿者進地 | パーマリンク

| append.gif

*1 このスクリプトはblog_publisher_ranking.cgiがMT本体のディレクトリに設置されているという想定でlib、およびextlibのパスを指定しています。設置場所が異なる場合はそれにあわせて、パスを変更する必要があるでしょう
*2 詳しくはMT4.xプラグイン作成/テンプレートでループを利用する方法を参照のこと

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2008-06-20 (金) 07:34:56 (5789d)

アークウェブのサービスやソリューションはこちら