ninjadog: pug + jinja2 == ❤️¶

ninjadog¶
Pug template (formerly jade) support in Python
- Free software: MIT license
- Documentation: http://journalpanic.com/ninjadog
- GitHub: https://github.com/knowsuchagency/ninjadog
Installation¶
ninjadog requires Python 3, node-js, npm, and the pug-cli library
brew install npm
npm install -g pug-cli
pip install ninjadog
For use with Pyramid, just add it to the configuration
config.include('ninjadog')
Usage¶
ninjadog leverages the pug-cli library, written in nodejs, to render pug templates in Python.
It allows you to take something like this
html
head
title my pug template
body
#content
h1 Hello #{name}
.block
input#bar.foo1.foo2
input(type="text", placeholder="your name")
if name == "Bob"
h2 Hello Bob
ul
for book in books
li= book
else
li sorry, no books
and sprinkle some Python over it
from ninjadog import render
context = {
'name': 'Bob',
'books': ['coloring book', 'audio book', "O'Reilly book"],
'type': 'text',
}
print(render(file=filepath, context=context, pretty=True))
to render this
<!DOCTYPE html>
<html>
<head>
<title>my pug template</title>
</head>
<body>
<div id="content">
<h1>Hello Bob</h1>
<div class="block">
<input class="foo1 foo2" id="bar">
<input type="text" placeholder="your name">
<h2>Hello Bob</h2>
<ul>
<li>coloring book</li>
<li>audio book</li>
<li>O'Reilly book</li>
</ul>
</div>
</div>
</body>
</html>
You can even combine jinja2 syntax for unparalleled template-rendering power.
from ninjadog import render
def stop_believing():
return False
context = {
'stop_believing': stop_believing,
'happy': {
'birthday': 'today',
}
}
template_string = """
h1 hello, world
if happy.birthday == 'today'
p it's time to celebrate!
p {{ "Don't" if not stop_believing() }} stop believing
"""
print(render(template_string,
context=context,
pretty=True,
with_jinja=True))
<h1>hello, world</h1>
<p>it's time to celebrate!</p>
<p>Don't stop believing</p>
Why?¶
Pug templates are a super elegant and expressive way to write html, IMO.
There exists a project, pyjade and a less-popular fork, pypugjs, that are pure-python implementations of the pug template engine, but they have some bugs and the maintenance is a bit lacking.
It made more sense to me to use the existing nodejs implementation, and find a way to have it play nicely with Python.
ninjadog does this by spawning the pug cli as a subprocess. This means that it can’t be as fast as a native template engine like pyjade, but it will be more reliable as it’s leveraging the popular and well-maintained nodejs implementation.
Command Line Interface¶
ninjadog v0.4.1
Render pug templates to html.
Usage:
ninjadog string [options] <string>
ninjadog file [options] <file>
ninjadog dir [options] <source> [<destination>]
ninjadog - [options]
ninjadog -h | --help
ninjadog -V | --version
Options:
-h --help show help and exit
-V --version show version and exit
-f --file <file> the filepath to the template
-p --pretty pretty print output
-c --context <context> json string to be passed as context
-j --with-jinja render jinja2 syntax as well as pug
-v --verbose verbose output
-n --dry-run verbose output and exit without executing
<destination> destination directory to render pug files to
Strings may be passed via pipe using `-` argument.
i.e.
echo 'h1 hello {{ name }}' | ninjadog - -j -c '{"name": "Sam"}'
outputs
<h1>hello Sam</h1>
Pyramid¶
You can avoid having to render each template anew with every HTTP request.
In your Pyramid configuration, you can have ninjadog cache templates by setting
the ninjadog.cache
option to true like so
[app:main]
ninjadog.cache = true
Configurator(settings={'ninjadog.cache': True})
# ...
… however you like to configure your app.
While this will make each page load much faster after the first visit, IT ALSO MEANS YOU CANNOT HAVE ANY MUTABLE STATE IN YOUR TEMPLATE as the template itself will only be rendered once.
It may be best to prototype by using ninjadog as normal - mutable state, conditionals, mixins… whatever - but to set the aformentioned option to true and move any logic dealing with mutable state into javascript for production. The choice yours.