Mason2 how to wrap (augment) content of internal component

View: New views
4 Messages — Rating Filter:   Alert me  

Mason2 how to wrap (augment) content of internal component

by Roman Daniel :: Rate this Message:

| View Threaded | Show Only this Message

Is it possible to achieve the effect of wrapping child component content by its parent with internal components?
For request component I could use


form/Base.mc:
--------------------
<%class>
has form => (is =>'ro', required =>1);
</%class>

<%method wrap>
<form .....>
% inner();
</form>
</%method>


form/login.mc:
---------------------
<% $.field(...) %>
<% $.field(...) %>


But when called from other component, method main is called directly and wrap is skipped. 

<& /form/login.mc, form=>$login_form &>


I appreciate any tip

Roman Daniel

------------------------------------------------------------------------------
Ridiculously easy VDI. With Citrix VDI-in-a-Box, you don't need a complex
infrastructure or vast IT resources to deliver seamless, secure access to
virtual desktops. With this all-in-one solution, easily deploy virtual
desktops for less than the cost of PCs and save 60% on VDI infrastructure
costs. Try it free! http://p.sf.net/sfu/Citrix-VDIinabox
_______________________________________________
Mason-users mailing list
Mason-users@...
https://lists.sourceforge.net/lists/listinfo/mason-users

Re: Mason2 how to wrap (augment) content of internal component

by Jonathan Swartz :: Rate this Message:

| View Threaded | Show Only this Message

Definitely possible, but I am working on the best syntax... :)

Jon

On Jan 6, 2012, at 1:55 AM, Roman Daniel wrote:

Is it possible to achieve the effect of wrapping child component content by its parent with internal components?
For request component I could use


form/Base.mc:
--------------------
<%class>
has form => (is =>'ro', required =>1);
</%class>

<%method wrap>
<form .....>
% inner();
</form>
</%method>


form/login.mc:
---------------------
<% $.field(...) %>
<% $.field(...) %>


But when called from other component, method main is called directly and wrap is skipped. 

<& /form/login.mc, form=>$login_form &>


I appreciate any tip

Roman Daniel
------------------------------------------------------------------------------
Ridiculously easy VDI. With Citrix VDI-in-a-Box, you don't need a complex
infrastructure or vast IT resources to deliver seamless, secure access to
virtual desktops. With this all-in-one solution, easily deploy virtual
desktops for less than the cost of PCs and save 60% on VDI infrastructure
costs. Try it free! http://p.sf.net/sfu/Citrix-VDIinabox_______________________________________________
Mason-users mailing list
Mason-users@...
https://lists.sourceforge.net/lists/listinfo/mason-users


------------------------------------------------------------------------------
Ridiculously easy VDI. With Citrix VDI-in-a-Box, you don't need a complex
infrastructure or vast IT resources to deliver seamless, secure access to
virtual desktops. With this all-in-one solution, easily deploy virtual
desktops for less than the cost of PCs and save 60% on VDI infrastructure
costs. Try it free! http://p.sf.net/sfu/Citrix-VDIinabox
_______________________________________________
Mason-users mailing list
Mason-users@...
https://lists.sourceforge.net/lists/listinfo/mason-users

Re: Mason2 how to wrap (augment) content of internal component

by Jonathan Swartz :: Rate this Message:

| View Threaded | Show Only this Message

Well, it's harder than I thought without implementation changes or a plugin.

Here are the options I'm considering so far:

1) Change the way you call these components - i.e. instead of

    <& /form/login.mc, form=>$login_form &>

do

    <% $m->construct('/form/login.mc', form => $login_form)->render %>

Obviously this is ugly, would be better to be able to change it transparently without changing each component call.

2) Change Mason::Request::comp (<& &>) so that instead of calling main() directly, it calls a method call() which in turn calls main(). Then you can override call() or use an around-modifier on it. e.g.

    form/Base.mc:
    ---------------------
    <%around call>
   <form .....>
   % $self-$orig(@_);
   </form>
    </%around>

This introduces an extra method for every component call that will almost never be overriden. Maybe not a big deal in the grand scheme of things, but feels hacky. Also introduces another reserved method name in Mason::Component. Finally if you have multiple layers of these they will wrap in the reverse direction you expect.

3) Add a plugin that does #2, so that the extra method call doesn't hit everyone, just those that need it.

4) Create a way to apply roles to components. Then your Base.mc could use a role that has an around modifier on main().

Thoughts welcome.

Jon

On Jan 6, 2012, at 3:21 PM, Jonathan Swartz wrote:

Definitely possible, but I am working on the best syntax... :)

Jon

On Jan 6, 2012, at 1:55 AM, Roman Daniel wrote:

Is it possible to achieve the effect of wrapping child component content by its parent with internal components?
For request component I could use


form/Base.mc:
--------------------
<%class>
has form => (is =>'ro', required =>1);
</%class>

<%method wrap>
<form .....>
% inner();
</form>
</%method>


form/login.mc:
---------------------
<% $.field(...) %>
<% $.field(...) %>


But when called from other component, method main is called directly and wrap is skipped. 

<& /form/login.mc, form=>$login_form &>


I appreciate any tip

