Feedback for new cellog:namespaced-templates package

Hi,

tl;dr https://github.com/cellog/namespaced-templates <-- wrote this, looking for feedback

I ran into a problem crafting a flexible way to swap between template options while rapidly prototyping a site. I noticed that I was manually prefixing all of my templates with the same prefix. This also means that if I want to pop in a small change within a complex template tree (i.e. something in the middle of a rendered page) to try out a couple of options, I need to either write custom switching code for just that section every time, or copy/paste the whole template tree, rename every template, add the changed code, then shoot myself in the head.

This doesn’t seem very fun (especially the last part), and so I decided to try to figure out an easy way to dynamically name templates based on something simple, like the directory. So, yesterday, namespaced templates was born.

Basically, if you pop your template trees into subfolders of the client/ or client/views directory, and append the “.ns.html” prefix instead of “.html,” a pre-processor will find all the <template name="blah"> blocks and prefix the name with the path, / replaced with _. So, a file “client/views/maintemplate/blah.ns.html” with <template name="blah"> becomes <template name="maintemplate_blah">.

In addition, a dynamic way of referencing these templates is needed. I elected to go with a minimal syntax change, so that templates can still be easily edited with your favorite code editor. To dynamically include templates, one uses:

${{>blah}}

instead of

{{>blah}}

This is compiled into {{> Template.dynamic ___goto "blah" "***noargs***"}}

${{>blah my="special" arguments="are also passed"}}

compiles into {{> Template.dynamic ___goto "blah" my="special" arguments="are also passed"}}

The ___goto helper returns the arguments Template.dynamic expects. It either passes the current template data if no arguments are passed, or the passed data. The magic is in how it modifies the template name.

To find templates, the package introduces a new concept: template path. Just like the executable path for command execution, template path is a separated list of template paths to search in. Examples might be "maintemplate" to only prepend maintemplate_ to templates requested, or "specialsubset:maintemplate" to search first for templates in the specialsubset template branch, and then in the maintemplate branch. To also search for templates without prefix, use a blank section like this: "specialsubset::maintemplate" or ":specialsubset:maintemplate" The first example will look for top-level templates in between looking in specialsubset and maintemplate, the last example looks first in top-level templates. Top-level templates are always searched for last, regardless of whether they are in the template path (this behavior may change if it introduces too many issues).

The template path can be set statically with the {{set_template_path "path:anotherpath"}} helper, or dynamically in a startup file:

Namespacer.setPath("path:anotherpath")

The template path is reactive, and if changed, templates that rely upon it will re-render. This allows quick switching of entire template trees, which is very useful for rapid prototyping.

I’d love to be able to get some assistance in providing an option to “compile” the templates for production, when the flexibility is not needed, once a single template tree exists. This would improve performance, by removing the dynamic template lookup.

Also, the html scanning/compiling is literally copied and pasted from meteor templating package. Is there some hook in Blaze that I am missing which allow me to intercept file contents before rendering and return the file to Spacebars just in time?

Thanks in advance,
Greg

2 Likes