実際のプロジェクトでxsltテンプレートを使用する

この記事では、テンプレートエンジンの比較テストは見つかりません。 しかし、実際のプロジェクトでテンプレートエンジンとしてxsltを使用することに関する情報があります。 名前付きテンプレートの可能性、テンプレート機能の使用、リファレンスブックが考慮されます。

1.プロジェクトの構造


通常、サイトページはいくつかの一般的なブロック(メニュー、フッターなど)とコンテンツ部分で構成され、一般的にはメインブロックと呼ばれます。 これらのブロックはすべて、インデックスブロック内に配置されます。インデックステンプレートは、どのブロックを表示するかを認識します。メニューは上部に、メインブロックは中央に、フッターは下部に配置する必要があります。

次の構造を取得します
/themes -     /themes/index/main.xsl -   /themes/models/user.xsl -  ,      /themes/inc/functions.xsl -  - /themes/blocks/footer.xsl -   /themes/blocks/menu.xsl -   /themes/cabinet/main.xsl -        


ユーザーのアカウントのメインページのコントローラーは次のように機能します。
  1. メインブロックのデータを受信し、/ themes / cabinet / main.xslで処理し、結果(準備ができているhtml)を最終的なxmlに入れます
  2. 同様に他のブロック(メニュー、フッター)のデータを処理し、結果をxmlに入れます
  3. すべてのブロックのデータを含む最終xmlは、インデックステンプレート/themes/index/main.xslを使用して処理され、結果がhtmlの形式でユーザーに返されます。


インデックステンプレート/themes/index/main.xslは次のようになります。
 <xsl:template match="page"> <head> <title><xsl:value-of select="title" /></title> </head> <body> <div class="page-container"> <xsl:value-of select="blocks/menu_top/html" disable-output-escaping="yes"/> <div class="main"> <xsl:value-of select="blocks/content/html" disable-output-escaping="yes"/> </div> <xsl:value-of select="blocks/footer/html" disable-output-escaping="yes"/> </div> </body> </xsl:template> 


2.名前付きテンプレート


xsltテンプレートは、データをxmlドキュメントとして受け入れます。 これは、ノード全体で操作できるため便利です。 たとえば、ユーザー名を表示するために、このようなテンプレートがあるかもしれません
 <xsl:template name="inc_show_user"> <xsl:param name="user"/> <img src="/img/{$user/userpic}.png"/> <xsl:value-of select="concat($user/first_name, ' ', $user/last_name)"/> </xsl:template> 
これは/themes/models/user.xslファイルにあります。

このテンプレートを使用して、現在のユーザーを表示できます。
 <xsl:call-template name="inc_show_user"> <xsl:with-param name="user" select="/*/cur_user"/> </xsl:call-template> 

ユーザーのリストを表示するには
 <xsl:for-each select="users/item"> <xsl:call-template name="inc_show_user"> <xsl:with-param name="user" select="."/> </xsl:call-template> </xsl:for-each> 


エンティティのこの表示の統一により、エンティティの表示をすばやく変更できます。 もちろん、すべてのユーザーが写真を持っているわけではありません。つまり、全員がそれを表示する必要はありません。
 <xsl:template name="inc_show_user"> <xsl:param name="user"/> <xsl:choose> <xsl:when test="$user/userpic>0"> <img src="/img/{$user/userpic}.png"/> </xsl:when> <xsl:otherwise> <img src="/img/default.png"/> </xsl:otherwise> </xsl:choose> <xsl:value-of select="concat($user/first_name, ' ', $user/last_name)"/> </xsl:template> 


3.テンプレートのインポート


ブロックテンプレートの「ユーザー」エンティティの表示にアクセスするには、ファイル/themes/models/user.xslを含める必要があります。
/themes/cabinet/main.xslテンプレートの場合、接続は次のようになります
 <xsl:import href="../models/user.xsl"/> 
(xsl:インポートは、xsl:スタイルシートの直後に記述する必要があります)

4.ビュー内の1行のphpコードではない


MVCパターンには、モデル、ロジック、およびプレゼンテーションの分離が含まれます。 アプリケーションロジックは、モデルに必要なデータを要求し、ビューに渡します。 ビューは、ユーザーに表示するために必要な量のデータを受け取る必要があります。 つまり ビューでは、それらを出力するだけで、他の方法でデータを変換しないでください。 idでユーザー名を受け取ったり、現在の時間を受け取ったりしないでください。 これらのデータはすべて、すでにプレゼンテーションに利用できるはずです。 データが欠落している場合、コントローラーはそれを提供する必要があります。

Xsltを使用すると、比較、カウント、ソート、数値のフォーマット、丸め、算術演算、連結などの単純なデータ操作を実行できます。これは前の段落と矛盾しているように見えます。 ただし、これらすべての操作の結果として、新しいデータは受信されず、利用可能なデータのみが変換されることに注意してください。

