実際のプロジェクトで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のテンプレートを整理するという質問、「抽象テンプレート」、いくつかの言語のサポートは未検討のままでした。 速度とキャッシュの問題も同様です。



All Articles