PHP4 テンプレートクラスライブラリ改 - tmpl2.class.php

作成 2002-03-13
修正 2002-10-20

このクラスライブラリは 川里 様が公開しているPHP4テンプレートクラスライブラリ tmpl204.class.tar.gz(19KB) - v2.0.4 (2001/12/24) をベースに、多重ループ(ネスト)に対応したものです。 素晴らしいライブラリを公開し、またこのソース公開の許可を頂いた 川里 様に感謝します。

クラスライブラリ名を tmpl2.class.inc から tmpl2.class.php に変更しています。
最新版は 2002-10-20 Ver 0.7 (tmpl2.class.php,v 1.18) です。


ライセンス

元のクラスライブラリをベースにしているので、このクラスライブラリも同じ LGPL で配布します。
LGPL に関しては以下のリンクを参照してください。

GNU 劣等一般公衆利用許諾契約書 (LGPL)
http://www.gnu.org/copyleft/lesser.ja.html


使用上の注意

このクラスライブラリの動作保証はしていません。自己責任で利用してください。


動作環境

PHP 4.1.x 以降(mbstring が有効であること:mb_convert_encoding() 関数使用 )

テスト環境1

テスト環境2


使い方

  1. クラスライブラリ(tmpl2.class.php)をWebサーバ上に用意します。
  2. Webサーバ上にテンプレート用 HTML "hello.html" を記述します。
    <html>
    <head>
    <title>test</title>
    </head>
    <body>
    Hello %language% World!
    </body>
    </html>
  3. Webサーバ上にPHP ソース "hello.php" を記述します。
    <?php
    include("tmpl2.class.php");
    $tmpl = new Tmpl2( "hello.html" );  // クラス初期化
    $tmpl->assign( "language", "PHP" );   // %language% を PHP に置き換え
    $tmpl->flush();  // 結果出力
    ?>
  4. Webサーバ上にある "hello.php" をブラウザで開きます。
    Hello PHP World!

    このように表示されれば、OKです。

詳しくはサンプルソースを参照してください。


仕様

元のPHP4テンプレートライブラリクラスに、loop のネスト、ifdef のネストと ifndef を付加させました。
基本的な機能はそのままに、HTML側で指示できる事を増やしています。
シンプルさは失っていますが、HTMLとPHPソースの分離には役立つはずです。

HTML上で指示

動作 記述 説明
ループ ループの開始 <!-- tmpl:loop %XXX% --> XXX にはPHP側と同じ名前を利用してください。
※ ループごとに別々の名前を付けてください。
※ ネスト可能。
ループの終了 <!-- tmpl:endloop %XXX% --> XXX にはPHP側と同じ名前を利用してください。
条件判断 判断文(定義済) <!-- tmpl:ifdef %XXX% --> XXX を定義していれば、そのブロックを有効にします。
※ ネスト可能。
判断文(未定義) <!-- tmpl:ifndef %XXX% --> XXX を定義されていなければ、そのブロックを有効にします。
※ ネスト可能。
(元仕様に追加)
条件反転 <!-- tmpl:else --> ifdef / ifndef の条件が成り立たない場合、そのブロックを有効にします。
(元仕様に追加)
条件判断終了 <!-- tmpl:endif --> ifdef / ifndef のブロック終端。
条件指示 <!-- tmpl:def %XXX% --> ifdef / ifndef で使用する条件判断の定義を行います。
※ PHP 側 の assign_def() と同等機能です。
(元仕様に追加)
拡張子変更 <!-- tmpl:ext2php %XXX% --> このコメント部の後ろに続く部分で XXX から php に変更します。
※ この機能はその1行だけしか有効になりません。
※ デザイン時は html でリンクテストを行い、PHP実行時には php でリンクする場合に有効。
(元仕様に追加)
ループ内条件判断 判断文(定義済) <!-- tmpl:ifldef %XXX% --> XXX を定義していれば、そのブロックを有効にします。
※ ネスト不可。 assign_def() ではなく assign() で値を定義することに注意してください。
(test07a.php を参照)
(ver 0.4 より追加)
条件判断終了 <!-- tmpl:endifl --> ifldef のブロック終端。
※ ネスト不可。
(test07a.php を参照)
(ver 0.4 より追加)

※ <!-- tmpl:ext2php ... --> を除き他の指示行はHTML出力時に削除するため、タグを続けて記入しないで下さい。

PHP上のコード

詳しくはサンプルのソースを参照
以下の説明は $tmpl = new Tmpl2 ; した場合の例です。

