[jifty-devel] Template::Declare Updates

David E. Wheeler david at kineticode.com
Tue Sep 8 23:45:47 EDT 2009

Thanks for taking the time to respond to my missives, Ruslan, greatly  

On Sep 8, 2009, at 4:45 PM, Ruslan Zakirov wrote:

>> Yes, from a user's point of view, AFAICT, aliases are are exactly  
>> like
>> imported templates except that you can attach "package variables" do
>> them. They look to be slower, too.
>> Am I missing something? Anyone else have knowledge of this?
> svk annotate may help find responsible person.

Jesse, `svn blame` mostly shows your fingerprints all over both  
`alias` and `import_templates`. Care to enlighten me as to why we have  

>> I'll have to have a look at that. I can see how `end_buffer_frame()`
>> would be useful for that, but then what's the purpose of
>> `new_buffer_frame()`?
> You have stream and can open a frame with a filter or frame with a
> private buffer that is out of stream.

Ah, I see. Neither is mentioned in tests, though. I'll have to look at  
what you did for Jifty, add some tests, and then document them  
properly. They definitely sound useful.

>>>> * `package_variables()` had a bug that made it useless. It also was
>>>>   not previously documented. Should I remove it?
>>> Don't know.
>> Perhaps I'll un-document it (it wasn't documented before) and add a
>> deprecation warning to it. Thoughts?
> I think fixing it and making available for the world is fine too.

That's what I've done so far, but I'm not sure there's a point to it.

>> Sounds like it shouldn't be documented then, yes?
> It can be moved to the end of the file and documented like, this is
> helper and you should use different syntax to set attributes of the
> tags. Undocummenting and comment probably will solve confusion as
> well.

I can document `append_attr()`, but if it's not for users to users at  
all, I think that the documentation should remain commented-out. It's  
really private, no?

> May be for sake of consistency we should introduce new function
> show_template and have the following
> show - magic that dispatch to _page or _template
> show_page - show exlcuding private
> show_template - show including private
> That will clear some confusion, I had that too at first.

The terminology is bad, frankly. Are these really intended to be used  
in user-space? I know that show() dispatches to show_page() as  
appropriate, but is show_page() ever used by template authors or tag  
set authors?

> It's unlikely.
> It's useful for pluggable applications, for example App::View,
> App::Plugin::X::View as roots (reverse order).

Ah, okay, I can see how it'd be useful to use them for plugins and  
whatnot. Very good.

> No inheritance. Layout your temlates as you like. In Jifty they may
> follow URLs completly or you can change the way things dispatched in
> dispatcher, for example you have '/user/show' template and in
> dispatcher has '/user/*/show' rule that loads the user, set argument
> and dispatches to '/user/show' template.

Sorry, what dispatcher? Is that a Jifty term for a controller? I so,  
then yes, I agree.

>> I ask because Mason dhandlers and autohandlers definitely impose
>> meaning on template paths as far as template resolution goes. But
>> AFAIK, no such meaning is imposed by T::D. True?
> True. I think it's better to leave dispatching out of T::D.

Okay, so paths have no inherent meaning to T::D. I had thought that  
was the case, but wanted to be sure, since import_templates() and  
alias() specifically affect paths, so I wanted to understand whether  
this was important for T::D or merely for users of T::D. And the  
answer is the users: I can impose the meaning on paths that I deem  

>> The only difference with my proposed `move()` method is that you  
>> would
>> only be able to call the latter of these two names for the template.
>> In short, the template would be moved (renamed) from "howdy" to  
>> "stuff/
>> howdy").
> Either something is broken or you're missing something. You can not
> run "howdy" from a template "/xxx" as "howdy" is relative path and
> resolves against "/xxx" to "/howdy" that doesn't exist, but you can
> run show("howdy") from "/stuff/xxx".

Oh! So paths *do* have inherent meaning! If I'm in /extras, I can't  
dispatch to "howdy", but I can dispatch to "/howdy" or /stuff/howdy",  

> Oh, I've read to the end and now understand. This mess is a result of
> using all classes as roots. That's it. See below.

Right, okay.

>> Say that I've defined a wrapper in a package:
> [snip]
> I never used wrappers. Actually Jifty don't use wrappers for page
> layouts, but instead adds 'page' function that does layouting. May be
> it's good to look there.

Sure. Wrappers were something I added last year, actually; I just want  
to have a way to make it easier to execute them in packages other than  
where they were defined. I think that's reasonable.

>> In this way, the View::Table package can use the wrapper even though
>> it's defined in View::Root, just as long as both are template roots.
> Using roots is wrong here again. In most cases an app has one root and
> all other roots are empty and for extending the app.

How are templates located in other packages if you don't tell T::D  
about those packages via the `roots` parameter?

>> Exactly. This is why I want to change things so that it looks at
>> defines all
>> classes in MyApp::View::TD::* namespace as TD roots, but moves the
>> templates in all but TD::Root to a path named for the package name.
>> Does that make sense to you?
> No, it's just wrong. Jonathan Rockway made mistake that should be  
> fixed.

I want to fix it, but first I must understand. I'm glad I've asked.

> Once again so it's clear. Roots are as different directories in a file
> system that mask each other. Consider CD-ROM that you can read and
> change using /flash/drive/cd-rom/xxx/. Files on change placed on flash
> drive, but only those that are different.
> In application root class may look like this:
> package View;
> template index => sub {
> };
> template splash => sub {
> };
> ...
> alias View::Users under '/users';
> package View::Users;
> alias View::CRUD under '', model => 'App::Model::User';
> template preferences => sub {...};
> package View::CRUD;
> template create => sub { my $model = $slef->pv('model') };
> template show => sub { ... };
> template list => {  ... };
> template edit => { ... };
> Something like that and only 'View' is root, but everything else
> either imported or aliased into root and/or other classes to build
> full layout.

Yes, but how does T::D resolve, say, users/preferences, unless you  
pass View::Users to `roots`? Does it just automatically know about all  
of its subclasses loaded into memory? Such would make it difficult to  
have more than one view at once, no?

> Now I see that plenty of problems you try to solve are caused by one
> incorrect implemtation decision. Once it's solved, you don't need move
> function and things get better.

Okay, I'm thinking something like this for Catalyst:

     package View::TD::Root;

     template index => sub { ... };
     template splash => sub { ... };

     package View::TD::Users;
     template preferences => sub { ... };
     import_templates View::TD::Users under '/users';

     package View::TD::Widgets;
     template preferences => sub { ... };
     import_templates View::TD::Widgets under '/widgets';

     package View::TD::CRUD;

     template create => sub {
         my ($self, $c) = @);
         my $model = $c->model( $self->package_variable('model') );
     template show => sub { ... };
     template list => {  ... };
     template edit => { ... };
     alias View::TD::CRUD under '/users', { model =>  
'Model::CDBI::User' };
     alias View::TD::CRUD under '/widgets', { model =>  
'Model::CDBI::Widget' };

I think that this is similar to what you've done, only I've called  
`alias` after the classes are defined, because otherwise the templates  
don't exist yet in those classes. I also used `import_templates` when  
I didn't need a package variable.

So does that correspond better with what you mean?



More information about the jifty-devel mailing list