ninjadog: pug + jinj2 == ❤️

_images/yodawg.jpg

ninjadog

https://img.shields.io/pypi/v/ninjadog.svg https://img.shields.io/travis/knowsuchagency/ninjadog.svg Updates

Pug template (formerly jade) support in Python

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(filepath=file, 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.3.6

Render pug templates to html.

Usage:
    ninjadog string [options] <string>
    ninjadog file [options] <file>
    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


Strings may be passed via pipe using `-` argument.

i.e. 

echo 'h1 hello {{ name }}' | ninjadog - -j -c '{"name": "Sam"}'

outputs

<h1>hello Sam</h1>

Indices and tables