Roman Daniel
------------------------------------------------------------------------------
Ridiculously easy VDI. With Citrix VDI-in-a-Box, you don't need a complex
infrastructure or vast IT resources to deliver seamless, secure access to
virtual desktops. With this all-in-one solution, easily deploy virtual
desktops for less than the cost of PCs and save 60% on VDI infrastructure
costs. Try it free! http://p.sf.net/sfu/Citrix-VDIinabox_______________________________________________
Mason-users mailing list
Mason-users@...
https://lists.sourceforge.net/lists/listinfo/mason-users



------------------------------------------------------------------------------
Ridiculously easy VDI. With Citrix VDI-in-a-Box, you don't need a complex
infrastructure or vast IT resources to deliver seamless, secure access to
virtual desktops. With this all-in-one solution, easily deploy virtual
desktops for less than the cost of PCs and save 60% on VDI infrastructure
costs. Try it free! http://p.sf.net/sfu/Citrix-VDIinabox
_______________________________________________
Mason-users mailing list
Mason-users@...
https://lists.sourceforge.net/lists/listinfo/mason-users

Re: Mason2 how to wrap (augment) content of internal component

by Roman Daniel :: Rate this Message:

| View Threaded | Show Only this Message

Thank you very much for a concise reply.

I'll start with 1) (it may be ugly but it is self documented), if I later found, there are two many cases of wrapping internal comps, I can switch to 2) 

Regarding option 4) I haven't found so far a way how to (reasonably) apply roles to a template. 
I can use 'with' in %class section but only for roles which don't interact with the importing class 
(modifiers, requires, ...) since the role is applied before the methods of the class are compiled.

I tried Scope::Guard unsuccessfully to process 'with' after methods are compiled

<%class>
use Scope::Guard qw(scope_guard);
# I need the role to be applied after methods are introduced in runtime
my $g = scope_guard sub { with 'MyApp::Mason::Component::Form::Wrapper' };

<%class>

which is obvious since on a file level the $g never goes out of scope.

What I even can't imagine is: "Then your Base.mc could use a role that has an around modifier on main()"
How a modifier applied to a base class can wrap a method supplied in a subclass?

Roman Daniel

2012/1/7 Jonathan Swartz <swartz@...>
Well, it's harder than I thought without implementation changes or a plugin.

Here are the options I'm considering so far:

1) Change the way you call these components - i.e. instead of

    <& /form/login.mc, form=>$login_form &>

do

    <% $m->construct('/form/login.mc', form => $login_form)->render %>

Obviously this is ugly, would be better to be able to change it transparently without changing each component call.

2) Change Mason::Request::comp (<& &>) so that instead of calling main() directly, it calls a method call() which in turn calls main(). Then you can override call() or use an around-modifier on it. e.g.

    form/Base.mc:
    ---------------------
    <%around call>
   <form .....>
   % $self-$orig(@_);
   </form>
    </%around>

This introduces an extra method for every component call that will almost never be overriden. Maybe not a big deal in the grand scheme of things, but feels hacky. Also introduces another reserved method name in Mason::Component. Finally if you have multiple layers of these they will wrap in the reverse direction you expect.

3) Add a plugin that does #2, so that the extra method call doesn't hit everyone, just those that need it.

4) Create a way to apply roles to components. Then your Base.mc could use a role that has an around modifier on main().

Thoughts welcome.

Jon

On Jan 6, 2012, at 3:21 PM, Jonathan Swartz wrote:

Definitely possible, but I am working on the best syntax... :)

Jon

On Jan 6, 2012, at 1:55 AM, Roman Daniel wrote:

Is it possible to achieve the effect of wrapping child component content by its parent with internal components?
For request component I could use


form/Base.mc:
--------------------
<%class>
has form => (is =>'ro', required =>1);
</%class>

<%method wrap>
<form .....>
% inner();
</form>
</%method>


form/login.mc:
---------------------
<% $.field(...) %>
<% $.field(...) %>


But when called from other component, method main is called directly and wrap is skipped. 

<& /form/login.mc, form=>$login_form &>


I appreciate any tip

Roman Daniel
------------------------------------------------------------------------------
Ridiculously easy VDI. With Citrix VDI-in-a-Box, you don't need a complex
infrastructure or vast IT resources to deliver seamless, secure access to
virtual desktops. With this all-in-one solution, easily deploy virtual
desktops for less than the cost of PCs and save 60% on VDI infrastructure
costs. Try it free! http://p.sf.net/sfu/Citrix-VDIinabox_______________________________________________
Mason-users mailing list
Mason-users@...
https://lists.sourceforge.net/lists/listinfo/mason-users




------------------------------------------------------------------------------
Ridiculously easy VDI. With Citrix VDI-in-a-Box, you don't need a complex
infrastructure or vast IT resources to deliver seamless, secure access to
virtual desktops. With this all-in-one solution, easily deploy virtual
desktops for less than the cost of PCs and save 60% on VDI infrastructure
costs. Try it free! http://p.sf.net/sfu/Citrix-VDIinabox
_______________________________________________
Mason-users mailing list
Mason-users@...
https://lists.sourceforge.net/lists/listinfo/mason-users