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 -
ユーザーのアカウントのメインページのコントローラーは次のように機能します。
- メインブロックのデータを受信し、/ themes / cabinet / main.xslで処理し、結果(準備ができているhtml)を最終的なxmlに入れます
- 同様に他のブロック(メニュー、フッター)のデータを処理し、結果をxmlに入れます
- すべてのブロックのデータを含む最終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つの方法があります。
- コントローラがstr_plural_formを呼び出して必要なデータを返すようにします
- /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のテンプレートを整理するという質問、「抽象テンプレート」、いくつかの言語のサポートは未検討のままでした。 速度とキャッシュの問題も同様です。