[stringtemplate-interest] template existence testing
Zenaan Harkness
zen at freedbms.net
Tue Apr 1 15:32:21 PDT 2008
On Tue, Apr 01, 2008 at 11:59:31AM -0700, Terence Parr wrote:
>
> On Mar 31, 2008, at 3:41 PM, Zenaan Harkness wrote:
>> As you correctly point out, overriding a template is exactly what I want
>> to do.
>>
>> BUT !! I don't know the name of the template I want to override in
>> advance
>
> No problem. use template ref indirection.
>
> <(name)()> inserts instance of template "x" if "name"->"x" in the attribute
> table
Yes, here's the extract from my first email in this thread:
> <if( st_exists("att_"+a.attributeName) )>
> // we have a specialization for this method, include
> // attribute-specific specialization code:
> <("att_"+a.attributeName)()>
> //alternatively:
> <({att_<a.attributeName>})()>
> <else>
> return a.attributeName;
> <endif>
>
> Barring the if conditional of course -
> st_exists("att_"+a.attributeName).
>> ((at least, the view does not know, and the view should not have
>> any deep knowledge of the data Model, at least as much as possible, and
>> putting this in the view would cause an explosion of data model
>> knowledge in the view, where there should be none)),
>
> Yep, the model can push in the name of the template no problem. I have
> another user that does this very thing to decide how to display something.
And in response to this (model pushing in template name as an
attribute), here's this from my first email too:
> It is possible to put a boolean in the Model, but that would
> violate my MVC: specializations depend purely on the specific
> template being used. The model simply should not know or care
> whether there is an attribute method body specialization - it is a
> view specific thing.
>> As you can see, not only am I currently caused to put very
>> model-specific knowledge in my [java|csharp|perl]-lib.stg template
>> groups, but it would also obviously cause the unnecessary explosion in
>> number of templates mentioned above.
>
> See if the indirection thing helps you. It gives you a great deal of
> flexibility: you get indirection as well as polymorphism combined :)
So, yes, template indirection is something I'm using, and gets me half
way there:
The problem is, as you correctly point out above, "the model can push in
the name of the template", so I could assume _every_ attribute of every
model possibly has a specialization, so that my model does not have to
have knowledge of which attributes' rendered outputs specifically require
specialization, and instead the Driver simply assumes they _all_ do,
but if the (specialization) template does not exist then there's an
attempt in ST to render a template which doesn't exist, and I get the
following error:
java.lang.IllegalArgumentException: Can't find template att_cowsOnFarm.st
So,
it is the output-language template specialization view (template) and
this view only, for a particular (model attribute, output language -
Java, C$, perl) combination _only_ (not the model, and not the
java-lib generic template group), which needs to know that there is a
specialization of a particular model attribute's template
(and the parent java-lib.stg template does not know the name of that
"overidden" template in the template specialization view in advance -
that would be unnecessary deep model knowledge embedded in the view
and I don't know how to make it work without (and which you also
suggested above) putting the specialization template name into the
model, which would require the model to know _which_ views
(templates) are implementing specializations for _which_ model
attributes, which is an MVC separation violation in reverse)
There are three solutions:
Option 1)
Have an attribute-specific template for every attribute in the model, so
that the appropriate attribute's template can be overridden by a
particular view specialization template (Java, C#, perl) iff required.
- causes model-specific knowledge to be in the view, can be
mitigated with an intermediate lib template group
- causes explosion in number of templates (at least in the
intermediate (model-specific) lib template group, most of which
are not used
- causes the driver (or the model) to have to insert the various
attribute specialization template names (for each attribute of
each model)), as attributes into the ST, most of which are never
used
- if in the model, violates MVC separation
Option 2)
Have the specialization view (for a particular model) override the
generic attGetter(a) template:
- reduces (at least marginally) the number of unused attribute
specialization templates (system-wide reduction, since some models
won't have any specializations)
- still requires the model, or driver, to insert template-names (as
attributes in ST view) for such models, which requires a flag in
that model to say thisModelMightHaveSpecializations, which is
getting model specific (minor MVC violation), and I imagine would
ultimately degenerate into Option 1) ("many models have at least
one specialization in at least one of the output language views,
so let's just assume they all do, as it simplifies the code")
Option 3)
Have a facility (in the driver, or directly in the template engine)
which can test for the existence of an arbitrary, name not known in
advance, template, and only _if_ it exists, execute this template, thus
avoiding the "template not found" ST error:
- requires implementation of template lookup table
- if in ST engine, requires no external support, can be used in
simple cases where people might not be bothered normally to
implement the functionality in the driver
- if in driver, can have system-wide, load-lookup-table-once
efficiencies; this is merely a performance optimization if the
facility otherwise exists in the ST engine
--
Homepage: www.SoulSound.net -- Free Australia: www.UPMART.org
Please respect the confidentiality of this email as sensibly warranted.
More information about the stringtemplate-interest
mailing list