stencilproject/Stencil

Add support for template variables

Closed this issue · 7 comments

When creating complex templates, I often encounter some situations where the use of variables would really help.

One simple example is a switch statement with a default case. Some implementations might require the default case, others don't if they already implement all the cases of the enum. Having a template variable available for increment would solve this issue as comparing the variable value to the number of cases could determine if the default case needs to be implemented or not.

I could obviously handle this before rendering the template, but I strongly believe it is an issue more related to the template formatting than the model logic.

What do you think?

We plan to soon merge https://github.com/SwiftGen/StencilSwiftKit — which adds a bunch of extensions, tags and filters to stencil — to Stencil itself soon.

StencilSwiftKit already contains a tag to set a variable from your template that could fit your needs, so once we do the merge you'll have access to these tags.

That's really good news. Thanks for the quick response. I will take a look at StencilSwiftKit and see if I can start using it now.

The tag you're interested in in StencilSwiftKit is {% set %} tag.

If you're writing Stencil templates that will be consumed by either SwiftGen or by Sourcery, both those tools that are using Stencil templates include StencilSwiftKit so already support those additional tags.

If you're writing Stencil templates for other needs (like HTML templates delivered by Vapor for example) I think you should be able to add StencilSwiftKit as a dependency to your project in addition to the Stencil dependency you already have and use StencilSwiftKit directly until we merge it into a future version of Stencil. (Don't hesitate to dig into StencilSwiftKit's README as we provide a Template subclass already preconfigured to use the additional tags)

I use Stencil for something different. I'm not totally sure how this works: do I simply need to make StencilSwiftKit a dependency of my project and the extension will be detected or do I need to manually create an extension? I can't find any documentation. Thank you.

Nevermind, I found what was missing (couldn't find any documentation for it though). If anyone is in the same situation make sure that:

  • the StencilSwift extension is registered customExtension.registerStencilSwiftExtensions()
  • the Environment instance is initialized with the custom template class as Environment(loader: FileSystemLoader(paths: [""]), extensions: [customExtension], templateClass: StencilSwiftTemplate.self)

@AliSoftware After playing a little bit with {% set %}, I realized the tag is restricted to the local scope. Is there any way to change the value of the tag so it can be used in a larger scope? Thank you.

I don't think so, as that's a core behaviour of template engines like Jinja, Stencil, Mustache, etc…: each scope creates an underlying context that gets pushed at the opening of the scope and poped at the end