ファイル内のネストされたタグの解析
質問
私は疑問に思っています-何かを解析する最も効果的な方法は何ですか:
{{HEADER}}
Hello my name is {{NAME}}
{{#CONTENT}}
This is the content ...
{{#PERSONS}}
<p>My name is {{NAME}}.</p>
{{/PERSONS}}
{{/CONTENT}}
{{FOOTER}}
もちろん、これは最終的にはテンプレートシステムになることを意図しているので、私の計画は、「オーバーレイ」するハッシュマップを作成することです。このようなものとしてのテンプレート
$hash = array(
'HEADER' => 'This is a header',
'NAME' => 'David',
'CONTENT' => array('PERSONS' => array(array('NAME' => 'Heino'), array('NAME' => 'Sebastian')),
'FOOTER' => 'This is the footer'
);
&quot;セクション&quot; (#で始まるタグ)、複数回繰り返すことができ、これが私をつまずかせるものだと思います...
また、任意のセクションには、他のセクションと通常のタグをいくつでも含めることができます...
だから..どうしましたか?
解決
これの期待される出力は次のようなものです:
これはヘッダーです
こんにちは、デビッドです
This is the content ...
My name is Heino.
My name is Sebastian.
これはフッターです
ハッシュマップのネストされた配列とテンプレートの繰り返し可能なセクションの関係をどのように管理していますか?想定されるテンプレートの実際の動作は何ですか?セクション以外の要素に配列が提供されている場合、それはどうなりますか?セクション要素に単一の値が指定されている場合、単一の要素のみを持つ配列と同じように扱われますか?
とにかく、テンプレートのパーサーに関して(データのマッピングで何をするかに関係なく)...私がやることは、トークンのタイプごとにクラスを作成することです。 -トークンのコンテンツ。これらは、オーバーライド可能なParse、Render、およびMapメソッドを持つ共通のトークンベースクラスから継承します。
状態図を作成し、各状態の入口点と出口点を把握し、トークン間の呼び出し構造にエンコードします。最後に、テンプレートを記述するトークンの列挙可能なコレクションを生成します。
これを抽象形式で取得したら、トークンでMapを呼び出すコレクションを繰り返して、ハッシュマップからトークンにデータを割り当て、Renderを呼び出してテンプレートを最終フォームにレンダリングします。
役立つこと。
他のヒント
最も効率的な方法は、テンプレートをPHPコードにコンパイルすることです。そして、コンパイルされたバージョンを含めるだけです。
Smarty Template Engine は同様のことを行います。また、賢いソースを見て、タグの解析方法を確認することもできます。
私はよりスマートで難しくないのでサードパーティのパーサーを使用しますが、これを演習として実行している場合、または独自のテンプレートエンジンを構築したい場合(PHPでは)、デザインパターン、具体的にはコンポジットデザインパターンの確認から始めます。
複合パターンは、XML解析を含むこのようなもののためにJavaフレームワークで多く使用されます。
.phpの別のファイル内で次のようなものを使用します。
<?php echo $HEADER ?>
Hello my name is <?php echo $NAME?>
<div id="CONTENT">
This is the content ...
<?php foreach ($PERSONS as $PERSON) : ?>
<p>My name is <?php echo $PERSON['NAME']?>.</p>
<?php endforeach ?>
</div>
<?php echo $FOOTER ?>
さらに、上記のファイルを、参照される変数が入力されるファイル内に含めます。
信じられないかもしれませんが、PHPは既に、実装を主張しているテンプレートシステムが提供するすべての機能を提供しています。 PHPの上に別の抽象化レイヤー(および複雑さ)を追加する必要はありません。
このために PHPのDOM を使用します。私のテンプレート言語は、IDとクラス属性を備えた単純なHTMLです。ただし、計画に固執する場合は、構文に一致するパターンで preg_replace_callback を使用します。ハッシュ内の適切な置換を見つけるコールバック関数。コンテナ要素で再帰的に呼び出します。