Source code for ninjadog.ninjadog
# -*- coding: utf-8 -*-
"""Main module."""
import json
import shlex
import subprocess as sp
import typing as T
from pathlib import Path
from jinja2 import Environment
from ninjadog.constants import PUG_CLI_PATH
from ninjadog.utils import jsonify
[docs]def render(string: str = '',
file: T.Union[Path, str] = None,
context: T.Any = None,
pretty: bool = False,
pug_cli_path: str = None,
with_jinja: bool = False) -> str:
"""
Render a pug template through the pug cli.
Args:
string: a string in pug syntax to be rendered
file: the path to a pug template
context: the data to be passed to the template
pretty: pretty html output
pug_cli_path: path to the pug cli
with_jinja: render jinja2 template syntax as well
Returns: rendered html
"""
if pug_cli_path is None and PUG_CLI_PATH is None:
msg = "the pug command was not found. Did you install it?\n" \
"brew install npm\n" \
"npm install -g pug-cli"
raise ValueError(msg)
elif pug_cli_path is None:
pug_cli_path = PUG_CLI_PATH
# create Path object if file argument is given
# Path() is idempotent so this shouldn't make any difference
# if the file argument is of type Path
filepath = Path(str(file)) if file is not None else file
# if filepath is given instead of a string argument,
# return render of string
if filepath and not string:
with filepath.open() as fp:
return render(fp.read(),
filepath,
context=context,
pretty=pretty,
pug_cli_path=pug_cli_path,
with_jinja=with_jinja,
)
cmd = shlex.quote(pug_cli_path)
path = '-p {}'.format(shlex.quote(str(filepath))) if filepath else ''
pretty_print = '-P' if pretty else ''
if context is None:
context_arg = ''
elif isinstance(context, str):
context_arg = '-O {}'.format(shlex.quote(context))
else:
context_arg = '-O {}'.format(shlex.quote(jsonify(context)))
# jinja templates require pre and post-processing
if with_jinja:
env = Environment()
env.globals = context
if isinstance(context, str):
context = json.loads(context)
string = env.from_string(string).render()
pug_cli = sp.Popen(shlex.split('{} {} {} {}'.format(cmd, context_arg, path, pretty_print)),
stdin=sp.PIPE,
stdout=sp.PIPE,
cwd=str(filepath.parent) if filepath else None,
universal_newlines=True,
)
html, _ = pug_cli.communicate(string)
return html if not with_jinja else env.from_string(html).render()