2011年12月02日
DynamicMTMLのFAQ

DynamicMTMLについてよく見かけるエラーのケースなどを紹介します。

404 Not Found ページが表示される

ダイナミックパブリッシングのページにアクセスすると「404 Not Found」が返ってくる。

原因1
動作に必要なファイル/ディレクトリが存在しない
対策1
下記が存在するか確認します
  • .htaccess ファイル
  • mtview.php (.mtview.php) ファイル
  • templates_c ディレクトリ
原因2
設置された .htaccess が動作していない
対策2
.htaccess が動作するか確認します。 利用可能なディレクティブにもよりますが、リダイレクトが可能であれば下記例でGoogle へアクセスが転送されると思います。
Redirect / http://www.google.co.jp/

PHPのソースが表示される

(静的)ダイナミックパブリッシングを利用した際に PHP のソースコードが表示される。

原因
PHP が動作していない
対策
PHP が動作するかサーバの設定などを確認します

異なるパラメータでアクセスした際、前回アクセス時の内容が表示される

パラメータの内容によって表示結果が変わる設定で、パラメータを変えても同じ結果が表示される。

原因
ダイナミックパブリッシングのキャッシュ機能が効いている
対策
ウェブサイト/ブログの全般設定画面で「キャッシュする」のチェックを外して保存する

「ページが見つかりません。 An error occurs」と表示される

(静的)ダイナミックパブリッシングのページにアクセスすると下記のメッセージが表示される。

原因
何らかの要因によって「ダイナミックパブリッシングエラー」システムテンプレートの内容が出力されている

この場合、下記の操作を行う事でエラーの原因を絞り込む事ができます。

  1. mt-config.cgi に環境変数DebugModeを記述します。
    DebugMode 1
  2. 再度エラーページへアクセスします。
  3. 「An error occurs」と表示されていた部分のメッセージが変化しているか確認します。

「An error occurs」が別のメッセージに変化したら、そのメッセージの内容に対して何らかの対策を行ってください。 下記にエラーメッセージ例の一部を紹介します。

エラーメッセージの内容

