2014-09-21 80 views
2

使用Mason2構建網站。每頁應調用3個過濾器(方法,內容稱爲):Mason2中的多種方法覆蓋

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

我有3種不同的實現這些過濾器(方法)。這3個過濾器的默認設置在頂層/Base.mc組件中定義。

現在,該網站的不同部分 - (不同的路線),說的

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

需要在使用的過濾器/方法的上述默認設置,但對於另一種途徑,

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

需要使用另一套filter1filter2filter3併爲

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

要使用第三套。

該方法可以容易地在較低級別的組件中重新定義,但是如(this question)那樣進行,不符合DRY原則,例如,在每個

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

需要重複同樣的3

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

的問題是:

  • 怎麼只寫一次的方法,3級不同的實現,以及如何使用他們一次?

我試圖做一個compomponent,如:/set2.mi/set3.mi,在那裏我試圖覆蓋這些過濾器的方法,並把它稱爲在需要/{c,d,e}/Base.mc作爲

<& /set2.mi &> 

但這並不作品。

如何編寫3種不同的方法執行方法,並在需要的深度處一次調用它們?可能嗎?

在標準的Perl我可能會使用角色,所以在需要的軟件包我會使用類似:

with 'Set1'; 
with 'Set2'; 

凡包Set1Set2將包含的必要方法的實現,或動態加載將使用require ...。在Mason2中是可能的,或者我必須重複%ovverride

希望這是有道理的......如果沒有,請添加評論,我會嘗試更新問題。

EDIT

實施例,用於短路該代碼,僅使用一個過濾器不3.

/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它會工作,並呼籲在/b/index.mc

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

MyHead過濾器將調用重新定義過濾器,並且將我想要什麼

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

問題是,

  • 我不想重複上面的過濾器代碼,在其他Base.mc組件中,如在/c/Base.mc/d/Base.mc等等。
  • 如何實現一次寫入過濾器並在許多其他組件中「使用」它以「重新定義」默認的過濾器。
+0

你說:「我有3個不同的實現這些過濾器(方法)。這3個過濾器的默認設置是在頂層/Base.mc組件中定義的。「 - 您能舉出一個過濾器的例子,以及它如何根據您所在網站的部分而有所不同? – 2014-09-21 10:08:28

+0

@ialarmedalien增加了一個例子,希望有道理.. – cajwine 2014-09-21 11:45:12

回答

0

一種解決方案可能是(不是一個很好的一個,併產生一個「spaghetty」比如代碼),與繼承鏈中的發揮,爲下一個:

  1. /Base.mc刪除你的「默認」的過濾器,所以它會只包含<%augment wrap
  2. 創建一個名爲例如一個組件:BaseSetDefault.mc,進入它,你的「默認」過濾器和明確的繼承鏈設置爲最高級別/Base.mc
<%augment wrap><% inner() %></%augment> 

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

<%flags> 
    extends => '/Base.mc' 
</%flags> 
  • 同樣,創建另一個組件再說稱爲/BaseSet2.mc,把這裏的 「集2」 過濾器,如:
  • <%augment wrap><% inner() %></%augment> 
    
    <%filter MyHead($arg)><h2 id="<% $arg %>"><% $yield->() %></h2></%filter> 
    
    <%flags> 
        extends => '/Base.mc' 
    </%flags> 
    
  • 現在,在/a/Base.mc/b/Base.mc - 無處不在,您要「默認」設置,更改鏈
  • <%flags> 
        extends => '/BaseSetDefault.mc' 
    </%flags> 
    
  • ,並在/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 
    

    這是不是很好的解決方案,但工程...