onelang / OneLang

MIT License
1.12k stars 84 forks source link

Template: self-removing blocks #17

Open koczkatamas opened 6 years ago

koczkatamas commented 6 years ago

There are multiple cases where we only have to add eg. a method if it has content. This sometimes needs to be predicted beforehand, which requires some ugly hacks right now.

Most of the cases happens where we use an {{if}} inside a {{for}} and we don't know many elements will be printed out actually. But even if we use two of fors or ifs it complicates the "predictor" expression and looks ugly.

We also need an {{else}} option where we don't just remove the block but replace it with some other content (eg. with pass in Python)

Some places where we need this logic:

How does it work?

If every child template gives empty result then the block is not showed (even if there is static content inside the block, eg. prefix / postfix text). If {{else}} is specified then instead of empty result, the contents of {{else}} is shown.

Proposed syntax

Python use pass if the method has no statements:

{{block}}
  {{genBody(method.body)}}
{{else}}
  pass
{{/block}}

Go / other langs: remove constructor if not used:

{{block}}
  func init() {
    {{for class in classes|sep=\n\n}}
      {{if class.reflect}}
        ...
      {{/if}}
    {{/for}}
{{/block}}

To-be-decided

What happens if we want to use that information whether a block was generated or not? Eg. only call an initialization method if it was generated beforehand? I don't know such case now, but we may run into one in the future...