mktime(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'Asia/Tokyo' for 'JST/9.0/no DST' instead

原因
php.ini に date.timezone の指定がされていない
対策
php.ini で date.timezone の設定を行ってください
date.timezone = Asia/Tokyo
参考: PHP: 実行時設定 - Manual
エラーメッセージの内容

is_readable() [<a href='function.is-readable'>function.is-readable</a>]: open_basedir restriction in effect. File(/plugins/block.mtblogname.php) is not within the allowed path(s): (/tmp)

原因
ダイナミックパブリッシングの動作に必要な PHP ファイルを読み込めない
対策
  • php.ini の設定で open_basedir が指定されている場合は設定を解除するか、設定を変更します
  • PHP ファイルのパーミッション、/path/to/mt/php ディレクトリのパーミッションを確認します
参考: PHP: コア php.ini ディレクティブに関する説明 - Manual

画面が途中まで表示される

(静的)ダイナミックパブリッシングのページが途中まで表示された状態になる。

原因
PHP を実行するためのメモリが足りない
対策
  • php.ini で memory_limit の指定値を上げます
  • mtview.php (.mtview.php) に下記の記述を加え、指定値を上げます
    ini_set( 'memory_limit', '64M' );

PHP の実行に必要なメモリは環境や運用方法によって異なりますのでサーバ管理者と相談するなど適宜設定ください。

サムネイルが生成されない

ダイナミックパブリッシングのテンプレートでサムネイル画像が生成されない。

原因
PHP モジュールの GD が利用できない
対策
  • GD が利用できるか確認します
  • GD がインストールされているか確認します
  • GD で利用可能な画像の種類に制限がないか確認します (画像の拡張子によっては正常に動作する場合)

文字化けする

ダイナミックパブリッシングで出力したページが文字化けする。

原因
PHP の mbstring モジュールが利用できない
対策
  • mbstring が利用できるか確認します
  • mbstring がインストールされているか確認します

画面がホワイトアウトする (何も表示されない)

この状態から原因の特定は困難だが、多くはエラーメッセージがでるケースの原因が当てはまるので PHP モジュールや設定を確認する。

他ケースの原因に当てはまらない場合は下記を確認する

原因1
mt-config.cgi のDBHost に下記の指定を行っている
DBHost 127.0.0.1
対策1
mt-config.cgi のDBHost を下記のように変更します
DBHost localhost
原因2
PHP でデータベースにアクセスできない
対策2
PHP でデータベースにアクセスできるかサーバ管理者などに確認する

Movable Type標準のダイナミックパブリッシングの動作確認

PowerCMSのダイナミックパブリッシングは、Movable Type のダイナミックパブリッシングが動作する事が前提条件になります。そのMovable Type標準のダイナミックパブリッシングは下記の手順で動作確認が行えます。

  1. MT 標準のテーマが適用されたウェブサイト/ブログを用意する
  2. 「公開」オプションで「ダイナミック」を選択したインデックステンプレートを作成します
  3. ウェブサイト/ブログのトップに .htaccess と mtview.php が生成されたか確認します
    生成されない場合
    ディレクトリのパーミッションを確認します
  4. 作成したテンプレートに MTタグを一切記述せずに「テスト」とだけ記述します
  5. 作成したインデックステンプレートの出力先にアクセスします
  6. 「テスト」と表示されるか確認します
    表示されない場合
    date.timezone や open_basedir など他ケースの原因について確認します
  7. テンプレートの内容を「<$MTBlogName$>」に変更します
  8. 作成したインデックステンプレートの出力先にアクセスします
  9. ブログ名が出力されるか確認します
    表示されない場合
    date.timezone や open_basedir など他ケースの原因について確認します

「キャッシュする」と「ビルド結果をキャッシュする」の違いについて

同じ全般設定画面にある設定ですが、「キャッシュする」はMT標準の、「ビルド結果をキャッシュする」はPowerCMS標準のもので、その機能は異なります。

キャッシュする

「キャッシュする」はパラメータの内容には対応していないため下記は同一の扱いになり、どちらへアクセスしても同じ結果が出力されます。

  • /hoge.html?foo=1
  • /hoge.html?bar=2

PowerCMS ver.3 をご利用の場合、ツールメニューの「ダイナミックキャッシュをクリアする」よりキャッシュファイルの削除が行えます。

ビルド結果をキャッシュする

「ビルド結果をキャッシュする」はパラメータの内容に対応しているため下記は同一の扱いにはならず、別々にキャッシュされます。(テンプレートで、パラメータの内容によって出力結果を変化させている場合です)

  • /hoge.html?foo=1
  • /hoge.html?bar=2

カテゴリー:プラグイン技術情報

レンタルサーバー等でスマートフォンオプションのテーマを適用したブログが表示の際に500エラーを返すといったトラブルがあった際に参考にしてください。以下はhetemlの例です。

  1. スマートフォンオプションのテーマを適用したブログではブログのサイト・ルート直下に.htaccessが生成されています。.htaccessから、php_flag short_open_tag off *の記述を#でコメントアウトしてください。
  2. hetemlサーバーのPHPのバージョンを確認する必要があります。確認方法は http://heteml.jp/support/manual/php5/ をご確認ください。
  3. ご利用のhetemlサーバーのコントロールパネルにログインしてください。
  4. 右サイドのメニューにある "php.ini 設定" をクリックします。
  5. 2.でご確認いただいたPHPのバージョンのタブを開きます。
  6. short_open_tag の項目がありますのでOff に変更後、[php.iniを設定する] ボタンをクリックして保存してください。

* この設定(php_flag short_open_tag )は <? といった記述でもPHPのコードとして解釈するかどうかを設定するもので、これが有効になっていることでXML宣言がPHPコードとして解釈されてしまうのを避けるためにDynamicMTML側で.htaccessに記述を追加しているものです。サーバーのApacheの設定で、.htaccessにこの記述をすることが許可されていないサーバーではこのエラーが発生します。php.ini側で設定するか、上記のようにサーバに用意されているコントロールパネルから設定することでエラーを回避できる可能性があります。

また、同じくphp.iniで date.timezone の設定がない場合もエラーになります。この場合、 php.iniにdate.timezone = Asia/Tokyo と設定してみてください。

カテゴリー:プラグイン技術情報

追記: 定員になりましたので受付を終了しました。


スマートフォンの普及を背景に「レスポンシブWebデザイン」(Responsive Web Design)という制作手法が注目を集めてます。Movable TypeをPHPによって拡張したDynamicMTML(ダイナミックMTML)を利用するとCSS3のメディアクエリーやjQuery Mobileといったクライアントサイドのアプローチに加えてサーバーサイドでの振り分け、ガラケー対応、画像の最適化などがPHPやJavaScriptの知識なしに実装できます。 この勉強会では、DynamicMTMLのテンプレート作成方法に加え、DynamicMTMLの内側の解説やPHPによる拡張方法の解説、PHPによるプラグインの作成方法について紹介します。

また、勉強会の後は実際に手を動かしてテンプレートやプラグインを作成するHack-A-Thonを行います(PCはご持参ください。ゲスト用無線LAN使えます)。アルファサードの開発者だけでなく、シックス・アパートのMT開発者も参加予定です。普段中々聞く機会のないMTのPHP活用について知識を得るチャンスです。若干名ですが参加可能です(参加無料)。

  • 日時: 9月30日(金)14:00~
  • 場所: アルファサード 東京オフィス
  • 東京都千代田区神田神保町3-10-3 松晃ビル8F
    電話:03-3265-8488
    http://alfasado.net/contents/company_profile.html#tokyo
  • 主催: アルファサード有限会社
  • 定員: 12名
  • 14:00~ PHPで作るMovable Typeプラグイン(仮)
    講演者: シックス・アパート 高山さん
  • 14:30~ Inside DynamicMTML~PHPによるフレームワークの詳細解説
    講演者: アルファサード 野田
  • 15:30~ Hack-A-Thon
  • 19:30~ 成果発表
  • 20:30~ 懇親会(会費制)

参加ご希望の方はお問合せください。

カテゴリー:イベント・セミナー情報

“カスタムフィールドで指定したグループ名を出力する方法はありますか?”というご質問をサポートにいただきました。Power CMS 3の新機能であるカスタムフィールドPro(MT標準のカスタムフィールドタイプを大幅に拡張するもの)で出来るようになった「個別のオブジェクト」と「オブジェクトのグループ」をカスタムフィールドで関連づける機能を使った時にテンプレートでグループ名を出したいといったケースだと思います。

「個別のオブジェクト」と「オブジェクトのグループ」の紐づけというのは例えば「ブログ記事」に「ブログ記事のグループ」を紐付けるといった同一のオブジェクトの関連付けや、「ブログ記事」に「バナーのグループ」を紐付けるといったような異なるオブジェクトのグループの関連付けを指します。

テンプレートの紹介の前に簡単にこの機能についてご紹介します。

グループ機能とは下記のキャプチャのように左側にオブジェクトの一覧、右側へドラッグ&ドロップしてオブジェクトをグループ化、表示順をマウス操作で自在に設定できるものです(キャプチャはバナー(広告)グループの編集画面)。

バナーグループの編集画面

関連情報

カスタムフィールドの作成時にカスタムフィールドの種類のところでグループを選択します。

カスタムフィールドの作成画面

指定できるグループ

  • ブログ記事グループ
  • ウェブページグループ
  • ブログ記事/ウェブページグループ(ブログ記事/ウェブページの混在)
  • カテゴリグループ
  • フォルダグループ
  • カテゴリ/フォルダグループ(カテゴリ/フォルダの混在)
  • ウェブサイトグループ
  • ブロググループ
  • ウェブサイト/ブロググループ(ウェブサイト/ブログの混在)
  • オブジェクトグループ(ウェブサイト/ブログ/カテゴリ/フォルダ/ブログ記事/ウェブページの混在)
  • アイテムグループ
  • バナーグループ(広告)
  • リンクグループ
  • テンプレートグループ
  • カスタムオブジェクト
  • カスタムオブジェクトを継承して作成されたオブジェクト

「システムオブジェクト」として指定したオブジェクト(例:ブログ記事)の編集画面に以下のようなボタンが表示されますので、リンクをクリックしてダイアログから作成したグループを選択します。

グループの選択ボタン

通常MTのカスタムフィールドはファンクションタグになりますが、Power CMSのグループについてはブロックタグになり、グループに登録されたアイテムが指定した順番通りに出力されます。例えばタグを「EntryBannerGroup」とした場合、以下のようにテンプレートを書くことができます。

<MTEntryBannerGroup>
<mt:if name="__first__"><ul></mt:if>
<li><a href="<$MTCampaignURL encode_html="1"$>"><img src="<$MTCampaignBannerURL encode_html="1"$>" width="<$MTCampaignBannerWidth$>" height="<$MTCampaignBannerHeight$>" alt="<$MTCampaignTitle encode_html="1"$>" /></a></li>
<mt:if name="__last__"></ul></mt:if>
</MTEntryBannerGroup>

カスタムフィールドで指定したグループ名を出力する

さて、ようやく本題です。Power CMS標準ではグループ名を出力することはできませんが、下記の方法で取得することができるようになります。

まず、GetNameプラグインをインストールします。modelモディファイアとidモディファイアを指定して、そのオブジェクトの名前を出力するプラグインです。

Power CMSのグループカスタムフィールドタグに raw="1" モディファイアを付けます。こうすることで、選択された(関連付けられた)グループのIDを得ることができます。そのIDをGetNameプラグインを用いて出力します。

<MTEntryBannerGroup raw="1" setvar="group_id"></MTEntryBannerGroup>
<MTGetName model="campaigngroup" id="$group_id" escape="html">

実はこのプラグインはサポートへの質問を受けて作成したものです。Power CMSのサポートチームではお客さまのご要望へお答えする、お客さまの課題を解決するために様々なサポートを行っています。マニュアルを見て“できそうにないな”と思った件でもお気軽にサポートへ相談してみてください。このような形で解決策をご提示できるかもしれません。

カテゴリー:Power CMS 3サポートテンプレート作成Tipsプラグイン

Movable Type案件での納品時のドキュメント、皆さんはどのようなものを作成していますか? アルファサードではプラグイン開発やカスタムWebアプリ等を作る際には設計ドキュメントやテーブルスキーマ一覧、テスト仕様書やテストのエビデンス等を作成しますが、テンプレート構築を含む案件ではテンプレートの一覧を作成してどの部分を修正するためにはどのテンプレートが対象になるかを一覧にして渡すケースもあるかと思います。

もちろん、テンプレート名やソースから直感的に「どの部分の修正はどこ」が分かるような作り方をしておくのがベターなのはいうまでもありません。

また、再構築処理の最適化のために再構築トリガーの洗い出しにテンプレートの一覧を出力したいといったケースもあるでしょう。そういうシーンでのテンプレートリストを出力する用途でTemplatesプラグインを作成しました。

以下のテンプレートはすべてのウェブサイト/ブログのインデックス・テンプレートのうち公開オプションが「スタティック(既定)」且つ拡張子htmlのものをCSVとして出力するテンプレートです。Power CMS for MTがインストールされている場合、エンコーディング欄の「このアーカイブをShift_JIS出力する出力する」にチェックを入れて、Windows 向けの CSV を書き出すことができます。

<MTTemplates include_blogs="all" sort_by="blog_id" type="index" build_type="1" html="1"><MTTemplatesHeader>ブログ名,テンプレート名,blog_id,template_id,管理画面URL<MTFor regex_replace="/(?<!\r)\n|\r(?!\n)/","\r\n">
</MTFor></MTTemplatesHeader>"<$MTBlogName regex_replace='/(?=")/g','"'$>","<$MTVar name="template_name" regex_replace='/(?=")/g','"'$>",<$MTVar name="template_blog_id"$>,<$MTVar name="template_id"$>,<$MTCGIPath$><$MTAdminScript$>?__mode=view&_type=template&id=<$MTVar name="template_id"$>&blog_id=<$MTVar name="template_blog_id"$><MTFor regex_replace="/(?<!\r)\n|\r(?!\n)/","\r\n">
</MTFor></MTTemplates>

