Reputation: 53
This is an elementary issue which is probably related to Jinja2 PrefixLoader or ChoiceLoader.
On Python 3.6 we load with this command
jinja2.FileSystemLoader( searchpath= "\\template_folder\\")
On Windows 7, our file structure is as follows.
- folder_bbb * subfile.txt - template_folder * template_file - folder_aaa * subfile.txt
From the template_file we are successful with this command
{% include "folder_aaa/subfile.txt" %}
Now we wish to move the file one level up, and write
{% include "../folder_bbb/subfile.txt" %}
but that doesn't work, complaining file not found.
What is the correct way to write? Thanks.
Upvotes: 5
Views: 5489
Reputation: 11
I had this exact issue and spent a whole day going crazy over it before realizing that Jinja2’s FileSystemLoader sets the root directory based on the template being loaded.
When you define FileSystemLoader(searchpath="\\template_folder\\")
, template_folder becomes the root directory for all templates. This means:
{% include "folder_aaa/subfile.txt" %}
works because "folder_aaa" is inside "template_folder".
{% include "../folder_bbb/subfile.txt" %}
does not work because folder_bbb is outside of template_folder, and FileSystemLoader can’t navigate upwards in the filesystem.
If you have control over the loader, you can specify multiple search paths so that both template_folder and folder_bbb are included:
jinja2.FileSystemLoader(["c:\\template_folder\\", "c:\\folder_bbb\\"])
Now, you can just do:
{% include "subfile.txt" %}
and Jinja2 will search for the file in both directories.
Then you’re stuck with relative paths inside the root directory, meaning you can only include files downwards.
In my case (while working with Ansible), the solution was to move the template I was loading to the highest level (template_folder). That way, I could reference included templates using downward relative paths instead of trying to include files from a parent directory.
Upvotes: 0
Reputation: 123
You may specify all paths in the the loader
jinja2.FileSystemLoader(["c:\\template_folder\\", "c:\\folder_bbb\\"])
and refer the including block without a specific path
{% include "subfile.txt" %}
The path will be searched in order so that as you say, moving the file one level up, the file will be found. (You need the template_folder path for the template itself.)
Upvotes: 5