Jinja2 - break macros out across multiple files

jinja2

Solution

You can use extends to inherit from existing macro files. If in 'A' you inherit from 'B' then import 'A' into a page you can call B's macros as if they are part of file 'A' without the extra imports in your page. As you requested it will appear to be the same file outwardly. This is how it's done:

{% extends 'macrosdir/file.html' %}

Problem

Given a lengthy number of Jinja2 macros in a file, let's call it `macros.html`. I would like to break that file up into a number of smaller files, but have it appear the same outwardly when I call it with an `import`. So for example, suppose I have macros.html ``` {% macro A_1() %} A_1 {% endmacro %} {% macro A_2() %} A_2 {% endmacro %} {% macro A_3() %} A_3 {% endmacro %} {% macro B_1() %} B_1 {% endmacro %} {% macro B_1() %} B_1 {% endmacro %} ``` Elsewhere I import this with `import "macros.html" as macros`. I would like to break `macros.html` down into multiple files, such as `A.html` and `B.html` in this example, like this: A.html ``` {% macro A_1() %} A_1 {% endmacro %} {% macro A_2() %} A_2 {% endmacro %} {% macro A_3() %} A_3 {% endmacro %} ``` B.html ``` {% macro B_1() %} B_1 {% endmacro %} {% macro B_1() %} B_1 {% endmacro %} ``` However I would like the files that used `macros.html` to be able to still include it with the `import "macros.html" as macros`. I have tried a number of things, but they have not worked as expected. I typically get an error of `jinja2.environment.TemplateModule object has no attribute 'A_1'` when doing any of the following in `macros.html` ``` {% include "A.html" %} {# or #} {% from "A.html" import A_1 %} ``` The only option that seems to somewhat work is: ``` {% import "A.html" as XYZ %} {% set A_1 = XYZ.A_1 %} ``` Unfortunately in this case the macros in `A.html` cannot access global macros from the main file, which differs from the behaviour when the macros were included all in `macros.html`. In any case there is a lot of unnecessary repetition going on there, though, since I would be effectively importing anonymous module names for each file imported just to access and manually name each of its macro members. It seems like there should be a better option. One I have considered is writing my own file loader that loads and concatenates the glob of macros. Basically a pre-processor that creates "macros.html" from scratch.

Original source