免責事項
この記事では、アメリカを発見し、有名な文書の範囲をはるかに超える何かを説明するつもりはありません。 むしろ、それはいくつかのプロジェクトでうまく機能するシンプルだが効果的な実用的なソリューションについての物語になります。 また、「ダミーのための石工」の紹介的なタイプを書きません-すでにフリーメーソンのコンポーネントを見た人はほとんどそれを必要としません、そして、残りは本当のクールな唐辛子のように、それをその場で理解するか、マニュアルを吸う以外に何時間も費やすことができません役に立たない:)用語に関しては、元のドキュメントから逸脱しないように努めます。 たとえば、masonテンプレートコンポーネントを呼び出します。真空での球形の膝までの創造性
一連の単純なコンテンツページがあるとします。 ページにアクセスすると、現在のユーザーがそのページにアクセスできるかどうかが確認されます。 そうでない場合は、識別のために送信します。 当然、コンテンツはサイトの標準設計に含まれており、作成者はインクルーダーに共通部分を入れ、関数にコードを入れています。 したがって、例のcompany.html
ファイル:
<%INIT> 私の$ user = GetUserFromCookies(); $ m&> redirect( '/ login.html')$ user && $ user-> haveAccess($ r-> uri); </%INIT> <&/Header.inc、title => "サイトについて"&> <h1>サイトについて</ h1> <p> Runetで最も人気のあるサイトです</ p> <&/Footer.inc&>
おなじみのアプローチ? 原則として、上記の例に問題はありません。 すべてのコンポーネントにほぼ同じ包含物をドラッグしてデザインを表示するのが面倒な場合を除き、承認チェックではページからページにコピーする必要があります。 何ができますか? 余分な部分を削除してください:)
継承の理論的基礎
機能#1:親コンポーネント
各石工コンポーネントは、他のコンポーネントから継承できます。 このようなコンポーネントは、<%FLAGS>
セクションと
inherit
という名前のフラグを使用して強制的に強制(またはリセット)するか、自動的に計算できます。 2番目のケースでは、
autohandler
という名前のファイルは、コンポーネントが配置されているフォルダーで検索され、存在しない場合は、上記のフォルダーを使用して、メイソンがルートと見なしているフォルダーで検索が続行されます。 祖先が見つかった場合、メイソンは彼の親も見つけようとします。
継承チェーンが構築されるとすぐに、実行は「最も親」のコンポーネントに転送されます。このコンポーネントは、マジックコール
$m->call_next
を使用してアクションを実行し、その子孫に制御を転送できます。 子が処理された後、親コンポーネントの実行が続行されます。
継承チェーンを構築する上記の手順は、ページにアクセスするときにのみ機能します。 他のコンポーネントが含まれている場合、メカニズムはオンになりません。
機能#2:属性とメソッド
属性を使用すると、すべてが単純になります。コンポーネントの<%ATTR>
セクションで、名前付きパラメーターの任意のセットを開始できます。 現在のコンポーネントで直接宣言されていない親コンポーネントの属性がある場合、それらは継承されます。
メソッドの状況はほぼ同じです。各メソッドは
<%METHOD>
セクションでラップされ、「コンポーネント内のコンポーネント」を表します。これは、インクルーダーが接続されているのとほぼ同じ方法で呼び出すことができます。 通常のコンポーネントと同様に、メソッドはテンプレートとして(データを出力するために)、関数として(計算結果を取得するために)使用できます。
継承の実用的な基本
それでは、これらの2つの機能を使用してページを改良してみましょう。 キャップとテールは論理的に/autohandler
されます。 唯一の「しかし」-ページのタイトルはヘッダー(
title
タグ内)に表示されます。
autohandler
からそれらの一番下に到達できれば、ページの属性に安全に入れることができます(そして、先を見て、はい、そう言うことができます)。 これで、権限チェック付きの伝播セクション
<%INIT>
のみができました。 すべてのページで認証が必要でない場合はどうなりますか? この問題を解決するための素晴らしい完全にOOPの方法は、ページ自体に検証の管理を任せることです。
authorize
属性を取得し、true値に設定されているすべてのページで承認を確認します(明確にするため、
/profile/login.html
を除くすべてのページを確認する必要があると想定しています)。 私たちの考えの結果:
/オートハンドラー:
<%INIT> 私の$ component_requested = $ m-> request_comp; #company.htmlコンポーネント if($ component_requested-> attr( 'authorize')) { 私の$ user = GetUserFromCookies(); $ m&> redirect( '/ login.html')$ user && $ user-> haveAccess($ r-> uri); } </%INIT> <%ATTR> 承認=> 1 </%ATTR> <&/Header.inc、title => $ component_requested-> attr( 'title')&> <h1> <%$ component_requested-> attr( 'title')%> </ h1> %$ m-> call_next; <&/Footer.inc&>
/company.html:
<%ATTR> title =>「サイトについて」 </%ATTR> <p> Runetで最も人気のあるサイトです</ p>
/profile/login.html:
<%ATTR> title => "サイトにログイン" 許可=> 0 </%ATTR> <p>ログインフォームがある可能性があります</ p>
簡単な例では明らかでないいくつかの簡単な結論:
- 属性には、現在のメニュー項目に関する情報を保存して強調表示すると便利です
- 上記のコードでは、
Header.inc
はページタイトルを引数として受け入れますが、原則として、まったく同じコードを使用してヘッダー自体からページタイトルを取得することはありません - ページをフォルダに正しく編成すると、追加レベルの
autohandler
をページに作成できます。 これにより、属性をより柔軟に管理できます(たとえば、authorize
属性を/free/autohandler
移動するauthorize
で、/free/
フォルダーのコンテンツ全体へのアクセスを開くことができ/free/autohandler
)。 ページのコンテンツを変更することもできます(たとえば、ページの本文の下にEULAを含むトップレベルの見出しまたはブロックを追加します)。
タスクを複雑にします
ページごとに異なるブロックがあるとします。 たとえば、サイト全体の右側の列にセクションのニュースが表示されますが、個人データの機密を保持する義務はユーザープロファイルのページに表示されます。 明らかに、継承もここで役立ちますが、今回はメソッドを使用して問題を解決する方がはるかに便利です。/autohandler
ニュースを表示するためのデフォルトのメソッド
/autohandler
記述し(実装を自分で考えてください)、
/profile/autohandler
そのテキスト
/profile/autohandler
再定義します:
<%メソッドrightmenu> <p>誰にもデータを提供しません!</ p> </%メソッド>
ここで、一部の(すべてではない)ページに、動的に収集されるサブメニューブロックがあり、サイトのさまざまなセクションでサブメニューが異なって形成されているとします。 たとえば、コンテンツが含まれるページでは、CMSデータベースから取得できます。また、「マイプロファイル」セクションでは、手で作成した静的メニューを使用できます。 当然、メニューに関するデータとそのプレゼンテーションを混在させたくないため、
SubMenu.inc
コンポーネントは実際のレンダリングに関与し、メニュー自体を記述する構造がパラメーターとして渡されます。 質問:継承の可能性を使用するために構造を配置する場所は? 回答:コンポーネントメソッドで。 以下は、対応するファイルに追加することが提案されているスニペットです。
/オートハンドラー:
%my $ component_requested = $ m-> request_comp; %if($ component_requested-> method_exists( 'submenu')){ <&/SubMenu.inc、MenuItems => $ component_requested-> call_method( 'submenu')&> %}
/プロファイル/オートハンドラー:
<%METHODサブメニュー> <%INIT> return [ '/profile/password.html' => 'パスワードの変更'、 '/profile/update.html' => '個人データの更新'、 '/profile/logout.html' => '終了' ]; </%INIT> </%メソッド>
あとがきの代わりに
上記の手法は、いくつかの単純だが非常に有用なタスクを解決します。autohandler
一般的なコードフラグメントを
autohandler
すると、テンプレート内の情報のないコードの量が大幅に削減されます。 属性を使用すると、コードの記述から構成に移行できます。 メソッドは、ページ上の視覚的なブロックを記述するのに理想的であり、コンポーネントにコードを柔軟にリンクする機能を提供します。
この記事にはアイデアのみが示されており、簡単に開発できます。 たとえば、ページを表示する代わりにCSVファイルをレンダリングできるコンポーネントを作成する必要がある場合、どのように問題を解決しますか? 素晴らしいですが、ユーザーの希望に応じてページがサイトの標準デザインでCSVまたはHTMLを生成する場合はどうでしょうか? スキンと異なるページの異なるスキンを接続する機能を備えたアプリケーションを作成するのは弱いですか? ちなみに、タスクは一見したほど簡単ではありません。 ただし、試してください:)