CloudyKit / jet

Jet template engine
Apache License 2.0
1.26k stars 106 forks source link

Setting variable values from content OR pipelining blocks #167

Closed simonekulczycki closed 4 years ago

simonekulczycki commented 4 years ago

I'm porting some code originally written in jinja to Jet and am faced with this use case (in jinja):

``` {% set ContentA %} {% endset %} ``` ``` {% import file1.tpl as file1 %} {{ file1.ContentA | customFilterX }} ``` Basically what it does is it sets a variable using the {% set %} directive and then prints it in another file passing it through a filter function. I haven't found a way of doing it in Jet as there is no way of setting a variable using the 'block' syntax. Ideally I would need to do one of the following: 1) Be able to set a variable using a block syntax, something like this (excuse the horrible syntax): ``` {{ ContentA := }} {{ end }} {{ ContentA | customFilterX }} ``` 2) Be able to use pipelining on blocks ``` {{ block ContentA() }} {{ end }} {{ yield ContentA() | customFilterX }} ``` Is there an alternative way of doing this that I am missing? Thanks!
sauerbraten commented 4 years ago

Jet v3 introduced exec() and return, so you could do this to achieve what you want:

file1.jet:

{{ return `
<some>
<very><complex>
<and><long>
<html><content>
` }}

file2.jet:

{{ exec("./file1.jet") | customFilterFunction }}

With this, template 1 simply returns a long mutliline string (using backtick delimiters), and tempate 2 "loads" the string by executing template 1 before using it in a normal pipeline. You can't assign actual rendering output to a variable in Jet though, so you can't have {{ actions }} inside the HTML in template 1.

Does this work for you?

simonekulczycki commented 4 years ago

Thanks for that, I knew I was missing something. This does work for me so I'll take that route. There are some small things that are lost in the process compared to jinja though. Namely:

1) Since the html is in quotes you loose syntax highlighting, code validation etc. Of couse there are ways around it.

2) The original code had multiple definitions in a single file. With the way you described i can only define a single block of html per file.