使用 Mason2 构建网站。每个页面应调用 3 个过滤器(方法,按内容调用(:
<% $.filter1(args...) {{ %>
<% $.filter2(args...) {{ %>
<% $.filter3(args...) {{ %>
我有 3 种不同的过滤器(方法(实现。这 3 个筛选器的默认集在顶级组件/Base.mc
定义。
现在,对于网站的不同部分 - (不同的路线(,例如
/a/all/paths>/...>
/b/.....
需要使用上述默认的过滤器/方法集,但对于其他路由,
/c/...
/d/...
/e/...
需要使用另一组filter1
,filter2
,filter3
和
/x/....
/y/...
想用第三套。
这些方法可以很容易地在较低级别的组件中重新定义,但是像(这个问题(一样做,并不是尊重 DRY 原则,例如在每个
/c/Base.mc
/d/Base.mc
/e/Base.mc
需要重复相同的 3
<%override filter1>
...
<%override filter2>
...
<%override filter3>
问题是:
- 如何只编写一次 3 种不同的方法实现,以及如何一次使用它们?
我尝试制作一个组合,例如:/set2.mi
,/set3.mi
,我尝试覆盖这些过滤器方法,并在所需的/{c,d,e}/Base.mc
中将其称为
<& /set2.mi &>
但这行不通。
如何编写 3 种不同的方法实现并在所需的深度Base.mc
中立即调用它们?可能吗?
标准perl中,我可能会使用角色,因此在所需的包中,我会使用类似以下内容的内容:
with 'Set1';
with 'Set2';
其中包Set1
和Set2
将包含所需方法的实现,或者对于动态加载将使用require ...
。在 Mason2 中是否有类似的东西,或者我必须重复%ovverride
?
希望这是有道理的...如果没有,请添加评论,我将尝试更新问题。
编辑
例如,对于短代码,仅使用一个筛选器而不是 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
过滤器
% $.MyHead('modal') {{
some other text
% }}
将调用重新定义的过滤器,并将输出我想要的
<h2 id="modal">some other text</h2>
问题是,
- 我不想在其他 N 个
Base.mc
组件中重复上述过滤器代码,例如在/c/Base.mc
和/d/Base.mc
等。 - 如何实现,编写过滤器一次并在许多其他组件中"使用"它以"重新定义"默认过滤器。
一种解决方案可能是(不是一个很好的解决方案,并产生类似"意大利面条"的代码(玩继承链,如下所示:
- 从
/Base.mc
中删除"默认"过滤器,因此它将仅包含<%augment wrap
- 创建一个组件,例如:
BaseSetDefault.mc
并输入其中,您的"默认"过滤器,并将继承链显式设置为顶级/Base.mc
<%augment wrap><% inner() %></%augment>
<%filter MyHead($arg)><h1 class="<% $arg %>"><% $yield->() %></h1></%filter>
<%flags>
extends => '/Base.mc'
</%flags>
- 同样,创建另一个称为
/BaseSet2.mc
的组件,并在此处放置"Set2"过滤器,例如:
<%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
这不是很好的解决方案,但有效...