2

Mason2を使用して Web サイトを構築します。各ページは 3 つのフィルター (コンテンツによって呼び出されるメソッド) を呼び出す必要があります。

<% $.filter1(args...) {{ %>
<% $.filter2(args...) {{ %>
<% $.filter3(args...) {{ %>

これらのフィルター (メソッド) の 3 つの異なる実装があります。これら 3 つのフィルタのデフォルト セットは、最上位/Base.mcコンポーネントで定義されています。

ここで、サイトの別の部分 (別のルート) について、

/a/all/paths>/...>
/b/.....

上記のフィルター/メソッドのデフォルト セットを使用する必要がありますが、別のルートでは、

/c/...
/d/...
/e/...

filter1filter2filter3およびの別のセットを使用する必要があります

/x/....
/y/...

3 番目のセットを使用します。

メソッドは低レベルのコンポーネントで簡単に再定義できますが、(この質問) のようにそれを行うことは、DRY 原則を尊重しません。

/c/Base.mc
/d/Base.mc
/e/Base.mc

同じことを繰り返す必要がある 3

<%override filter1>
...
<%override filter2>
...
<%override filter3>

質問は:

  • メソッドの 3 つの異なる実装を 1 回だけ記述する方法と、それらを一度に使用する方法

/set2.mi、のようなコンポーネントを作成しようとし/set3.miましたが、これらのフィルターメソッドをオーバーライドしようとし、必要に応じてそれを呼び出しまし/{c,d,e}/Base.mc

<& /set2.mi &>

しかし、これは機能しません。

3 つの異なるメソッドの実装を記述し、必要な deeprr で一度に呼び出す方法はBase.mc? 出来ますか?

標準の perl では、おそらくrolesを使用するため、必要なパッケージでは次のようなものを使用します。

with 'Set1';
with 'Set2';

パッケージSet1Set2必要なメソッドの実装が含まれる場所、または動的読み込みの場合はrequire .... Mason2 で可能なようなことはありますか、それとも繰り返す必要があり%ovverrideますか?

これが理にかなっていることを願っています...そうでない場合は、コメントを追加してください。質問を更新してみます。

編集

たとえば、コードを短縮するために、3 つではなく 1 つのフィルターのみを使用します。

/Base.mc

<%augment wrap><% inner() %></%augment>

% #this is the "default" MyHead filter
<%filter MyHead($arg)>
    <!-- in the real code it is more complicated, but for an illustration it is enough -->
    <h1 class="<% $arg %>"><% $yield->() %></h1>
</%filter>

/a/index.mcとして使用する場合

% $.MyHead('big') {{
some head text
% }}

次のように出力されます。

<h1 class="big">some head text</h1>

今、別のものを持っていMyHeadます。

<%filter MyHead($arg)>
    <!-- in the real code it is more complicated - basically want output different thing -->
    <h2 id="<% $arg %>"><% $yield->() %></h2>
</%filter>

上記のコードを追加する/b/Base.mcと動作MyHeadし、/b/index.mc

% $.MyHead('modal') {{
some other text
% }}

再定義されたフィルターを呼び出し、必要なものを出力します

<h2 id="modal">some other text</h2>

問題は、

  • などのように、他の N 個のBase.mcコンポーネントで上記のフィルター コードを繰り返したくありません。/c/Base.mc/d/Base.mc
  • フィルタを一度書き、それを他の多くのコンポーネントで「使用」して、デフォルトのものを「再定義」する方法。
4

1 に答える 1

0

次のように、1 つの解決策として、継承チェーンをいじることができます (あまり良い方法ではなく、"スパゲティ" のようなコードが生成されます)。

  1. から「デフォルト」フィルターを削除して/Base.mc<%augment wrap
  2. たとえば、次のように呼ばれる1つのコンポーネントを作成BaseSetDefault.mcし、それに「デフォルト」フィルターを入力し、継承チェーンを最上位に明示的に設定します/Base.mc
<%augment wrap><% inner() %></%augment>

<%filter MyHead($arg)><h1 class="<% $arg %>"><% $yield->() %></h1></%filter>

<%flags>
    extends => '/Base.mc'
</%flags>
  1. 同様に、as/BaseSet2.mcと呼ばれる別のコンポーネントを作成し、ここに「Set2」フィルターを次のように配置します。
<%augment wrap><% inner() %></%augment>

<%filter MyHead($arg)><h2 id="<% $arg %>"><% $yield->() %></h2></%filter>

<%flags>
    extends => '/Base.mc'
</%flags>
  1. ここで、/a/Base.mcおよび/b/Base.mc- どこでも、「デフォルト」セットが必要な場合は、チェーンを変更します
<%flags>
    extends => '/BaseSetDefault.mc'
</%flags>
  1. and では/c/Base.mc/d/Base.mc「Set2」フィルターが必要なすべての場所で、
<%flags>
    extends => '/BaseSet2.mc'
</%flags>

これから、の継承チェーンは次の/c/index.mcようになります。

/c/index.mc -> /c/Base.mc -> /BaseSet2.mc -> /Base.mc

実行は次のように行われます

/Base.mc -augment-> /BaseSet2.mc -augment-> /c/Base.mc -main-> /c/index.mc
                    ^^^^^^^^^^^^ - defines the Set2 filters

および/a/index.mc継承チェーンの場合

/a/index.mc -> /a/Base.mc -> /BaseSetDefault.mc -> /Base.mc

実行

/Base.mc -augment-> /BaseSetDefault.mc -augment-> /a/Base.mc -main-> /a/index.mc
                    ^^^^^^^^^^^^^^^^^^ - defines the "Default" filters

それはあまり良い解決策ではありませんが、うまくいきます...

于 2014-09-21T12:11:56.560 に答える