必要な結果を得るために必要なツールがすべて揃っているとは限りません。 たとえば、数値の出力を終了します。 多くの人が同様の機能を持っていると思います。
 function str_plural_form($n, $form1='', $form2='', $form5=''){ $lastN=$num%10; $lastT=$num%100; if($lastT>=10 && $lastT<=20){ return $form5; } switch ($lastN){ case 1: return $form1; case 2: case 3: case 4: return $form2; default: return $form5; } } 

さらに、xsltを使用すると、この関数をテンプレートから直接呼び出すことができます
 <xsl:value-of select="php:function('str_plural_form', 1*$cnt_users, '', '', '')"/> 

しかし、これはセクションのタイトルと矛盾するだけでなく、一種のアタビズムでもあります。 xsltテンプレート内でphp関数呼び出しを避けることをお勧めします。
どうする? 次の2つの方法があります。
  1. コントローラがstr_plural_formを呼び出して必要なデータを返すようにします
  2. /themes/inc/functions.xslに配置する名前付き関数テンプレートを作成します

 <xsl:template name="f_plural_form"> <xsl:param name="num"></xsl:param> <xsl:param name="format">### ###</xsl:param> <xsl:param name="is_show_num">1</xsl:param> <xsl:param name="space"/> <xsl:param name="str1"></xsl:param> <xsl:param name="str2"></xsl:param> <xsl:param name="str5"></xsl:param> <xsl:if test="$is_show_num=1"> <xsl:value-of select="format-number($num, $format)"/> <xsl:choose> <xsl:when test="$space!=''"> <xsl:value-of select="$space" disable-output-escaping="yes"/> </xsl:when> <xsl:otherwise> <xsl:text> </xsl:text> </xsl:otherwise> </xsl:choose> </xsl:if> <xsl:variable name="lastN" select="$num mod 10"/> <xsl:variable name="lastT" select="$num mod 100"/> <xsl:choose> <xsl:when test="$lastT>=10 and 20>=$lastT"> <xsl:value-of select="$str5" disable-output-escaping="yes"/> </xsl:when> <xsl:when test="$lastN=1"> <xsl:value-of select="$str1" disable-output-escaping="yes"/> </xsl:when> <xsl:when test="$lastN=2 or $lastN=3 or $lastN=4"> <xsl:value-of select="$str2" disable-output-escaping="yes"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="$str5" disable-output-escaping="yes"/> </xsl:otherwise> </xsl:choose> </xsl:template> 


関数呼び出しは次のようになります
 <xsl:call-template name="f_plural_form"> <xsl:with-param name="is_show_num">1</xsl:with-param> <xsl:with-param name="num" select="$cnt_users"/> <xsl:with-param name="str1"></xsl:with-param> <xsl:with-param name="str2"></xsl:with-param> <xsl:with-param name="str5"></xsl:with-param> </xsl:call-template> 


5.参照


ユーザー情報の結論に戻りましょう。 たとえば、フォーラムページでは、表示する必要があります


問題のvlobを解決できます。 各リストを受信したら、ユーザーをLEFT JOINし、ユーザーに関する情報を表示するために必要なデータを取得します。 しかし、そのような決定には否定的な側面もあります。 1つ目はデータの冗長性の可能性(リストからのユーザーを繰り返すことができる)、2つ目はSQLサーバーの追加の負荷です。

問題の別の解決策。 すべてのリストを取得します。 次に、これらのリストからuser_idのセットを取得します。 このセットでは、usersテーブルに1つのリクエストを作成します。 / ref_usersなどの既知のアドレスにxmlの結果を追加します。
その結果、投稿、active_users、online_users、ref_usersノードを含むxmlドキュメントを取得する必要があります。

ユーザー情報を表示するために、このような名前付きテンプレートを作成します
 <xsl:template name="inc_show_user_by_id"> <xsl:param name="user_id"/> <!--       id --> <xsl:variable name="cur_user" select="/*/ref_users/item[user_id=$user_id]"/> <xsl:call-template name="inc_show_user"> <xsl:with-param name="user" select="$cur_user"/> </xsl:call-template> </xsl:template> 
/themes/models/user.xslに保存します。 これは、ユーザーをIDで表示するためのテンプレートです。

このようなユーザー情報を含む投稿のリストを表示できます
 <xsl:for-each select="posts/item"> <xsl:call-template name="inc_show_user_by_id"> <!--    user_id   --> <xsl:with-param name="user_id" select="user_id"/> </xsl:call-template> <!--     --> <!-- ... --> </xsl:for-each> 


おわりに


記事は膨大であることが判明したため、ajaxのテンプレートを整理するという質問、「抽象テンプレート」、いくつかの言語のサポートは未検討のままでした。 速度とキャッシュの問題も同様です。

Source: https://habr.com/ru/post/J151241/


All Articles