MTTemplatesブロックタグのループ内ではmt_templateテーブルの各カラムの値が <$mt:var name="template_name"$>(テンプレート名の場合)の要中たちで取得できます。カスタムフィールドの値はカスタムフィールドに指定したテンプレート・タグで取り出せますので、テンプレートにテキストエリアを追加してテンプレートの説明を記述するようにしておけばドキュメント作成の手間を軽減できるようになります。

指定可能なモディファイア

blog_idブログID
include_blogs対象とするブログIDを列記(カンマ区切り)または"all" "children" "siblings"が指定可能です。
exclude_blogs対象外とするブログIDを列記(カンマ区切り)します。
typeテンプレートのタイプです。index(インデックス), individual(ブログ記事), page(ウェブページ), custom(モジュール), archive(アーカイブ)等が指定できます。
build_type公開オプションです(0=再構築しない, 1=スタティック, 2=手動, 3=ダイナミック, 4=公開キュー経由)。
sort_by表示順に指定するカラム名
sort_order表示順(descendもしくはascend)
include_backupバックアップテンプレートを含む場合に指定します。typeモディファイアの指定がある場合はそちらが優先されます。
not_template_idIDを指定した単一のテンプレートを除いて出力します。

プラグインはスタティックパブリッシング専用です。ファイルを実際に生成したくない場合にはインデックス・アーカイブを作成してプレビュー機能を使うとよいでしょう。

アルファサードでは現在 Power CMS パートナーを募集しています。パートナー様に対しては GitHub で公開中のプラグイン(50近くあります!)のサポートも行っています。予算的に Power CMS の導入が難しいケースでもプラグインを活用した構築に関するサポートやライセンスの割引購入、非公開の技術資料のご提供などのメリットがあります。是非この機会にご検討ください。

カテゴリー:テンプレート作成Tipsプラグイン

アルファサードでは今期「パートナーを支援する会社へ」を全社方針とし、取り組んでいます。

その一環として、2011年7月12日のPower CMS for MT ver.3の発表と合わせて、「Power CMS Partner」制度を発足いたしました。

弊社製品をご利用・ご提案いただいているWeb制作会社様、システム開発会社様、デザイン会社様により一層お役立て頂ける特典をご用意しました。

自社評価用・デモ用ライセンスのご提供をいたしますので、お客様へのご提案時に弊社製品を用いてその場で管理画面を作成することも可能です。Power CMS for MT ver.3カスタムオブジェクト等を利用して、是非わかりやすい管理画面を作ってクライアントへのご提案にお役立てください。

また、先日7月26日に行われたセミナーのスライドなど、技術情報や販促資料等をパートナー様限定でご提供いたします。

パートナー制度の詳細について

Power CMS Partner とは、アルファサード有限会社(以下、アルファサード)の製品を取り扱う法人または個人に対して行う支援制度です。

パートナープログラムは2種類あります。企業様向けに「Power CMS Partner Pro」、5名以下の法人又は個人向けに「Power CMS Partner SOHO」です。

Power CMS Partner にご登録いただいたパートナー様には、以下の特典をご提供いたします。

