Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Nunjucks – A rich and powerful templating language for JavaScript by Mozilla (mozilla.github.io)
108 points by kolev on Oct 12, 2014 | hide | past | favorite | 43 comments


I love me some Python/Jinja/Flask/CherryPy, but after having written JS apps in React that run seamlessly on the client and the server, I can't imagine going back to something like this. The best case scenario, you have to maintain a JS port of your app to support rendering your Jinja templates on the client. Or, you can just use Node, Webpack, and React to serve a single codebase that renders on either end. Save Python for your data API.


Why is the top comment on Hacker News always a nay-sayer? Not everyone is working on greenfield projects. Nunjucks is a huge improvement for many large codebases.


Well, right now there are three top-level comments, and the one you refer to is the only one of those presenting more than a sentence. Also, it seems to be no longer ranked first.

In any event, I must say I like this kind of comments: a bit opinionated but putting forth some rationale, and hence inviting a healthy exchange of opinions.


> and hence inviting a healthy exchange of opinions.

There is no "inviting a healthy exchange of opinions",he is basically just trashing the project.There is nothing interesting in what he is saying,though he's free to say whatever he wants.Proof is the answers to his comment.


I don't consider a qualified statement of preference to be "nay-saying." If the article was about React, someone claiming to prefer Nunjucks would be "nay-saying." Since it's about Nunjucks, someone claiming to prefer React is "nay-saying."


I've been using Nunjucks client side and Flask + Jinja2 server side for about a year now. While there's some duplicate effort, it's not as bad as you might imagine.

The duplicate effort: porting some custom Jinja2 filters and plugins from Python to JS. That was a few hours of work on a project that has seen thousands of hours of total work, so down in the noise really. If Python on the server side has big benefits in your problem space, don't let this deter you.

The other thing to be aware of if you want isomorphic templating across JS and Python: Nunjucks is a subset of Jinja2. When I did the Jinja2 -> Nunjucks port, probably 95% of things just worked. The other 5% was either language-idiosyncratic stuff (for example {% set foo = 'bar' %} is scoped to the current block in Nunjucks, but leaks out of block scope in Jinja2) or places where I was being unnecessarily fancy in templates. The port forced me to keep my templates simple and not use the more exotic features of Jinja2, which has turned out to be a good thing.


If Nunjucks rendered performantly (like React), I could see the argument being made that it's the same upsides with an easier to read syntax (and should be thought of as an alternative from that POV); however, marketing it as a way to render your Python app in JS doesn't appeal to me for any new project.


To that end, I wonder if the virtual DOM aspect of React could/should be broken out into its own library. You could have different templating languages up front to suit different use cases/programming styles, but each would be converted to DOM in the fastest way possible by React's renderer.

There are so many awesome things that React's model enables (like live editing with react-hot-loader). It would be awesome if the next generation of templating languages could inherit them for effectively free.


What, you mean like virtual-dom[1]?

[1] https://github.com/Matt-Esch/virtual-dom


I've never worked on a larger javascript project, so I'm not sure why you'd care if your front-end js renders on the server (i'm assuming this means no visual browser). Is this for purposes of automated testing?


