3

I have the following project,

APP
|-static
  |-templates
    |-file.html
|-blueprints
  |-blueprint1.py
  |-blueprint2.py
|-app.py

Each blueprint file has various sanic routes that I want to render a template when called.

I have tried putting the following in each blueprint file,

template_env = Environment(
    loader=PackageLoader('APP', 'static/templates'),
    autoescape=select_autoescape(['html', 'xml'])
)

only to get the error ModuleNotFoundError: No module named 'APP'

Substituting APP with blueprintsgives me the error TypeError: expected str, bytes or os.PathLike object, not NoneType

I have also tried using a FileSystemLoader like this,

template_loader = FileSystemLoader(searchpath="../static/templates")
template_env = Environment(loader=template_loader)

and load the template I need template = template_env.get_template('file.html')

But I get a template not found when visiting the url.

Directly trying to render my template with,

with open('..static/templates/file.html') as file:
    template = Template(file.read())

again results in a file not found error.

What is the best way to use jinja templates in my app?

dearn44
  • 3,198
  • 4
  • 30
  • 63

2 Answers2

4

In this i created a project in witch i render a value to jinja template and it's work fine you can take a look at this i hope will be helpfull: this is the tree of the project :

.
├── app.py
└── static
    └── templates
        └── template.html

2 directories, 2 files

here is the template.html:

<html>
<header><title>This is title</title></header>
<body>
  <p>{{ value }}!</p>
</body>
</html>

here is the app.py :

#!/usr/bin/python
import jinja2
import os
path=os.path.join(os.path.dirname(__file__),'./static/templates')
templateLoader = jinja2.FileSystemLoader(searchpath=path)
templateEnv = jinja2.Environment(loader=templateLoader)
TEMPLATE_FILE = "template.html"
hello="hello..... "
template = templateEnv.get_template(TEMPLATE_FILE)
outputText = template.render(value=hello)  # this is where to put args to the template renderer
print(outputText)

output:

<html>
<header><title>This is title</title></header>
<body>
</body>
</html>
@gh-laptop:~/jinja$ python app.py 
<html>
<header><title>This is title</title></header>
<body>
  <p>hello..... !</p>
</body>
</html>
Ghassen
  • 764
  • 6
  • 14
1

To explain simply how PackageLoader works : The template folder defined (second parameter: package_path) should be relative to the folder containing the module visible from python (first parameter: package_name).

So as APP is not a module, you should use app instead. As the template folder will be relative to APP (the folder containing app) then the package_path is good.

gdoumenc
  • 589
  • 7
  • 10