[Maypole] Re: Maypole responding to requests very slowly (or, how to get just one associated record instead of getting the world)

Simon Flack sf@flacks.net
Fri, 03 Dec 2004 17:28:44 +0000


Peter Speltz wrote:
> --- David Baird <dave@riverside-cms.co.uk> wrote:
> 
> 
>>
>>Simon Flack wrote:
>>
>>>Peter Speltz wrote:
>>>
>>>>I was thinking in the view::base where "IT" is created of doing 
>>>>something like
>>>>this:
>>>>
>>>>    . . .
>>>>    cgi => $r->template_args{classmetadata_cgi} || { $class->to_cgi }
>>>>    . . .
>>>>
>>>>Then the model's sub can make them if it wants or set it to "1" to get 
>>>>none or
>>>>do nothing and get them.
>>>
>>>
>>>That looks good. But I'm not sure that it should be controlled by a 
>>>template parameter. I was going to suggest something in $r->config, but 
>>>that doesn't smell quite right either.
>>>
> 
> 
> To me, since classmetadata is a template_arg essentially, so it would make
> sense to override it in template_args. which is what you do now.  But you have
> to do this currently and its all or nothing in the current View::Base
> my $classmetadata = {}
> $classmetadata->{cgi} = { col1 => ..., };
> $classmetadata->{list_columns} = [ . . . ];
> # Below wipes out all classmetadata except what's defined above.
> $r->template_args->{classmetadata} = $classmetadata;  

It just seems a little odd to me to alter the relationship between the 
model and the view by setting a template variable. It feels more like a 
hack than a proper solution. I don't mean any offence, we may have to go 
with hacks for the short-term to preserve compatability, but I'd like to 
know what the ideal solution would be first.

> It's obvious why that's undesireable to say the least. That's why i like the 
> $r->{template_args}{TopLevel__NextLevel__YetAnotherLevel} method. Old code
> still works but use $r->{template_args}{classmetadata__whatever} to override
> individual vars made in View::Base and $r->{template_args}{TopLevel} to
> override whole heirarchies.
> 
> NOTE: double underscore separate levels in hash.
> 
> 
>>>Perhaps it's something that you define on a class-by-class basis. Or 
>>>perhaps you want different behaviour for different actions in a model?
>>>
> 
> 
> Not sure what you mean. Each action sub can override whatever it wants. Say in
> view, you don't want overhead of making cgi or list_columns say this:
> sub view {
>   ...
>   $r->template_args{classmetadata__list_columns} = 1; 
>   $r->template_args(classmetadata__cgi} = 1;
> 
>   .. .
> }

That syntax looks quirky to me. I'd rather change Maypole::View::Base to 
set each param individually than to add to the list of parameters that 
we need to support.

> Everything still backward compatible, just a handy optimization and more
> powerful configuration of template_args. And template sys. independent.
> 
> 
>>>I'd be tempted to change it to:
>>>
>>>     cgi => sub { $class->to_cgi() },
>>>or
>>>     cgi => sub { $class->to_field(@_) },
>>>
> 
> 
> This looks interesting.
> 
> 
>>>That should work quite nicely for M::V::TT - there's no overhead unless 
>>>you actually use it in the template. I imagine you'd need a different 
>>>solution for Mason though.
>>
>>Mason templates are just Perl, so you would say
>>
>>     $classmetadata->{cgi}->()
>>
>>instead of
>>
>>     $classmetadata->{cgi}
>>
>>Out of interest, how does the call look in TT - is it the same for both 
>>cases?
>>
> 
> 
> [% classmetadata.cgi.column %]
> In TT objects, hashes, lists all use . operator to do their thing.
> 
> 
>>Maybe the whole classmetadata thing should be an object?
>>
> 
> 
> Can you give an example of how that would significantly improve things now? I
> don't see how it would help but I wouldn't be surprised if it would. 

I'm not sure we need the extra complexity. Everything in 'classmetadata' 
is already the result of a method call on $class.

We could just *always* provide classmetadata.name and make the rest of 
it optional. Then you can call the methods you're interested in from 
your template (e.g. with Template::Plugin::Class). And from the sound of 
it, you can do the same in Mason without a plugin.

--simonflk