Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jinja2 load templates from separate location than working directory

Tags:

jinja2

I have a module that handles creating and executing SQL queries by using Jinja2 to render templates. The module itself and a directory called 'templates' are located on a network drive that I can access from multiple machines on the network.

Everything works when I work from inside the same directory, as expected.

When I try to load and use this module from a separate location, I get a TemplateNotFound: error. The function itself looks like this, with the line containing the error highlighted:

from jinja2 import Environment, FileSystemLoader, Template, meta

def get_sql_query(position):
    filename = "PositionDelta.sqltemplate"

    # Create Jinja2 Environment, using the 'templates' folder
    env = Environment(loader=FileSystemLoader('templates')) # Error!
    template = env.get_template(filename)

    # Get source of template file
    template_source = env.loader.get_source(env, filename)[0]

    # Parse template source and get all undeclared variables
    parsed_content = env.parse(template_source)
    template_variables = list(meta.find_undeclared_variables(parsed_content))

    # Get all tag values associated with position
    tag_values = get_tags_list(position)

    # Combine template variables and tag values into dictionary and render sql query from template
    dictionary = dict(zip(template_variables, tag_values))
    sql_query = template.render(dictionary)

    return sql_query

This function that is failing is the following line:

env = Environment(loader=FileSystemLoader('templates'))

I think when I call the FileSystemLoader function, it's searching for the template folder relative to the working folder. How can I set it to look for the template directory relative to the module location itself?

like image 407
cbcoutinho Avatar asked Jun 22 '16 12:06

cbcoutinho


2 Answers

This works for me:

from jinja2 import Environment, FileSystemLoader
template_dir = '/home/colin/template_dir'
env = Environment(loader=FileSystemLoader(template_dir))

My guess is that as your path doesn't start with a forward slash its loading relative to your application. Try using the full path to the template directory.

like image 93
wobbily_col Avatar answered Sep 26 '22 13:09

wobbily_col


In the end, the method that I was looking for required that I create my module(s) into a package. I decided to use Jinja2's package loader method because it looks for the template files relative to the package itself, rather than relative to the working directory:

import jinja2

templateEnv = jinja2.Environment( loader=jinja2.PackageLoader('package_name', 'templates'))
template = templateEnv.get_template( 'template_filename' )
template.render({'var1':var1, 'var2':var2})
like image 20
cbcoutinho Avatar answered Sep 26 '22 13:09

cbcoutinho