Thursday 21 January 2010

Catalyst-Mason passing variables in a convoluted manner

Okay my problem is the following:

I have an autohander containing a header component and I would like to dynamically set variables from my base component in the header component.

solution 1

use attributes, the included header expects the argument and the base component may have the attribute

set optional attribute in the base component:

<%attr>
title=>'Specific title for my page'
< / %attr>
....
% rest of component

in the autohandler:

% my $title = ($m->base_comp->attr_exists('title')) ? $m->base_comp->attr('title') : "";
<& /common/header_forsite.mc, title=>$title &>


then in the header (common/header_forsite.mc);


<%args>
$title=>'Standard title for site'
< / %args>

...
<title> <%$title%> </title>
....
Solution 1 (for Mason 2)

Mason 2 no longer has the <%attr> and <%args> sections they are both to be handled by <%class> attributes (Moose style):

The autohandler has been replaced with Base.mc so that the following should hoepfully be a replacement for the HTML::Mason solution above:

set optional attribute in the child component:

<%class>
has 'title' => (isa=>'Str',default=>'Specific title for my page');
< / %class>
....
% rest of component

in the Base.mc:
         
         <%class>
         has 'title' => (isa=>'Str',default=>'Default');
         < / %class>
% my $title = $self->app_name;
<& /common/header_forsite.mc, title=>$title &>


then in the header (common/header_forsite.mc);



         <%class>
         has 'title' => (isa=>'Str',default=>'Standard for the site');
         < / %class>
...
<title> <%$title%> </title>
....



Solution 2

Use methods. Methods are first called from the base component, in our method we could setup a variable to be used in our included header file (if we weren't including the header but the contents were in the autohandler we could just call the method to display the content)

set a method in our base component:

<%method .some_method>
% ...
% $c->stash->{eg_variable} = ' EOS'
% //some javascirpt to display in the header perhaps
% $('[id^=type').each(function(){
% $(this).hide();
% }
% EOS
< / %method>

declare our method in the autohandler and call it in the correct location (before call to header):


<%method .some_method>
% #does nothing at the moment - overridden by component
< / %method>

% my $title = ($m->base_comp->attr_exists('title')) ? $m->base_comp->attr('title') : "";
% my $self = $m->base_comp;
% if ($self->method-exists('.some_method')){
% <& SELF:.some_method &>
% }

<& /common/header_forsite.mc, title=>$title &>


Then the stash variable can be accessed in the header (common/header_forsite.mc):


$(document).ready(function(){
...

% if (defined($c->stash->{eg_variable})){
<% $c->stash->{eg_variable}%>
% }

});
...

No comments:

Post a Comment