Skip to content

Enable Jinja %include% statements for out-of-template content #1495

@aghast

Description

@aghast

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions