10

I am trying to create a html template in python using Jinja2. I have a templates folder with my 'template.html' but I don't know how to deal with environments or package loaders.

I installed Jinja2 using easy_python and ran the following script.

from jinja2 import Environment, PackageLoader
env = Environment(loader=PackageLoader('yourapplication', 'templates'))
template = env.get_template('mytemplate.html')
print template.render()

I get the following error because I don't know how to define a package/module. Please help me I just want to create a simple template.

  File "log_manipulationLL.py", line 291, in <module>
env = Environment(loader=PackageLoader('yourapplication', 'templates'))
 File "/usr/local/lib/python2.7/dist-packages/Jinja2-2.6-py2.7.egg/jinja2/loaders.py",    line 216, in __init__
provider = get_provider(package_name)
File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 213, in get_provider
__import__(moduleOrReq)
ImportError: No module named yourapplication
luisfer
  • 125
  • 2
  • 10

5 Answers5

13

If you don't want or need a Python package, you probably should use a FileSystemLoader instead, like this:

from jinja2 import Environment, FileSystemLoader, select_autoescape
env = Environment(
    loader=FileSystemLoader('file/path/'),
    autoescape=select_autoescape(['html', 'xml']),
)
Flimm
  • 136,138
  • 45
  • 251
  • 267
9

PackageLoader expects an actual Python module using the regular dot syntax. For example if your structure looks like this:

myapp/
  __init__.py
  …
  templates/
    mytemplate.html

You should use myapp as the module name.

patrys
  • 2,729
  • 17
  • 27
7

I solved this problem using the following code:

 env = Environment(loader=PackageLoader('scriptname', 
                                        templatesPath))

where this code is into the file scriptname.py.

I am not sure if my answer is relevant but I was wondering that perhaps someone may find this answer useful. If I am wrong please let me know.

Édouard Lopez
  • 40,270
  • 28
  • 126
  • 178
pafede2
  • 1,626
  • 4
  • 23
  • 40
  • 2
    Package loader calls `scriptname.py`. If you initialize the package loader in there, the code will be called a second time. – Henrik Jan 25 '17 at 13:04
  • 1
    You have to be careful - if you code isn't all in functions/classes, re-importing the same file can re-execute the code inside, resulting in double-template output! – mhansen May 17 '20 at 02:49
4

PackageLoader is defined like this:

class PackageLoader(BaseLoader):
    """Load templates from python eggs or packages.  It is constructed with
    the name of the python package and the path to the templates in that
    package::

        loader = PackageLoader('mypackage', 'views')

    If the package path is not given, ``'templates'`` is assumed.

    Per default the template encoding is ``'utf-8'`` which can be changed
    by setting the `encoding` parameter to something else.  Due to the nature
    of eggs it's only possible to reload templates if the package was loaded
    from the file system and not a zip file.
    """

And then the __init__() method is as follows:

def __init__(self, package_name, package_path='templates',
             encoding='utf-8'):

This makes us notice that a structure like this:

myapp/
  __init__.py
  ...
  templates/
    mytemplate.html

Will have the same PackageLoader instance with both of these declarations:

PackageLoader('myapp')
PackageLoader('myapp', 'templates')

And so if you are running from the myapp/ path, you then just need to say:

PackageLoader('templates', '')

So that it will just take templates/ as the path. If you leave the 2nd argument empty, it will try to find the templates in templates/templates.

Finally, you can check what has been loaded by using the list_templates() method:

PackageLoader('templates', '').list_templates()
fedorqui
  • 275,237
  • 103
  • 548
  • 598
0

I had multiple templates and jinja2 documentation is not well documented. You can actually use the FileSystemLoader from jinja2

from jinja2 import Environment, FileSystemLoader

# Declare the environment
templateLoader = FileSystemLoader(searchpath="./templates")
env = Environment(loader=templateLoader)


# Generate the HTML template base on the template name
template = env.get_template(f'{template}.html')

# And then use it to render your templates
html = template.render( ) # Your args goes here

Credits: This Answer

MANAN
  • 713
  • 9
  • 6