Objective
I would like to use Jinja's {% include RELATIVE_PATH %} statement to include small fragments of content in my template file(s), without installing the included fragments in the expanded template.
I could do this by storing the included elements outside the template_dir, in a sibling directory. This is how cookiecutter.json and the hooks/ directory work. This seems like a good and natural way to maintain content that supports the template but is not part of the template.
Problem
Presently cookiecutter creates a FileSystemLoader based in the template (ex, {{ cookiecutter.root_dir }}) directory thusly:
with work_in(template_dir):
env.loader = FileSystemLoader('.')
This sets the CWD to the template_dir and creates the Loader with a search path of just that directory (and children).
Unfortunately, Jinja hard-codes a specific exclusion against using .. in relative paths, for security reasons. If you try to {% include '../foo' %} Jinja raises a TemplateNotFound exception.
So in order to be able to search the directories outside the template_dir for content, they must be somehow added to the search path when the loader is created.
Proposed solution
When creating the FileSystemLoader, provide a search path that also includes the repository root directory. I found that ['.', '..'] works as a dumb proof-of-concept.
Testing
I don't expect this to cause failures in other test cases, since this apparently represents new functionality. It's possible that someone could be using include against a directory below the template_dir, but that would be a test of Jinja's path handling, which is IMO a Jinja test until and unless they fail to get it right.
The two major statements that are impacted by this would be Jinja's include and import. Test cases should include one or both statements, and confirm text and possibly macros are visible.
Objective
I would like to use Jinja's
{% include RELATIVE_PATH %}statement to include small fragments of content in my template file(s), without installing the included fragments in the expanded template.I could do this by storing the included elements outside the
template_dir, in a sibling directory. This is howcookiecutter.jsonand thehooks/directory work. This seems like a good and natural way to maintain content that supports the template but is not part of the template.Problem
Presently
cookiecuttercreates aFileSystemLoaderbased in the template (ex,{{ cookiecutter.root_dir }}) directory thusly:This sets the CWD to the
template_dirand creates the Loader with a search path of just that directory (and children).Unfortunately, Jinja hard-codes a specific exclusion against using
..in relative paths, for security reasons. If you try to{% include '../foo' %}Jinja raises aTemplateNotFoundexception.So in order to be able to search the directories outside the
template_dirfor content, they must be somehow added to the search path when the loader is created.Proposed solution
When creating the
FileSystemLoader, provide a search path that also includes the repository root directory. I found that['.', '..']works as a dumb proof-of-concept.Testing
I don't expect this to cause failures in other test cases, since this apparently represents new functionality. It's possible that someone could be using
includeagainst a directory below thetemplate_dir, but that would be a test of Jinja's path handling, which is IMO a Jinja test until and unless they fail to get it right.The two major statements that are impacted by this would be Jinja's
includeandimport. Test cases should include one or both statements, and confirm text and possibly macros are visible.