&pgid();
 
 #contents
 
 MT::Boostrapを利用してMTのライブラリ(とそれによって提供されるクラス、オブジェクト)を利用した独自アプリケーション(CGI)を構築することができます。
 
 このエントリーではMT::Bootstrapを使うと何がうれしいのか、そして、MT::Bootstrapの簡単な使い方について説明します。
 
 参照:Movable Type オブジェクト・リファレンス - MT::Bootstrap
 [[MT::Bootstrap>http://www.movabletype.org/documentation/man/MT/Bootstrap.html]]
 
 ** MT::Bootstrapを使うと何がうれしいのか? [#r95b5d09]
 
 MT::Bootstrapを使うことで次のようなうれしいことが!
 
 - MT、MT::App、MT::ObjectといったMTのライブラリが提供するクラス、オブジェクトを独自アプリケーション(CGI)で利用できる
 - ↑によってSQLを直接叩なんてことをせずに、MTで保持しているデータにAPI経由でアクセスできる(MT::Object様々)
 - ↑からDBに依存しない実装が可能(MT::Objectが環境差を吸収してくれる)
 - 導入しているPluginが独自に定義しているMT::*クラス、オブジェクトも利用できる
 - HTTPヘッダの出力、GET/POSTデータの受け取り、標準出力への出力、メールの送信など定型の処理をMTに任せてしまえる
 - (やったことないけど)MTのユーザ管理、認証の仕組みも利用できる
 
 なので、例えば、MTのユーザ別に記述したブログ数を出力する「ブログいっぱい書いた人ランキング」を表示するCGIなどが簡単に作れます。
 
 ** MT::Bootstrapの簡単な使い方 [#r560be68]
 
 Step by StepでMT::Bootstrapの簡単な使い方を示します。
 
 *** 1. 本体プログラムを作成する [#qb2fa31f]
 
 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とします。((このスクリプトはblog_publisher_ranking.cgiがMT本体のディレクトリに設置されているという想定でlib、およびextlibのパスを指定しています。設置場所が異なる場合はそれにあわせて、パスを変更する必要があるでしょう))
 
 保存したスクリプトに実行権限を与えておきます。
 
  $ chmod a+x blog_publisher_ranking.cgi
 
 *** 2. Mainクラスを作成する [#g533c92d]
 
 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://www.movabletype.org/documentation/man/MT/App.html]]のサブクラスとします。こうすることで、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;
  }
  
 のコードで、アプリケーションに対するリクエストの取り扱いを初期化しています。
 
 具体的には、
 
 + app_methodsでBlogPublisherRankingというモードとこれを処理するメソッド_BlogPublisherRankingを定義し
 + modeメソッドでBlogPublisherRankingを指定することでアプリケーションのモードをBlogPublisherRankingに変更し
 + 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などのパスで保存します。
 
 参照:
 - [[MT::App>http://www.movabletype.org/documentation/man/MT/App.html]]
 - [[MT::App init_request>http://www.movabletype.org/documentation/man/MT/App.html#%24app-%3Einit_request]]
 - [[MT::App add_methods>http://www.movabletype.org/documentation/man/MT/App.html#%24app-%3Eadd_methods(%25arg)]]
 - [[MT::App mode>http://www.movabletype.org/documentation/man/MT/App.html#%24app-%3Emode(%5B%24mode%5D)]]
 - [[MT::App param>http://www.movabletype.org/documentation/man/MT/App.html#%24app-%3Eparam(%24name%5B%2C_%24value%5D)]]
 
 *** 3. テンプレートのロードと出力構築 [#bd4b3924]
 
 では、_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,
      );
  
      # テンプレートにパラメータを適応して、結果文字列(ブログいっぱい書いた人ランキング)を生成して返す
      my $html = $app->load_tmpl('blog_publisher_ranking.tmpl', \%param);
      return $app->build_page($html, \%param);
      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>
 といった形になります((詳しくは[[MT4.xプラグイン作成/テンプレートでループを利用する方法]]を参照のこと))。
 
      my $html = $app->load_tmpl('blog_publisher_ranking.tmpl', \%param);
      return $app->build_page($html, \%param);
     return $app->build_page('blog_publisher_ranking.tmpl', \%param);
 
 $app->load_tmplと$app->build_pageの双方をコールする必要がある理由はよくわかっていません^^;
 ご存知の方がいれば教えていただけるとうれしいです。
 build_pageで結果を生成して返します。
 
 [[MT::App build_page>http://www.movabletype.org/documentation/man/MT/App.html#%24app-%3Ebuild_page(%24tmpl_name%2C_%5C%25param)]]
 
 *** 4. MT::Objectのロード [#e5184c22]
 
 書いたエントリー数が多い順にユーザ名を返す_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)>http://www.sixapart.jp/movabletype/manual/object_reference/archives/mt_object.html]]
 
 #blikifooter(進地);

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS

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