製品情報や技術情報等のご提供
アルファサードから製品情報や技術情報等を受け取ることができます。
製品や技術の最新情報の他、一般には公開していないセミナースライドなどをご提供いたします。
アルファサード製品の割引価格でのご提供
Power CMS for MT、Xtalkなどアルファサード製品を割引価格でご購入頂けます。
※割引率につきましてはお問い合わせください。
製品サイト/アルファサード サイトでのご紹介
パートナー様の基本情報や構築事例などを、製品サイト・アルファサードのウェブサイトにてご紹介いたします。
自社評価用・デモ用ライセンスのご提供
自社評価用、デモ用にPower CMS for MTの最新版(Proの場合はエンタープライズ版、SOHOの場合はスタンダード版)、及びXtalkライセンスが提供されます。
お客様へのご提案などを目的に、各製品をご評価頂けます。
※Movable Typeのライセンスは別途必要です。
アルファサード作成プラグインのサポート/商用ライセンスでのご利用
アルファサードのプラグイン(https://github.com/alfasado)をサポート付き/商用ライセンスで利用できます。
製品ロゴ/パートナーロゴのご利用
製品ロゴ/パートナーロゴデータをご提供いたします。ご提案書や御社サイトへの掲載などにご使用頂けます。
自社ブランドでの製品販売(Partner Proのみ)
要件を満たした場合、OEMライセンス契約により、自社ブランドでの製品販売が可能です。
セミナーの共催(Partner Proのみ)
要件を満たした場合、共同プロモーション(セミナーでの事例紹介)等に参加することができます。

登録料・年会費

必要な登録料と年会費は次の通りです。

パートナー種別登録料(初年度会費含む)年会費(2年目以降)
Power CMS Partner Pro105,000円(税込)52,500円(税込)
Power CMS Partner SOHO52,500円(税込)25,750円(税込)

カテゴリー:Power CMS 3

本日(6月25日)MTDDC(Movable Type Developers & Designers Conference)が開催されています。その中でMTチームはセキュリティ強化月間という発表がされていました。

弊社では、MT5.0xから5.1xのリリース時にいくつかの脆弱性レポートもしくはパッチをシックス・アパートのMTチームに送付させていただきました。現在開発が佳境を迎えているPower CMS3の開発の中では、セキュリティポリシーを新たに定め直してコードレビューを行っています。

ここではMTのメソッドを例にとって、どのようにコードを見ていくかについての手順と、脆弱性に限らずバグを発見するためのデバッグ方法のヒントなどを紹介します。

MTに限った話ではないですが、まずはソフトウェアのお作法や開発の慣習を理解することから始まります。MTにおけるメソッドのレビュー・デバッグを例にとって考えてみたいと思います。

通常MTでは mt.cgi?__mode=foo&_type=bar&id=buz&blog_id=1 のような形でリクエストを送ります。

この、__mode=foo のfooを「mode(モード)」と呼びます。この各モードに対する動作を定義しているのが「method(メソッド)」です(MVCで言うところのContoroller)。

mt.cgi?__mode=dashboard

の場合、モードは「dashboard」です。基本的にはモードごとにメソッドが指定されています。

メソッドはMTが標準で定義されているメソッド(core_methods)の他に、プラグインやアドオンで定義されているものも存在します。

※定義されている=registryに登録されているもの

メソッドで行われる処理は基本的に次のようなものです。

“何らかの処理(DBへの書き込み、削除、読み込み、もしくは再構築等の処理)を行った後、テンプレートを読み込んで、パラメタを指定してビルドした結果を返す(もしくは別のmodeへ必要なパラメタを付けてリダイレクトする)。”

mt.cgiの実体はMT::App::CMS(ファイルは mt_dir/lib/MT/App/CMS.pm)で、(MT5.1)の37行目からの sub core_methods{} が各メソッドを定義している部分になります。

sub core_methods {
    my $app = shift;
    my $pkg = '$Core::MT::CMS::';
    return {
        'tools'     => "${pkg}Tools::system_check",
        'dashboard' => "${pkg}Dashboard::dashboard",
        'menu'      => "${pkg}Dashboard::dashboard",
        'admin'     => "${pkg}Dashboard::dashboard",

        ## Generic handlers
        'save'          => "${pkg}Common::save",
        'edit'          => "${pkg}Common::edit",
        'view'          => "${pkg}Common::edit",
        'list'          => "${pkg}Common::list",
# ...

$pkgは'$Core::MT::CMS::'ですので、__mode=dashboard のコードは MT::CMS::Dashboard(ファイルは mt_dir/lib/MT/CMS/Dashboard.pm)の sub dashboard{} がその動作を定義している箇所になります。ダッシュボードの動作で何らかのエラーや確認したい点がある時は、この部分のコードを見ていくということになります。

各プラグインでは以下のように定義されています。

applications:
    cms:
        methods:
            powercms_foo: $PowerCMS::PowerCMS::CMS::powercms_foo

この場合、PowerCMS::PowerCMS::CMS(ファイルは通常 mt_dir/addons/PowerCMS.pack/lib/PowerCMS/CMS.pm もしくは mt_dir/plugins/PowerCMS/lib/PowerCMS/CMS.pmになります)の sub powercms_foo{} がコードになります。

注意したいのは、例えば core_method の save メソッドは

        'save'          => "${pkg}Common::save",

とありますので、MT::CMS::Common の sub save{}がコードの実体ですが、mt_dir/lib/MT/CMS/Common.pm の該当箇所は次のようになっています。

sub save {
    my $app  = shift;
    my $q    = $app->param;
    my $type = $q->param('_type');

    return $app->errtrans("Invalid request.")
        unless $type;

    # being a general-purpose method, lets look for a mode handler
    # that is specifically for editing this type. if we find it,
    # reroute to it.

    my $save_mode = 'save_' . $type;
    if ( my $hdlrs = $app->handlers_for_mode($save_mode) ) {
        return $app->forward($save_mode);
    }
# ...

このメソッドへのリクエストは __mode=save&_type=entry のように_typeパラメタを持ちます(実際はpostリクエストなのでブラウザのアドレスバー等で見かけることはありません)。 つまりこのケースでの変数 $save_mode は 'save_entry' となります。

    if ( my $hdlrs = $app->handlers_for_mode($save_mode) ) {
        return $app->forward($save_mode);
    }

ここで該当するメソッド save_entry が存在するかどうかを調べ、存在すれば $app->forward($save_mode) しています(※そのメソッドに処理をforwardする)。

再び sub core_methods を確認します。以下のように save_entry が存在します。

        'save_entry'   => "${pkg}Entry::save",

つまり、__mode=save&_type=entry で実行されるコードの実体は、MT::CMS::Common の sub save{}ではなく(正確には、このコードを途中まで経由してから別のところへ処理が丸投げされている)、MT::CMS::Entry(ファイルは mt_dir/lib/MT/CMS/Entry.pm)) の sub save{} ということになります。

該当するモードの調べ方

  1. ブラウザのアドレスバーで確認する
    getリクエストの場合、はこれで確認できます。
    http://www.example.com/mt_dir/mt.cgi?__mode=foo&_type=bar&id=buz&blog_id=1
  2. メソッドを呼び出す直前の画面ソースの form のinput要素(type="hidden" name="__mode")の値を確認する
    ※postの前にJavaScriptで値を書き換えるケースもあるので注意が必要です。
  3. ログを取って確認する
    postリクエストの場合では、例えば下記のようなプラグインを書いてプラグインディレクトリに設置し、リクエスト後にシステムログを見て確認します。
name: Debug
id:   Debug
callbacks:
    MT::App::CMS::pre_run: >
        sub {
            my $app = MT->instance;
            $app->log( 'query_string:' . $app->query_string );
            $app->log( 'mode:' . $app->mode );
        }

modeが確認できたら、MT::App::CMS::core_methods もしくはプラグインのregistryの定義を確認して、該当の処理がどこに書かれているかを確認し、処理内容を追っていきます。

該当箇所の特定

MT、もしくはMTにおけるメソッドの話に限りませんが、アプリケーションのファイルが膨大な数になってくると該当の箇所を探すのも大変です。何らかの調査をおこなう際に「箇所を効率良く特定する」ことが大切です。「プラグインでエラーが発生しました」もしくはソースコードの特定の行数がログに残っている場合などは良いのですが、単にエラーが返されたときや手がかりが少ないときなどはエラーメッセージやログに表示されている文字列がヒントに、該当の箇所を特定します。

findコマンドでソースコード内の文字列を grepする

cd /path/to/mt_dir/lib
find . -name "*.pm"|xargs grep 'This is test.'

このコマンドはマッチしたファイル、マッチした箇所前後の文字列を返してくれます。

言語ファイルから特定する

例えば「データベースのエラーでログインを確認できませんでした: ...」というエラーメッセージに遭遇したとします。ユーザーの言語設定が日本語の場合、エラーメッセージは日本語です。mt_dir/lib/MT/L10N/ja.pm を確認して該当のメッセージのオリジナル(英語)の表現を検索します(この検索はテキストエディタ等で行えます)。

    'The login could not be confirmed because of a database error ([_1])' => 'データベースのエラーでログインを確認できませんでした: [_1]',

オリジナルのメッセージを確認できたら先ほどの findコマンドで grepします。

find . -name "*.pm"|xargs grep 'The login could not be confirmed because of a database error'

./lib/MT/App.pm: "The login could not be confirmed because of a database error ([_1])",
./lib/MT/L10N/de.pm:	'The login could not be confirmed because of a database error ([_1])' => 'Anmeldung konnte aufgrund eines Datenbankfehlers nicht durchgeführt werden ([_1])',
./lib/MT/L10N/es.pm:	'The login could not be confirmed because of a database error ([_1])' => 'No se pudo confirmar el acceso debido a un error de la base de datos ([_1])',
./lib/MT/L10N/fr.pm:	'The login could not be confirmed because of a database error ([_1])' => 'L\'identifiant ne peut pas être confirmé en raison d\'une erreur de base de données ([_1])',
./lib/MT/L10N/ja.pm:	'The login could not be confirmed because of a database error ([_1])' => 'データベースのエラーでログインを確認できませんでした: [_1]',
./lib/MT/L10N/nl.pm:	'The login could not be confirmed because of a database error ([_1])' => 'Het aanmelden kon niet worden bevestigd wegens een databaseprobleem ([_1])',

./MT/App.pm以外はすべて言語ファイルなので、該当のエラーは mt_dir/lib/MT/App.pm 内で発生したことがわかります。

おおまかに問題の発生箇所が特定できたら、デバッグログを記録したり、画面に実行状況をフィードバックさせたりしながら検証していきます。

システムログへの保存

先ほど、モードの特定のためのプラグインの例をあげました。システムログへのメッセージの保存は最も手軽なデバッグ方法の一つです。

該当箇所のエラー発生の直前、もしくはモードの先頭箇所からいくつかのポイントに、

MT->log( 'Step 1' );

もしくは

$app->log( 'Step 1' );

といった形でログを残していき、どこまでが正常に実行されたかを特定していきます。

変数の内容を確認したい時には、Data::Dumperモジュールを使うと便利です。例えば変数 $entry が正しくセットされていない時に $entry->id をコールすると

エラーが発生しました: Can't call method "id" on an undefined value at (eval 363) line 1.

のような形でエラーになります。MTのエラー画面にこれが表示されるかシステムログに表示されるかは実行されている処理の種類によります。基本的にメソッドの中で発生した場合はMTのエラー画面にメッセージが表示されます。一方、プラグインによるコールバックの処理などで発生した場合にはシステムログに記録されます(この場合はプラグイン名があわせて記録されるため、特定は比較的容易です)。

変数 $entry が正しくセットされているかをログに残すには、Data::Dumperを用いて以下のようにします。

use Data::Dumper;
MT->log( Dumper $entry );

リアルタイムにフィードバックを得る

MTのシステムログにエラーを表示する方法は手軽ではありますが、実はやってみると結構面倒です。

  1. デバッグログ記録のためのコードを入れる
  2. ブラウザで当該の処理を実行する
  3. システムログをみる

リアルタイムに状態を確認するにはいくつかの方法があります。

メソッドの中で得たい結果を return する

メソッドの実行結果はメソッドのルーチンの中で return したタイミングでブラウザに返されます。 よって、メソッドの中で、

return 'Step 1';

とすればブラウザに結果が返ります。 変数の確認についても先ほどの例と同様に

use Data::Dumper;
return Dumper $entry;

とすれば結果をブラウザでリアルタイムに得ることができます。

強制的にdieする

メソッドから呼ばれているサブルーチンの中では return $foo; が使えないケースがあります。サブルーチンの実行結果をメインルーチンは受け取るだけ、といったケースでは return $foo; は使えません。

この場合は、サブルーチンの中で dieすることでMTのエラーメッセージに確認したい内容を渡すことが出来ます。

die 'Step 1';

または

use Data::Dumper;
die Dumper $entry;

warnings(Perlの警告)を使って確認する

この方法が最も簡単で多くの内容を確認できる方法でです。return や die を使う方法のように、1度に1つの結果しか得られないこともありませんし、システムログのように画面を遷移して結果を確認する必要もありません。また、1度のリクエストの処理に1秒かからなければ、システムログの画面での記録されたログの記録順を確認できないこともあります(同一の秒で保存されたログが保存順に表示されるとは限りません)。

mt-config.cgi に

DebugMode 1

と記述するか、管理画面の全般の設定で、DebugMode を 1に設定します。 あとは、確認したいコードの中に warn $foo; のような形で確認したい内容を吐き出すようにします。

warn 'This is a Debug Message.';

とすると、ブラウザの画面下部に「警告とメッセージ」が表示されます。

Request completed in 1.145 seconds.
This is a Debug Message. at (eval 361) line 1.

尚、DebugMode 2 とするとエラー発生箇所等の情報を画面に表示してくれます。必要に応じて設定しましょう。

カテゴリー:技術情報

Power CMS 3の新しいDynamicMTMLでは、データベースを問わず、もしくは複数のデータベースを組み合わせて(もしくはデータベースがなくても)MTML(MTタグ)が使えるようになっています。

これにより、ステージ配信と組み合わせて静的ファイルを公開サーバーに転送しているようなケースで(公開サーバーからはDBを参照していない)端末の毎の振り分けや何らかの分岐にMTタグを使うことができるようになります。

これまでにも、データベースなしでMTタグを動かすサンプルや、WordPressのDBを参照してMTタグで出力するWordPressプラグインなどを公開していましたが(AlfieとWordPressプラグインはPowerCMS 3に含まれます)、同じくDynamicMTMLをベースにしてCakePHPのテンプレートエンジンとしてMTMLを利用できるようにする(ViewでMTタグを使えるようにする)MTCakeを作成しました。

CakePHPはPHPで書かれたWebアプリケーションフレームワークで、Ruby on RailsのRuby on Railsの影響を強く受けていると言われています。Webアプリケーションを高速に開発するための様々な仕掛けが盛り込まれています。

CakePHPのブログチュートリアルを例にとって、MTCakeを使うことでCakePHPのロジックとプレゼンテーションがどのように分離できるかを見ていきましょう。

CakePHPブログチュートリアル

MTCakeをインストールしたら以下の1から6の手順でPostモデル/コントローラ/ビューを作成します。その後、作成した /app/controllers/posts_controller.php と /app/views/posts/index.ctp をMTCakeを使って書き換えてみましょう。

  1. ブログデータベースの作成
  2. Cakeのデータベース設定
  3. Cakeのデータベース設定
  4. Postモデルの作成
  5. Postsコントローラの作成
  6. Postビューの作成

オリジナルのコード

<!-- File: /app/controllers/posts_controller.php -->
<?php
class PostsController extends AppController {
    var $name = 'Posts';
    function index() {
        $this->set('posts', $this->Post->find('all'));
    }
}
?>

<!-- File: /app/views/posts/index.ctp -->
<h1>Blog posts</h1>
<table>
    <tr>
        <th>Id</th>
        <th>Title</th>
        <th>Created</th>
    </tr>
    <!-- Here is where we loop through our $posts array, printing out post info -->
    <?php foreach ($posts as $post): ?>
    <tr>
        <td><?php echo $post['Post']['id']; ?></td>
        <td>
            <?php echo $html->link($post['Post']['title'], 
array('controller' => 'posts', 'action' => 'view', $post['Post']['id'])); ?>
        </td>
        <td><?php echo $post['Post']['created']; ?></td>
    </tr>
    <?php endforeach; ?>
</table>

posts_controller.php のコードだけでもCakePHPフレームワークの利点が見えると思います。問題は/app/views/posts/index.ctp のほうです。WordPressでもそうなのですが、テンプレートがPHPのコードそのままになっています。ループの部分は <?php foreach ($posts as $post): ?>~ <?php endforeach; ?>、タイトルを取り出すのは配列 $postの[Post]の[title]をPHPのコードで取得しなければなりません。

MTCakeを使って書き換えたコード

<!-- File: /app/controllers/posts_controller.php -->
<?php
class PostsController extends AppController {
    var $name = 'Posts';
    function index() {
        $ctx = $this->ctx;
        $ctx->__stash[ 'vars' ][ 'page_title' ] = 'Blog posts';
        $ctx->stash( 'Post', $this->Post->find( 'all' ) );
        // => <mt:cake:loop model="Post">~</mt:cake:loop>
        // or $ctx->stash( 'posts', $this->Post->find( 'all' ) ); 
        // => <mt:cake:loop model="Post" stash="posts">~</mt:cake:loop>
    }
}
?>

<!-- File: /app/views/posts/index.ctp -->
<h1><mt:var name="page_title" escape="html"></h1>
<!-- Here is where we loop through our posts array, printing out post info -->
<mt:cake:loop model="Post">
<mt:ignore>
    or <mt:cake:loop model="Post" stash="posts">
</mt:ignore>
<mt:if name="__first__">
<table>
    <tr>
        <th>Id</th>
        <th>Title</th>
        <th>Created</th>
    </tr>
</mt:if>
    <tr>
        <td><mt:var name="id"></td>
        <td>
            <a href="./view/<mt:var name="id">"><mt:var name="title" escape="html"></a>
        </td>
        <td><mt:var name="created"></td>
    </tr>
<mt:if name="__last__">
</table>
</mt:if>
</mt:cake:loop>

posts_controller.php のコードはさほど変わっていませんが、/app/views/posts/index.ctp の方は大きく変わっており、PHPのコードは全く入っていません。デザイナーとプラグラマが完全に分業する場合には、MTタグがわかる前提ではありますが、後者の方がデザインテンプレートとしてはロジックとプレゼンテーションが分離できているように感じられませんか?

DynamicMTMLを利用すると、MTのテンプレートエンジンを独立して利用できるようになります。開発言語はPerlとPHPの両方で書くことができます。MTに限らず他のCMSやフレームワークと組み合わせることで、高度なサイト開発・構築が可能になりますが、このエントリでその可能性を感じていただければ幸いです。

カテゴリー:Power CMS 3サイト制作全般プラグイン技術情報

2度目のPower CMS for MT ver.3 の製品発表セミナーが6月9日(木)に開催されます。現段階でまだお申し込みは可能ですので、ご都合のつく方は是非ご参加ください。

2007年にver.1をリリースしてから今秋で4年、これまでを少し振り返りながら新しいPower CMS for MTについて何回かにわけてご紹介したいと思います。

  • 2007年11月 Power CMS for MT ver.1.0 - MT4上で動作する最初のバージョン。拡張フィールド+テンプレートセレクタで管理画面をノンプログラミングでカスタマイズ可能、エントリーグループ(ブログ記事/ウェブページのGUIでの並び替え)、サイト内検索、承認ワークフローに対応。
  • 2008年4月 Power CMS for MT ver.1.1 - MT4.1対応。CSVインポート、アンケートフォーム、ステージ配信、アクセス解析に対応
  • 2010年6月 Power CMS for MT ver.1.5 / Power CMS for MT Enterprise - MT4.2対応。Tree形式のダッシュボード、携帯サイト、会員限定サイト、エンタープライズサーチ、リビジョン管理、リンクチェック、リモートバックアップ、既存HTMLのインポートに対応。
  • 2010年4月 Power CMS for MT ver.2 - MT5対応。ユーザーインターフェイスの改良、Drag & Dropアップロード、DynamicMTML(静的ダイナミック・パブリッシング)に対応、ワークフローリビジョンに対応した新バージョン。
  • 2010年7月 Power CMS for MT ver.2.03 - 広告配信(バナー/キャンペーン管理)、カスタムオブジェクト、グループ&ソート機能の強化、携帯サイトの絵文字に対応。
  • 2011年1月 Power CMS for MT ver.2.05 - 最大250%のパフォーマンス向上。Google Analystics連携、DynamicMTMLを強化(PHP APIを整備)したバージョン。

様々な新しい機能を取り込みながらバージョンアップを重ね来たことがおわかりいただけるかと思います。ver1.5の際に「多機能化」しましたが、その後はUIまわりや足回りの改良、単機能の追加が中心のアップデートであったといえます。

PowerCMS 3

新しいバージョンはこれまでの多機能化路線とは違い(それでも機能だけを見れば大きく増えているわけですが)、製品のコンセプト自体が大きく変わります。コンセプトは「CMS・サイト設計の在り方を変える」「PowerCMSのフレームワーク化」「製品のポテンシャルの底上げ」です。

アウトラインについてはセミナーのスライドを動画でアップしていますので、是非ご覧ください。

カスタムオブジェクト・フレームワークとスニペット・カスタムフィールド

当社では“MT脳”と呼んでいるのですが、MT(に限らず一般的なCMS製品、もしくはBlogエンジン)でサイトを設計する時に、権限やコンテンツの種類ごとにウェブサイト(ブログ)をどんどん増やしていって結果として肝心の“マネジメント”がしにくい状況になってしまうケースを見かけます。

MTのオブジェクトの構成(概略)

MTのカスタムフィールドで管理画面のバリエーションをいくつも持てる、が故に今度はカスタムフィールドの数が数千規模になってしまうようなケースも見かけます。

これは、MTが基本的にウェブページ/ブログ記事という2種類のコンテンツ管理しか出来ないために、コンテンツの種類ごとにブログを分けてマルチブログ(ポータル機能)で連携させるという手法をとるわけです。使い勝手を上げるために管理画面のラベルを変更したりjQueryでフィールドのレイアウトを変更したりといった工夫をするわけですが、このような設計をしていると以下のような問題をどうするかが課題になってきます。

  • カスタマイズの工数とコスト負担を誰がみるのか
  • 行き過ぎたカスタマイズとバージョンアップ耐性問題
  • 再構築トリガーのためにシステム全体が重量化、サーバー負荷の増大

一つ目の問題に対する新しいPowerCMSの答えは、「管理画面の操作とHTML(CSS)さえわかれば、ノンプログラミングで高度にカスタマイズできるCMS」です。その肝になるのが「カスタムオブジェクト・フレームワーク」と「スニペット・カスタムフィールド」の2つです。

カスタムオブジェクト・フレームワークは、MTが持っているMT::ObjectとMT5.1の新機能であるListing Frameworkを拡張したもので、管理画面であらゆるオブジェクトを管理、そしてコンテンツとして出力できるものです。

オブジェクトとは何か

一口にウェブサイトといっても、そこで扱う情報はサイトによってまちまちです。

  • BtoB企業のコーポレートサイト
  • ECサイト
  • 出版社のサイト
  • 家電メーカーのサイト
  • ニュース系ポータルサイト
  • コミュニティサイト

これらのサイトでは扱うモノ(オブジェクト)が違います。

出版社のウェブサイトが扱うオブジェクト
スポーツ系ポータルサイトが扱うオブジェクト
  • すべてはオブジェクトである
  • オブジェクトは相互に関連付けられている
  • 文章(テキスト)、画像(写真)、動画、サウンドもオブジェクト
  • オブジェクトによって構造(オブジェクトが持つ情報=DBのカラム)は違う
  • オブジェクトによって適している入力フォーマット、表現(ページのレイアウトやデザイン)は違う

こういったものをひとつのツール(Movable Type=CMS)で管理するために、従来私たちははツールの持つ構造にサイトの情報を当てはめていく発想、手法を用いていたように思います。もしくはサイトで扱う種類にあわせて“近い”ツールを選ぶといったことを行っていました。

PowerCMSではツールにサイトが歩み寄るのではなく、サイトにあわせてツールが歩み寄ることができます。

カスタムオブジェクト・フレームワークとは、Movable Typeが持つMT::ObjectのAPIとMT5.1のListing Frameworkを拡張し、自由なCMS設計を可能にする技術です。

カスタムオブジェクト・フレームワークによって拡張されたメニュー/一覧画面
  • 様々なオブジェクトを一覧で画面できる
  • 各オブジェクトには専用の編集画面が用意される
  • オブジェクト毎にユーザー権限を設定できる
  • オブジェクトの表示順をGUIで設定できる
  • オブジェクトの階層管理ができる
  • オブジェクトをテンプレートエンジンを介してページ出力できる
  • オブジェクトは相互に関連づけることができる
  • オブジェクトはインポート/エクスポートできる

スニペット・カスタムフィールド

カスタムオブジェクトはサイトが扱う情報(オブジェクト)毎に“素直”にCMSの構成を設計することを可能にします。一方でスニペット・カスタムフィールドは、それぞれのオブジェクトの投稿・管理インターフェイスを自由に設計することを可能にします。

スニペット・カスタムフィールド

Adobe DreamweaverやMicrosoft Visual Studioにあるコードスニペットは文字通りあらかじめ登録した「コードの断片」を簡単に挿入できる機能ですが、PowerCMSのスニペット・カスタムフィールドはHTMLで作成したコードがそのまま管理画面のフォームに挿入されます。

受け取り側のコード(プログラム)は一切書く必要がありません。input要素やtextarea、typeがfileのinput要素で添付ファイルを付けることもできます。これにより、出力されるウェブサイト上のページのレイアウトに限りなく近い管理画面の投稿インターフェイスをつくることが可能になり、カスタム・フィールドを増やすことで陥りがちな“縦長で見通しの悪い管理画面”になることを防ぐことができます。

各機能の詳細については今後のエントリで何度かにわけてご紹介していきたいと思います。

実際の管理画面のデモは明後日のセミナーでも披露いたします。ご興味のある方は是非お越し下さい。

カテゴリー:Power CMS 3

WordPressはデータベースにMySQLを利用し、PHPで書かれたオープンソースのブログソフトウェアです。豊富なテーマやプラグインによる拡張性の高さから数多くのブログやウェブサイトで利用されています。

Power CMS for MTのDynamicMTMLエンジンを利用することで、WordPressのコンテンツをMTML(Movable Type Markup Language=MTタグ)で呼びだして表示制御することができます。この機能はWordPressプラグインによって提供され、ダイナミックパブリッシングもしくはDynamicMTML上で動作します。

WordPressコンテンツを表示するMT:WPタグ

WordPressのコンテンツを表示するにはMT:WPタグを利用します。MT:WP:Entriesはブログ記事(WordPressの「投稿」)をループ表示するブロックタグです。

テンプレート・タグの例を以下に示します。

<mt:wp:Entries category="Foo" limit="20">
    <mt:if name="__first__"><ul></mt:if>
    <li class="<mt:if name="__odd__">odd<mt:else>even</mt:if>">
        <a href="<$mt:wp:EntryPermalink$>">
            <$mt:wp:EntryTitle escape="html"$>
            (<$mt:wp:EntryAuthorDisplayName$> / <$mt:wp:EntryDate format="%b %Y"$>)
        </a>
        <mt:wp:EntryCategories glue=",">
            <mt:if name="__first__">Categories:</mt:if>
            <a href="<$mt:wp:CategoryLink$>">
                <$mt:wp:CategoryLabel$>
            </a>
        </mt:wp:EntryCategories>
        <mt:wp:EntryTags glue=",">
            <mt:if name="__first__">Tags:</mt:if>
            <a href="<$mt:wp:TagLink$>">
                <$mt:wp:TagName$>
            </a>
        </mt:wp:EntryTags>
    </li>
    <mt:if name="__last__"></ul></mt:if>
</mt:wp:Entries>

WordPressの一般的なテンプレート記述はPHPコードですが、WordPressプラグインを利用することで、テンプレート・タグは完全にロジックと分離され、見通しが良くなることがおわかりいただけるかと思います。

インストールと設定

  1. DynamicMTMLのインストール(インストールについてはこちらのドキュメントを参照)
  2. wp-config.cgiを設定します(mt/plugins/WordPress/wp-config.cgi)。記述方法についてはMovable Typeのmt-config.cgiと互換性があります。
  3. wp-prefix.phpを設定(データベースのprefixを指定します)。

*wp-prefix.phpの例

<?php
// DATABASE PREFIX
define( 'WP_PREFIX', 'wp_' );
?>

これでWordPressのコンテンツをMTMLで処理する準備が整いました。

Movable TypeのコンテンツとWordPressコンテンツを一つのページに表示する

簡単な例として、Alfie(DynamicMTMLのテンプレートエンジンの愛称)を利用したテスト方法をご紹介します。

  1. Movable TypeとWordPressをインストールします。Movable Typeではウェブサイトの直下にブログを1つ作成します(blog_idは2となります)。
  2. ドキュメントルート直下にalfieディレクトリを設置します。
  3. alfie/alfie.phpを編集します($mt_dirにMTのインストールパス、blog_idにMTのブログIDを指定します)。
    <?php
        $mt_dir = '/var/www/cgi-bin/mt';
        $SEP = DIRECTORY_SEPARATOR;
        $blog_id = 2;
        require_once( $mt_dir . $SEP . 'addons' . $SEP . 'DynamicMTML.pack' .
                                $SEP . 'php' . $SEP . 'dynamicmtml.run.php' );
    ?>
  4. _htaccessを編集し、.htaccessにリネームします。この例は、/alfieディレクトリ以下の拡張子htmlのファイルを動的処理し、MTとWordPressのコンテンツを動的に処理可能にする例です。
    Options -Indexes +SymLinksIfOwnerMatch
    DirectoryIndex /alfie/alfie.php
    <IfModule mod_rewrite.c>
      RewriteEngine On
      RewriteCond %{REQUEST_FILENAME} !-f [OR]
      RewriteCond %{REQUEST_FILENAME} -d [OR]
      RewriteCond %{REQUEST_FILENAME} ^[^.]+$|\.(html|HTML)$ [NC]
      RewriteRule ^ alfie.php [L]
    </IfModule>
    <IfModule !mod_rewrite.c>
      Order Deny,Allow
      Deny from all 
    <FilesMatch (^(|[^.]+)|alfie.php?)$>
      Allow from all
    </FilesMatch>
      ErrorDocument 403 /alfie/alfie.php
      ErrorDocument 404 /alfie/alfie.php
    </IfModule>
    php_flag short_open_tag off
  5. /alfie/index.htmlを作成し、テンプレートを記述します。
    <h1><$mt:BlogName$></h1>
    <h1><$mt:wp:BlogName$></h1>
  6. ブラウザで/alfie/にアクセスします。

Movable TypeとWordPressのコンテンツをブラウザで表示

MT:WPテンプレートタグ

mt:wp:Entries(ブロックタグ) * mt:wp:get_posts, mt:wp:postsはmt:wp:Entriesのエイリアス

WordPressの「投稿」(ブログ記事)をループ出力します。下記のモディファイアが利用可能です。

id            :IDが一致する投稿を1件読み込みます。
category      : カテゴリ名で投稿を絞り込みます。
category_id   : カテゴリIDで投稿を絞り込みます。
tag           : Tagで投稿を絞り込みます。
status        : ステータスを指定します。'*'を指定するとすべてを対象にします。 'publish' がデフォルト値です。
type          : 投稿の種類(type)を指定します。'*'を指定するとすべてを対象にします。 'post' がデフォルト値です。
sort_by       :投稿の表示順を指定します。IDが初期値です。
sort_order    : 'ascend(昇順)'または'descend(降順 - 初期値)'を指定します。
lastn         : 表示する投稿の数を指定します。
offset        : limitモディファイアと一緒に指定し、先頭のoffset件をスキップしてロードします。
limit         :数値を指定してロードする投稿件数を指定します。
glue          : ループ出力の区切り文字を指定します。
mt:wp:EntryNext(ブロックタグ) * mt:wp:next_postはmt:wp:EntryNextのエイリアス

現在のコンテキストの投稿の1件次の投稿をブロックコンテキストにセットします。キーはauthored dateです。

mt:wp:EntryPrevious(ブロックタグ) * mt:wp:previous_postはmt:wp:EntryPreviousのエイリアス

現在のコンテキストの投稿の1件前の投稿をブロックコンテキストにセットします。キーはauthored dateです。

mt:wp:Categories(ブロックタグ) * mt:wp:list_categoriesはmt:wp:Categoriesのエイリアス

WordPressの「カテゴリ」をループ出力します。下記のモディファイアが利用可能です。

hide_empty    : 1を指定するとカテゴリに属する投稿がないカテゴリを含んで読み込みます。
toplevel      : mt:wp:SubCategoriesと同様です。
sort_by       :投稿の表示順を指定します。IDが初期値です。
sort_order    : 'ascend(昇順)'または'descend(降順 - 初期値)'を指定します。
lastn         : 表示する投稿の数を指定します。
offset        : limitモディファイアと一緒に指定し、先頭のoffset件をスキップしてロードします。
limit         :数値を指定してロードする投稿件数を指定します。
glue          : ループ出力の区切り文字を指定します。
mt:wp:Tags(ブロックタグ)

WordPressの「タグ」をループ出力します。下記のモディファイアが利用可能です。

hide_empty    : 1を指定するとタグに属する投稿がないタグを含んで読み込みます。
sort_by       :投稿の表示順を指定します。IDが初期値です。
sort_order    : 'ascend(昇順)'または'descend(降順 - 初期値)'を指定します。
lastn         : 表示する投稿の数を指定します。
offset        : limitモディファイアと一緒に指定し、先頭のoffset件をスキップしてロードします。
limit         :数値を指定してロードする投稿件数を指定します。
glue          : ループ出力の区切り文字を指定します。
mt:wp:EntryCategories(ブロックタグ) * mt:wp:get_the_categoryはmt:wp:EntryCategoriesのエイリアス

現在の投稿が属するカテゴリをループ出力します。このタグの中ではmt:wp:Category関係のテンプレートタグが利用できます。

mt:wp:EntryTags(ブロックタグ) * mt:wp:get_the_tagsはmt:wp:EntryTagsのエイリアス

現在の投稿につけられたタグをループ出力します。このタグの中ではmt:wp:Tag関係のテンプレートタグが利用できます。

mt:wp:ArchiveList(ブロックタグ)

月別アーカイブのリストを出力するためのブロックタグです。テンプレートの例:

<mt:wp:ArchiveList archive_type="Monthly">
<mt:if name="__first__"><ul></mt:if>
    <li>
        <a href="<mt:wp:ArchiveLink archive_type="Monthly">">
            <mt:wp:archivetitle format="%b %Y">(<mt:wp:ArchiveCount>)
        </a>
    </li>
<mt:if name="__last__"></ul></mt:if>
</mt:wp:ArchiveList>
mt:wp:SubCategories(ブロックタグ) * mt:wp:get_the_tagsはmt:wp:EntryTagsのエイリアス

サブカテゴリを階層化してリスト表示するブロックタグです。

hide_empty    : 1を指定するとカテゴリに属する投稿がないカテゴリを含んで読み込みます。
sort_by       :投稿の表示順を指定します。IDが初期値です。
sort_order    : 'ascend(昇順)'または'descend(降順 - 初期値)'を指定します。
lastn         : 表示する投稿の数を指定します。
offset        : limitモディファイアと一緒に指定し、先頭のoffset件をスキップしてロードします。
limit         :数値を指定してロードする投稿件数を指定します。
glue          : ループ出力の区切り文字を指定します。

テンプレートの例:

<mt:wp:SubCategories hide_empty="1">
<mt:wp:SubCatisFirst><ul></mt:wp:SubCatisFirst>
    <li>
        <a href="<mt:wp:CategoryLink>">
        <mt:wp:CategoryLabel> (<mt:wp:CategoryCount>)
        </a>
    <mt:wp:SubCatsRecurse></li>
<mt:wp:SubCatisLast></ul></mt:wp:SubCatisLast>
</mt:wp:SubCategories>
mt:wp:SubCatIsFirst(ブロックタグ)

mt:wp:SubCategoriesループの最初のループで出力されます。

mt:wp:SubCatIsLast(ブロックタグ)

mt:wp:SubCategoriesループの最後のループで出力されます。

mt:wp:SubCatIsLast(ブロックタグ)

mt:wp:SubCategoriesループの最後のループで出力されます。

mt:wp:SubCatsRecurse(ブロックタグ)

現在のカテゴリに属するサブカテゴリの mt:wp:SubCategories ブロックを再帰的に表示します。

mt:wp:BlogName(ファンクションタグ)

ブログ名を表示します。

mt:wp:BlogInfo(ファンクションタグ)

ブログに関する情報を表示します。 テンプレートの例:

<$mt:wp:BlogInfo name="blogdescription"$>

=>Just another WordPress site
mt:wp:BlogURL(ファンクションタグ) * mt:wp:site_urlはmt:wp:BlogURLのエイリアス

ブログのURLを表示します。

mt:wp:EntriesCount(ファンクションタグ) * mt:wp:count_postsはmt:wp:EntriesCountのエイリアス

ブログに属する投稿数を表示します。

category      : 対象とする投稿が属するカテゴリ名。
category_id   :対象とする投稿が属するカテゴリID。
tag           :対象とする投稿につけられたタグ名。
status        : ステータスを指定します。'*'を指定するとすべてを対象にします。 'publish' がデフォルト値です。
type          : 投稿の種類(type)を指定します。'*'を指定するとすべてを対象にします。 'post' がデフォルト値です。
mt:wp:EntryTitle(ファンクションタグ) * mt:wp:the_titleはmt:wp:EntryTitleのエイリアス

現在の投稿のタイトルを表示します。

mt:wp:EntryBody(ファンクションタグ) * mt:wp:the_content, mt:wp:EntryContentはmt:wp:EntryBodyのエイリアス

現在の投稿の本文を表示します。

mt:wp:EntryExcerpt(ファンクションタグ) * mt:wp:the_excerptはmt:wp:EntryExcerptのエイリアス

現在の投稿の概要を表示します。

mt:wp:EntryGUID(ファンクションタグ) * mt:wp:the_guidはmt:wp:EntryGUIDのエイリアス

現在の投稿のguidを表示します。

mt:wp:EntryAuthorDisplayName(ファンクションタグ)

現在の投稿の投稿者名を表示します。

mt:wp:EntryAuthor(ファンクションタグ) * mt:wp:the_authorはmt:wp:EntryAuthorのエイリアス

現在の投稿の投稿者IDを表示します。

mt:wp:EntryDate(ファンクションタグ) * mt:wp:the_dateはmt:wp:EntryDateのエイリアス

現在の投稿の投稿日を表示します。日付に関するモディファイアが指定できます。

mt:wp:EntryPermalink(ファンクションタグ) * mt:wp:the_permalinkはmt:wp:EntryPermalinkのエイリアス

現在の投稿パーマリンクを表示します。テンプレートの例:

<$mt:wp:EntryPermalink$>

=> http://www.example.com/p=1
mt:wp:EntryMeta(ファンクションタグ) * mt:wp:post_metaはmt:wp:EntryMetaのエイリアス

keyモディファイアを指定して現在の投稿のカスタムフィールドの値を表示します。

mt:wp:CategoryLabel(ファンクションタグ) * mt:wp:cat_nameはmt:wp:CategoryLabelのエイリアス

カテゴリのコンテキスト内でカテゴリ名を表示します。

mt:wp:CategorySlug(ファンクションタグ)

カテゴリのコンテキスト内でカテゴリの'slug'を表示します。

mt:wp:CategoryCount(ファンクションタグ)

カテゴリのに属する投稿の数を表示します。

mt:wp:TagName(ファンクションタグ) * mt:wp:tag_nameはmt:wp:TagNameのエイリアス

タグのコンテキスト内でタグ名を表示します。

mt:wp:TagSlug(ファンクションタグ)

タグのコンテキスト内でタグの'slug'を表示します。

mt:wp:TagCount(ファンクションタグ)

タグのコンテキスト内でタグが付けられた投稿の数を表示します。

mt:wp:ArchiveLink(ファンクションタグ) * mt:wp:get_month_link はmt:wp:ArchiveLinkのエイリアス

mt:wp:ArchiveListブロックタグの中でアーカイブへのリンクを表示します。

<$mt:wp:ArchiveLink archive_type="Monthly"$>

=> http://www.example.com/?month=yyyymm

様々なデータベースへの接続とテンプレートエンジンのメリットを活かす

DynamicMTMLを利用すれば、このように複数のデータベースのデータをテンプレーエンジンを介して出力することができます。WordPressに限らず、他のCMSや既存のデータベースとMovable Typeを連携させるようなサイト構築にDynamicMTMLが活用いただけることがおわかりいただけたかと思います。

参考リンク

カテゴリー:プラグイン技術情報

  • Alfasado
Alfasado