動作 記述 説明
コンストラクタ new Tmpl2( $filename , $icode , $ocode ) ; クラスのインスタンス生成を行う。

■引数
$filename : テンプレートHTMLファイル名の指定(初期値は "./template.htm")
$icode : テンプレートとPHPのコード("SJIS","JIS","EUC-JP" 等、初期値は"")
$ocode : 出力コード("SJIS","JIS","EUC-JP" 等、初期値は"SJIS")

■戻り値
  無し
デバックモード $tmpl->dbgmode( $dbgflag ) ; デバックモードの指示を行います。
開発者のテスト用なので通常は使用しません。

■引数
$dbgflag :
  -1 なら処理時間とループ回数の報告。
  0 ならデバック情報無し(初期値)
  1 なら配列情報の出力
  2 ならより詳しい出力

■戻り値
  無し
漢字変換設定 $tmpl->set_kcode( $conv , $incode , $outcode ) ; 漢字変換の設定を行います。
※ PHPの mbstring が有効でないと使えません(参照: mb_convert_encoding() )。

■引数
$conv : 1 なら変換する。 0 なら変換しない。
$incode : テンプレートとPHPのコード("EUC-JP","UTF-8" 等、初期値は"EUC-JP")
$outcode : 出力コード("SJIS","JIS","EUC-JP" 等、初期値は"SJIS")

■戻り値
  無し
テンプレートファイル名の指定 $tmpl->set_fname( $filename ) ; テンプレートファイル名の指定を行います。

■引数
$filename : テンプレートファイル名。

■戻り値
  無し
置換用文字列の追加 $tmpl->assign( $name , $value ) ; 置換用文字列の追加を行います。

■引数
$name : 置換する名前。
$value : 置換する値。

■戻り値
  無し

※ ループの内と外で保管する配列が違うことに注意してください。
ループ内部で設定した置換文字列はループ内のみ有効です。
ループ外で設定した置換文字列はループ内外とも有効です。
ifdef / ifndef 展開変数の追加 $tmpl->assign_def( $name ) ; ifdef / ifndef 展開文字列の追加を行います。

■引数
$name : 定義名。

■戻り値
  無し

※ ループの内外に関係なく定義は有効です。
(元仕様に追加)
ループ名設定 $tmpl->loopset( $lpname ) ; ループ開始時のループ名を設定します。

■引数
$lpname : ループ名前。

■戻り値
  無し
ループの繰り返し $tmpl->loopnext( $lpname ) ; ループの繰り返しを設定します。

■引数
$lpname : ループ名前。

■戻り値
  無し
ループの終了 $tmpl->loopend( $lpname ) ; ループの終了を設定します。

■引数
$lpname : ループ名前。

■戻り値
  無し

(元仕様に追加)
コード変換と出力 $result = $tmpl->flush( $outvar ) ; コード変換と出力を行います。

■引数
$outver : 0 なら echo で出力、1 なら文字列で返す。

■戻り値
  テンプレート処理結果

サンプル

ダウンロードした LZH を展開し、その内容全てをWebサーバに置くことで、以下のサンプルを試すことできます。


変更履歴


他のテンプレートエンジン

PHP 開発元ではテンプレートエンジン Smarty を公開しています。
国産テンプレートエンジンは 日本 PHP ユーザー会 のリンクページ を参照してください。


連絡先

ご意見、ご感想はこちらまで。
本業が忙しいので、バグ対応が出来ない場合もあります。ご了承ください。

佐藤 充男

メモ

動作の流れ

$tmpl->assign(); で置換する文字列をセットします。 HTML出力は $tmpl->flush(); 時に行われます。

  1. phase 1 - HTMLソースの解析
    ifdef / ifndef のブロックとネスト、loop のブロックとネストを解析し、配列に保持します。
    この時点でHTML側に問題があれば、エラーを出力し、その後の動作を中止します。

  2. phase 2 - ifdef / ifndef の解析
    ifdef / ifndef の設定を元に出力するHTML部のみ抽出します。

  3. phase 3 - loop の展開、置換処理
    出力するHTMLを先頭から順に処理していき、loop の展開と置換処理を行います。

  4. phase 4 - 漢字コードの変換
    漢字コードの変換指示がある場合、変換します。

内部使用の配列

