tundra icon indicating copy to clipboard operation
tundra copied to clipboard

How can I write functions with template code inside?

Open wolframkriesing opened this issue 4 years ago • 8 comments

the following works

{% const fn = () => 'print me'; %}
{{ fn() }}

the following does NOT throw any error yet (but also doesnt do anything useful)

{% const fn = () => { %}<b>print me</b>{% } %}

but if I try to call it, i get TypeError: Cannot read property 'toString' of undefined

{% const fn = () => { %}<b>print me</b>{% } %}
{{ fn() }}

wolframkriesing avatar Apr 25 '20 21:04 wolframkriesing

Hello @wolframkriesing! Due to the way the template engine works, those examples aren't valid.

But there is this alternative:

{% const fn = () => { return '<b>print me</b>' } %}
{! fn() !}

It may be ugly but should give you the expected result. :) Regards.

Usbac avatar Apr 27 '20 04:04 Usbac

this will work for smaller templates but once you get to have larger blocks, like an article or a shopping basket item, etc. this will not be handy. as i understand it there is no way yet to have reusable code blocks callable within a template, right? any plan to build that? Is there a roadmap/plan for this project?

wolframkriesing avatar Apr 29 '20 06:04 wolframkriesing

Actually yes! you can use reusable code blocks (at least with external files) in your templates with the require tag.

This is an example where the tag will be replaced by the content of the another_view.html file:

<div>
    @require(another_view.html)
</div>

Also the imported view will have access to the current scope.

Usbac avatar Apr 30 '20 10:04 Usbac

I tried that too, even though it's not ideal imho, but would be a good start.

I tried multiple things, but can NOT get variables set in the template to work in the required template, my code

  {% var aVariable = 42 %}
  @require(src/templates/another_view.html)

the file another_view.html looks like this

aVariable = {{aVariable}}

I always get

UnhandledPromiseRejectionWarning: Error: ReferenceError: aVariable is not defined
    at getRender (/app/node_modules/tundrajs/src/tundra.js:204:15)
    at getCode (/app/node_modules/tundrajs/src/tundra.js:148:35)

I even tried to write

  {% aVariable = 42 %}
  or 
  {% const aVariable = 42 %}
  or 
  {% global.aVariable = 42 %}

I always get this error

wolframkriesing avatar Apr 30 '20 11:04 wolframkriesing

Thank you for pointing out that limitation, it has been fixed! :) 212b5f93030fee403ae0ffde23ece0cf91553df2

By the way, a feature to allow reusable code blocks within the same template has been added to the development roadmap and should be ready for the next version.

Regards!

Usbac avatar Apr 30 '20 22:04 Usbac

Hello @wolframkriesing! The version 1.2 of Tundra is out, and it includes the reusable code blocks feature (called spreads).

Take a look at the documentation to see how to use them (is at the end of the page): https://github.com/Usbac/tundra/wiki/Syntax

Let me know if that complies with your situation to close this particular issue. Regards!

Usbac avatar May 02 '20 22:05 Usbac

I have finally tried out your new spread and it works well, when used in one file. I have e.g. an article-preview block/spread that I would like to reuse in multiple templates. Is that possible? I would kinda need to import the file where the spreads are defined in, right?

wolframkriesing avatar Jun 14 '20 12:06 wolframkriesing

It wasn't possible to use spreads coming from an imported view, but now with the 1.3 version it is possible. :)

02e7f546b2801c5f66377fd568e5bf9d87ae20c8

Just define your spreads in one file and then import that file into the current one with the require tag (like this @require(spreads.html)).

Usbac avatar Jun 18 '20 01:06 Usbac