Discussion:
[jifty-devel] RFC: New Template::Declare Mixin Interface
David E. Wheeler
2009-10-06 21:17:58 UTC
Permalink
Jiftyers,

I'm now pretty clear on how importing templates works in
Template::Declare. And I think I've got a handle on aliasing, too,
though there may well be some subtleties I've missed. But part of the
reason why it was tough for me to figure out (aside from the lack of
documentation) was the fact that these two methods do very similar
things (interface-wise), though their implementations are very
different. The fact that they both fall under the header "Mixin" only
increased the confusion for me.

Before I document these methods, I'd like to propose a new interface
that incorporates the features of both importing and aliasing, but
gives template authors and users a log more control over composition.
It's simpler, too. I propose a new method: mix. To get the current
behavior of import_templates, you'd use:

mix MyApp::SomeRole under '/somerole';

To get the alias behavior, you'd use:

mix MyApp::Stuff under '/stuff' with { name => 'Larry' };

Furthermore, I'd add another keyword, into, which would allow not just
template authors, but template users to mix stuff around. For example:

mix MyApp::Stuff into MyApp::Main under '/stuff';

This would mix MyApp::Stuff into MyApp::Main -- I do not have to be
the author of MyApp::Main (or re-open the package) to do it. If no
`under` argument is passed, it would default to `caller(0)`, just as
it does now.

At first, I'd probably just have the code dispatch to `alias` and
`import_templates`, even as I'd like to deprecate those methods. But
long-term, it might make sense to make aliases and imported templates
use the same implementation.

I think that this is a cleaner interface, simpler to understand as
mixing, and less prone to confusing users.

Thoughts?

Thanks,

David
David E. Wheeler
2009-10-07 21:31:57 UTC
Permalink
Post by David E. Wheeler
Before I document these methods, I'd like to propose a new interface
that incorporates the features of both importing and aliasing, but
gives template authors and users a log more control over composition.
It's simpler, too. I propose a new method: mix.
I've gone ahead and done this in [a branch](http://svn.jifty.org/svn/jifty.org/Template-Declare/branches/mixmaster
), just to be safe. The new `mix()` method looks pretty much like
`alias()`, but with a little more (optional) sugar:

mix Some::Clever::Mixin under '/mixin';
mix Some::Other::Mixin under '/otmix', set { name =>
'Larry' };
mix My::Mixin into My::View, under '/mymix';

Note the use of `into`, so that one does not have to be in the scope
of the package that one wants to mix into. This will prove useful for
a new Catalyst view implementation I have in mind, but I suspect that
it will be useful for other folks, too: it allows one to compose
templates into all sorts of mixtures, if you will.

I can take or leave the use of `set`, but I thought it kind of went
along with other sugary keywords. If it's hated for any reason, I can
kill it off; it's entirely optional.

Of course, you can omit the sugar altogether if you like:

Some::Clver::Mixin->mix( '/mixin' );
Some::Other::Mixin->mix( '/otmix', { name => 'Larry' } );
My::Mixin->mix('My::View', '/mymix');

Here's what I've done in the mixmaster branch:

* Converted the implementation of `alias()` to be the same as that
used for `import_templates()`.

Side-effects:

+ Aliasing a class with super classes now passes the class in which
each template is defined as the invocant to the alias templates. For
example, if Foo defines the template `hello` and Bar inherits from
Foo, and you alias Bar under /here, it used to be that "Bar" would be
passed to /here/hello, but now Foo is passed to /here/hello. This is
how `import_templates` worked, so I suspect that the previously
inconsistent behavior was an oversight.

+ The `aliases` and `alias_metadata` class accessors are gone, as
is `_has_aliased_template()`. The latter method was private, and the
two accessors were undocumented. Were they ever used anywhere, perhaps
in Jifty?

* Added `mix` as described above. No side-effects. I moved the and
updated the documentation for `alias` under `mix` and updated the
documentation for `alias` and `import_templates` to say that they were
deprecated in favor of `mix`.

That's about it. If the changes to `alias` break existing code, I can
revert those changes -- or mock up a compatible interface. But I
suspect that they will have no effect. I'd appreciate some testing.

Assuming that I get buy-in from the interested parties, I'll merge
these changes into trunk and finally fill in the documentation for
mixins. After that, the only other issue I know of is with `path_for()
`, mentioned in another thread. I can fix that after the merge.

Best,

David
David E. Wheeler
2009-10-08 17:43:11 UTC
Permalink
Post by David E. Wheeler
+ The `aliases` and `alias_metadata` class accessors are gone, as
is `_has_aliased_template()`. The latter method was private, and the
two accessors were undocumented. Were they ever used anywhere, perhaps
in Jifty?
FYI, On IRC, Shawn tells me that these methods weren't used in Jifty
or the BPS code anywhere. On Jesse's request, I restored them to the
`aliases()` and `alias_metadata()` methods to just Carp::cluck().

Best,

David

Loading...