[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