Building a website using Mason2. Each page should call 3 filters (methods, called by content):
<% $.filter1(args...) {{ %>
<% $.filter2(args...) {{ %>
<% $.filter3(args...) {{ %>
I have 3 different implementation of those filters (methods). The default set of those 3 filters, are defined in the top level /Base.mc component.
Now, for a different parts of the site - (different routes), say for the
/a/all/paths>/...>
/b/.....
need use the above default set of filters/methods, but for another routes,
/c/...
/d/...
/e/...
need use another set of filter1, filter2, filter3 and for the
/x/....
/y/...
want use the third set.
The methods can be easily redefined, in lower level components, but doing it as in (this question), isn't honors the DRY principe, e.g. in each
/c/Base.mc
/d/Base.mc
/e/Base.mc
Need repeat the same 3
<%override filter1>
...
<%override filter2>
...
<%override filter3>
The question is:
- how to write only once the 3 different implementations of the methods, and how to use them at once?
I tried make an compomponent, like: /set2.mi, /set3.mi, where I tried override those filter-methods, and called it in the needed /{c,d,e}/Base.mc as
<& /set2.mi &>
But this doesn't works.
How to write the 3 different methods implementatinons and call them at once in the needed deeprr Base.mc? Is it possible?
In standard perl i would probably use roles, so in the needed packages I would use something like:
with 'Set1';
with 'Set2';
Where the packages Set1 and Set2 would contain the implementations of the needed methods, or for dynamic loading would use the require ... . Is something like possible in the Mason2, or i must repeat the %ovverride?
Hope this make sense... if not, please add an comment and i will try update the question.
EDIT
Example, for shorting the code, using only one filter not 3.
The /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>
When in the /a/index.mc using it as
% $.MyHead('big') {{
some head text
% }}
will output like:
<h1 class="big">some head text</h1>
now, have an another MyHead.
<%filter MyHead($arg)>
<!-- in the real code it is more complicated - basically want output different thing -->
<h2 id="<% $arg %>"><% $yield->() %></h2>
</%filter>
If I add the above code to my /b/Base.mc it will work, and calling the MyHead filter in the /b/index.mc
% $.MyHead('modal') {{
some other text
% }}
will call the redefined filter, and will output what i want
<h2 id="modal">some other text</h2>
The problem is,
- I don't want repeat the above filter code, in N other
Base.mccomponents, like in/c/Base.mcand/d/Base.mcand so on. - How to achieve, to write the filter once and "use" it in many other components for "redefine" the default one.