大量の配列を使うため、巨大なHTMLには向きません。

  1. array $this->arDefStack - ifdef / ifndef ネストスタック
    $this->arDefStack[] = array(
      "def_self" => ifdef / ifndef のブロック名
      "def_type" => 種類 "ifdef" または "ifndef"
      "def_list" => $this->arDefList[] の添字
    );

    HTML 解析時に使用する。

  2. array $this->arPhpLoopStack - PHP側 loop ネストスタック
    $this->arPhpLoopStack[] = array(
      "lop_self" => loop の現在のブロック名
      "lop_cnt" => loop 回数
      "lop_list" => $this->arPhpLoopList[] の添字
    );

    PHP 処理時に使用する。

  3. array $this->arHtmlLoopStack - HTML側 loop ネストスタック
    $this->arHtmlLoopStack[] = array(
      "lop_self" => loop の現在のブロック名
      "lop_list" => $this->arHtmlLoopList[] の添字
    );

    HTML 解析時に使用する。

  4. array $this->arDefList - ifdef / ifndef リスト
    $this->arDefList[] = array(
      "def_root" => ifdef / ifndef の root ブロック名
      "def_parent" => ifdef / ifndef の親ブロック名
      "def_self" => ifdef / ifndef の現在のブロック名
      "def_nest" => ifdef / ifndef のネスト数
      "def_type" => 種類 "ifdef" または "ifndef"
      "result" => 結果判定(true:展開する、false:展開しない)
      "html_start" => HTML 上の loop 開始行(初期値:-1)
      "html_end" => HTML 上の loop 終了行(初期値:-1)
    );

    HTML解析時に作成する配列です。
    <!-- tmpl:ifdef %...% --> の個数だけ作成します。

  5. array $this->arPhpLoopList - loop リスト
    $this->arPhpLoopList[] = array(
      "lop_root" => loop の root ブロック名
      "lop_parent" => loop の親ブロック名
      "lop_pcnt" => loop 親ブロックのカウント数
      "lop_self" => loop の現在のブロック名
      "lop_nest" => loop のネスト数
      "lop_allcnt" => loop 回数
    );

    PHP側で $tmpl->loopset(); 時に作成する配列です。
    $tmpl->loopnext(); 時に loop 回数を+1します。

  6. array $this->arHtmlLoopList - loop リスト
    $this->arHtmlLoopList[] = array(
      "lop_root" => loop の root ブロック名
      "lop_parent" => loop の親ブロック名
      "lop_self" => loop の現在のブロック名
      "lop_nest" => loop のネスト数
      "html_start" => HTML 上の loop 開始行(初期値:-1)
      "html_end" => HTML 上の loop 終了行(初期値:-1)
    );

    HTML解析で <!-- tmpl:loop %...% --> 時に作成する配列です。

  7. array $this->arDefValue - ifdef / ifndef 展開用リスト
    $this->arDefValue["%".定義名."%" ] = true

    PHP側で $tmpl->assign_def(); 時に作成する配列です。

  8. array $this->arChangeValue - 単純置換用リスト
    $this->arChangeList["%".定義名."%"] = 値

    PHP側で $tmpl->assign(); 時に作成する配列です。

  9. array $this->arLoopValue - loop 中の置換用リスト
    $this->arLoopValue[] = array(
      "lop_list" => $this->arPhpLoopList[] の添字
      "lop_cnt" => loop 回数
      "value" => array( ["%".定義名."%"] = 値, ... )
    );

  10. array $this->arHtmlTemp - テンプレートHTMLソースの解析
    $this->arHtmlTemp[] = array(
      "line_cnt" => 行番号
      "source" => HTML1行のソース
      "cnt_convert" => 置換対象数
      "def_root" => ifdef / ifndef の root ブロック名
      "def_parent" => ifdef / ifndef の親ブロック名
      "def_self" => ifdef / ifndef の現在のブロック名
      "def_nest" => ifdef / ifndef のネスト数
      "def_type" => 種類 "ifdef" または "ifndef"
      "def_list" => $this->arDefList[] の添字
      "lop_root" => loop の root ブロック名
      "lop_parent" => loop の親ブロック名
      "lop_self" => loop の現在のブロック名
      "lop_nest" => loop のネスト数
      "lop_list" => $this->arHtmlLoopList[] の添字
      "cut_out" => 0 なら出力対象、1 なら出力しない
    );

    テンプレートHTMLを読み込み時に作成する配列です。
    1行ごとの情報を保持しています。

  11. array $this->arHtmlTemp2 - ifdef / ifndef 処理を終えたHTMLソース
    $this->arHtmlTemp2[] は $this->arHtmlTemp[] からコピーするため同じ構成

  12. array $this->arOneLoopValue - ある1ループで assign() された文字列をセット
    $this->arOneLoopValue["%".定義名."%" ] = 値


$Id: index.htm,v 1.2 2002/10/20 08:27:35 satou Exp $