Test Failed
Branch feature/user-customizations (24e3d3)
by Shalom
03:23
created

inji.engine.TemplateEngine.render()   A

Complexity

Conditions 2

Size

Total Lines 28
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 16
dl 0
loc 28
rs 9.6
c 0
b 0
f 0
cc 2
nop 3
1
#!/usr/bin/env python3
2
3
# -*- coding: utf-8 -*-
4
5
from jinja2 import DebugUndefined, StrictUndefined, Undefined, make_logging_undefined
6
from jinja2 import Environment, FileSystemLoader
7
from jinja2.exceptions import TemplateNotFound, UndefinedError
8
import sys
9
import logging
10
import inspect
11
12
from . import utils
13
from . import filters
14
from . import tests
15
from . import globals
16
17
def get_symbols(mod):
18
  return { k:v for k,v
19
            in inspect.getmembers(mod)
20
            if not (k.startswith('_')) }
21
22
class TemplateEngine(object):
23
24
  def __init__( self,
25
                undefined_variables_mode_behaviour='strict',
26
                j2_env_params={},
27
    ):
28
29
    m = undefined_variables_mode_behaviour
30
    if   m in ['strict', 'StrictUndefined']:
31
      Handler = StrictUndefined
32
    elif m in ['empty',  'Undefined']:
33
      Handler = Undefined
34
    elif m in ['keep',   'DebugUndefined']:
35
      Handler = DebugUndefined
36
37
    # Setup debug logging on STDERR to have the jinja2 engine emit
38
    # its activities
39
    root = logging.getLogger(__name__)
40
    root.setLevel(logging.DEBUG)
41
    handler = logging.StreamHandler(sys.stderr)
42
    handler.setFormatter(logging.Formatter('%(name)s %(levelname)s: %(message)s'))
43
    root.addHandler(handler)
44
45
    UndefinedHandler = make_logging_undefined( logger=root, base=Handler )
0 ignored issues
show
introduced by
The variable Handler does not seem to be defined for all execution paths.
Loading history...
46
47
    j2_env_params.setdefault('undefined', UndefinedHandler)
48
    j2_env_params.setdefault('trim_blocks', True)
49
    j2_env_params.setdefault('keep_trailing_newline', False)
50
    j2_env_params.setdefault('extensions', [
51
                            'jinja2.ext.i18n',
52
                            'jinja2.ext.do',
53
                            'jinja2.ext.loopcontrols',
54
                          ])
55
56
    self.j2_env_params = j2_env_params
57
58
    self.filters = get_symbols(filters)
59
    self.tests   = get_symbols(tests)
60
    self.globals = get_symbols(globals)
61
62
  def render(
63
      self,
64
      template,
65
      context
66
    ):
67
    """ Render the template """
68
69
    # We don't assume that includes and other sourceables reside relative
70
    # to the current directory but instead relative to the "master" template
71
    # we are processing. We deviate from jinja tradition this way.
72
    # This is because.
73
    # 1. We process template from stdin in temporary directories
74
    # 2. We should be free to change the process CWD and not break rendering
75
    rootdir = utils.dirname(template)
76
77
    self.j2_env_params.setdefault('loader', FileSystemLoader(rootdir))
78
    j2_env = Environment(**self.j2_env_params)
79
80
    j2_env.globals.update(self.globals)
81
    j2_env.filters.update(self.filters)
82
    j2_env.tests.update(self.tests)
83
84
    try:
85
      template = utils.basename(template)
86
      yield j2_env.get_template(template).render(context)
87
    except UndefinedError as e:
88
      raise UndefinedError( "variable {} in template '{}'".format(
89
              str(e), template) ) from e
90
91