It gives you the best of both worlds: Non-JavaScript user agents, like search bots and scrapers, can still understand your page (as if it's rendered on the server), but you don't need to send redundant markup on each page view (because the client can render the new page with just a diff).


Slightly off-topic, but have you tried Ractive? I found it's 'ideology' similar to React (reusable components, virtual dom), but less verbose.


I personally dislike react templating, and not everything is meant to be a single page app. So your way of doing things isnt definetly not as smart as you think.


React is not really like Angular, you can use it to improve a page by adding new components, you don't have to use React for everything like you would do with Angular.

But yeah, I'm not really a huge fan of the template system either and the whole jsx thing is not really convenient.


Well,I didnt talk about AngularJS. I talked about SPAs and the fact that I dont like React templates and JSX in general.


What I'd really like to see would be a nice templating language that recognizes and takes advantages of the regular structure of HTML rather than just treats it as a giant string. Can you imagine writing a program using string templating rather than functions, objects and libraries? Sure, it would be possible, but it would be rather awkward...

The closest I've seen to what I want is DRYML: http://hobocentral.net/manual/dryml-guide

The big advantage of DRYML over systems like React & builders is that it has a really nice story for customization. Rather than customizing just through XML attributes, it also has a system for passing in snippets through XML children. But not just snippets for the top component, but but snippets for children of the components you're instantiating.

This has huge advantages for reusability. There are millions of jQuery widgets out there. How come you never use any of them? They never fit the style, behaviour nor requirements of your app. Yet on the server side, you pull in tens of gems, npms, etc from random authors.

DRYML allows customization in both the small and the large. It works well for both defining and customizing <a> tags as well as huge custom components. That huge custom component will use your customized <a> etc, so it automatically picks up your theme and behavior.

DRYML has some major disadvantages though: it's really nice to use, but defining new components looks like line noise. It's also tied to a heavyweight, lightly used framework for Ruby on Rails called Hobo.

One of my many projects abandoned due to lack of time is a port of DRYML's "standard library" Rapid to React. React isn't quite as nice as DRYML for re-use and customization, but it has a large number of advantages in popularity, speed and readability. If anybody else is interested in the project, give me a shout.


The Enlive scraping/templating library for Clojure can be used in a pretty novel way to generate templates. I guess it's a bit like transforming XML with XSLT, except without the need for an intermediary language (in favor of a DSL in Clojure).

Templating with Enlive takes regular old HTML, which could even be mockups of your ui, and a list of (selector, transform) pairs to apply to it. The selectors mostly mimic CSS, while the transforms come with a library to manipulate node attributes, contents, etc. Taking a non-functional form and setting its method and action might look like this:

    [:form#my-form] (enlive/set-attr :action "." :method "POST")
My favorite part of using enlive is that it removes almost all responsibility from any frontend developers to know about the templating. They can just produce straight HTML mockups with enough CSS hooks for you to get in and change what needs changing. I even use it on projects that I don't envision anyone else working on -- it's nice not to have to context-switch between design and development all the time.


There were a whole family of older template systems that worked on this model. They suck because in practice they are much more restrictive, difficult to work with, and in most cases inefficient, since fundamentally they are working in the domain of a fully parsed node graph, instead of simply being lightweight control structures for basically memcpy().

See e.g. https://en.wikipedia.org/wiki/Template_Attribute_Language

On the flexibility front, the same template language (and especially ones with good whitespace control, e.g. Jinja2) can be used for any text-like format. If browser or device quirks force you to emit invalid XML to trigger some desired behavior, you don't end up in a fight with your perfectionist templating system (and probably resorting to regexes over its output) to achieve the desired result.

I'd say (and probably, a younger version of myself turns in his grave as I say it) that in this case, worse turns out to be much better.


TAL as it was implemented for ZOPE was a total abortion (especially when they threw in other crap to make up for its gaping weaknesses like TALES, METAL, and those goofy expression what were not anything like any other language, plus "acquisition" which was a terrible and useless approach to scoping). The ZOPE stack's approach to templating and scoping and components and their entire way of thinking about it was totally demented and wrong headed. I used it a lot in my wild and crazy ZOPE days, and I hated it then and won't ever go back.

On the other hand, there are other similar attribute based xml templating languages that are much much better, because they didn't try to reinvent the wheel out of tapioca and rusty iron filings, but instead they simply acted as a thin veneer over Python, so everything you knew about and could do in Python applied without any distortion or unnecessarily creative reinterpretation.

Specifically, TurboGears used the "Kid" templating language, the next generation of which was re-implemented as "Genshi". I have used both extensively, and although they do have some problems and limitations (many of which Genshi addressed), I really like them a lot, and they are easy to use and think about, and not so full of surprises and disappointments as the horrible stuff from ZOPE that they (distantly) descended from. I've used Kid and then Genshi in large template-heavy projects over many years, and I still use Genshi and like it. It is actually quite elegant and minimalistic, and super easy to learn.

http://genshi.edgewall.org/

Genshi operates on pure clean XML internally, has real Python loops, conditionals, variables, functions, parameter passing and extensibility, and has plug-in serializers for various formats like XML, XHTML and HTML5, that know about all the formatting rules and conventions and browser quirks and superstitions like <BR />, and never produce incorrectly quoted or formatted content. You can also use it to product plain text as well as markup.


Yet client-side React is faster than string template languages for most practical purposes.

And rarely is speed the most important attribute of a template language. If it was, we'd be writing all of our server code in C.

At least for DRYML, it only requires valid XML on input, it can emit any string on output.

But in essence, you're right. String templating languages have been more successful than TAL or DRYML. But my belief is that's because we just haven't done it properly yet. TAL suffers XML disease, and DRYML has other problems.


Don't you avoid needing to work on a fully parsed node graph if you proccess data using streams/events? Kind of like how SAX parsers avoid creating a DOM tree in memory.

I think Genshi does something similar to this but I'm not 100% sure.


I agree completely, which is what I did with my own binding library (which is supposedly going to be open-sourced in early 2015). The templating language is HTML (which can be viewed and styled normally) with a few custom data- attributes, the logic is Javascript. No extra silly half-assed languages to learn (aren't HTML, CSS, and Javascript enough?). The entire library is under 7kB minified (less gzipped) and does one-way (read-only) and two-way (live-updated) binding without changing the underlying object.

To bind an object to a chunk of DOM (it leverages jQuery) you simple do something like $(selector).bindomatic(object) and you're done. (If you need additional logic, you pass it on the side in an options object.)


> What I'd really like to see would be a nice templating language that recognizes and takes advantages of the regular structure of HTML rather than just treats it as a giant string.

A webpage is a giant string.HTTP is a giant string over tcp. And you dont need all your complicated stuff if you dont like "giant strings".

There is already something called XSL that can transform structured data into anything else.You just choosed to ignore it in your rant.


Sounds similar to the Web Components which allows you to define insertion points in the templates.

http://www.w3.org/TR/2013/WD-components-intro-20130606/#inse...

http://webcomponents.org/


Have you looked at Apache Jelly[1]? This is a server side templating language in itself.

[1] http://commons.apache.org/proper/commons-jelly/


There is either Lift (for Scala) or AngularJs - both might be something of what you are looking for.


Try Yesod.


> “Nunjucks has allowed us to port all of our existing templates from a Django project to something that's easier to manage.

why is it easier to manage?


Looks exactly like swig. Only the async operations are new.

http://paularmstrong.github.io/swig/


That's because both are Jinja reimplementations (given the name, I expect Swig is a JS version of Twig[0], itself a PHP implementation of Jinja, and originaly started by Armin Ronacher — Jinja's author[1][2])

[0] http://twig.sensiolabs.org

[1] https://github.com/mitsuhiko/twig

[2] http://fabien.potencier.org/article/34/templating-engines-in...


Yes I figured that out. I just don't understand why this has to exist. It's adding nothing noteworthy and very likely not faster either.

By the example of async which initiates value lookups... it can only be slower and promotes the bad habbit of putting too much logic into views.


It would be interesting if the templating languages stopped being "for X programming language".

I'd like to see a sane templating language that is based on a spec and it could be supported under different programming languages.


Mustache and Handlebars are pretty much that. They are available in most programming languages.


> that is based on a spec

No,because your spec wouldnt suit everybody and you'll end up with 20 other specs. That's why there is not just 1 programming languages.Because silver bullets dont exist.


There's no problem with 20 other specs.

I didn't mean spec as in a universal standard.

I meant a language that defines its syntax and functionality as a spec so it can be implemented in the same way in many languages so you can pick your favourite flavour and use it in as many languages as you want without surprises.

So given the template 'T' and template context 'C', you could always produce the exact same output regardless of whether you used javascript or python (assuming the libraries implemented the language based on the spec).

The spec doesn't mean it has to be a silver bullet, it will be a single bullet and there will be many bullets, but whatever bullet you pick, you can use it in more places.


On the surface, this looks very similar to Twig, a PHP template engine also inspired by Jinja.

http://twig.sensiolabs.org/doc/templates.html


Is this string templating? I can't find anything about that on the site. (I'm guessing it is, if it can run on the server and the client.)


This reminds me a lot of the template language in Django.


They make no secret of it essentially being a JS implementation of Jinja

> Rich Powerful language with block inheritance, autoescaping, macros, asynchronous control, and more. Heavily inspired by jinja2

And Jinja is an extended reimplementation of Django's template language.


Jinja is a reimplementation of the Djano language (but improved). This is it's JS port. It's a spiritual successor to Django, ported to JavaScript.


This is its JS port.


It's inspired by Jinja (Python) so, yeah.


Another "ninja" name, pushing programming toward stereotypically "dude/violent" interests for no reason.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: