Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can live without inheritance in closure templates in big project?

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?

like image 472
Boyo Avatar asked Sep 23 '15 10:09

Boyo


1 Answers

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.

like image 178
Patrick Avatar answered Nov 01 '22 07:11

Patrick