We use closure library and closure compiler, and we want to use closure templates.
But closure templates haven't got inheritance. That's really a problem for us.
As I understand, the reason why closure templates don't have inheritance, is because templates must be simple, and easy to read.
But how can you live without inheritance in big projects?
For example, we have a template file button.soy that generates button with public template project.createButton
and private templates: project.createOpenTag_
, project.createCSSClasses_
, project.createAttributes_
, project.createContent_
, project.createCloseTag_
.
We have JavaScript class project.Button
, and we have project.ButtonCircle
(perhaps this separate class project.ButtonCircle
seems unnecessary, but it's just an example) which extends project.Button
.
project.ButtonCircle
needs little changes made in project.createButton
template.
Of course we can add new functionality to project.createButton
, but it's a very bad idea, because such approach will create monster templates in the future.
Or we can create public template project.createCircleButton
in file button-circle.soy, call all private templates from project.createButton
in it, and when we need to 'override' one of these private templates, (for example project.createCSSClasses_
), we just create new private template in button-circle.soy with name project.createCSSClassesCirbleButton_
.
Yet in this case we need to copy-paste all content from project.createButton
to project.createCircleButton
. That's terrible.
Also we tried using Delegate Templates, but it's not suited for inheritance.
What is approach towards this problem?
It's hard to gather your exact use case but having used soy/closure extensively at my time at Google I sympathize with your puzzlement as they're not my favorite. I agree with @Francois-Richard's general suggestion for keeping common templates very small and composing multiple together. The soy model (and many other JS templating systems I've used frankly) strongly favor composition over inheritance.
Extension
If a CircleButton
is logically and stylistically the same but just with added functionality or styling, then composition will work great.
<div class="circle">
{call .button}
</div>
Parameterization
If a CircleButton
is logically the same but stylistically different, why not allow Button
to be parameterized by shape and reuse the same template?
{call .button shape="circle" /}
Composition
If a CircleButton
is neither logically nor stylistically the same but merely share some base elements, then extract those to templates/classes and use composition.
<div class="circle">
{call .buttonSharedA /}
<span>{call .buttonSharedB /}</span>
</div>
Soy really doesn't jive as well with the rest of closure vis a vis OO-thinking IMHO, and just requires a different approach.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With