Description
In my local python/module.rst
I only need to override one block of the default template.
{% extends "python/module.rst" %}
{% block functions scoped %}
{% endblock %}
That fails, somewhat expectedly, with an RecursionError. My idea for a workaround was to inject a custom filter to make the path for the extend
absolute.
def _autoapi_prepare_jinja_env(jinja_env):
jinja_env.filters["base_template"] = lambda value: f'{autoapi.settings.TEMPLATE_DIR}/{value}'
autoapi_prepare_jinja_env = _autoapi_prepare_jinja_env
and then make the child template
{% extends "python/module.rst" | base_template %}
{% block functions scoped %}
{% endblock %}
That however fails since jinja's FileSystemLoader
(or Environment
?) always appends given paths as relative to its preset basedir(s). So then I hacked the jinja env further, including a new loader that has the filesystem root as the last search path.
autoapi_template_dir = '/my/local/template_dir'
def _autoapi_prepare_jinja_env(jinja_env):
import jinja2
tpl_dir = autoapi.settings.TEMPLATE_DIR
jinja_env = jinja_env.overlay(loader=jinja2.FileSystemLoader([tpl_dir, autoapi_template_dir, '/']))
jinja_env.filters["base_template"] = lambda value: f'{tpl_dir}/{value}'
Jinja still doesn't find the base template with the absolute path though, so I used a custom loader. Also the overlay
doesn't actually use MyLoader
.
autoapi_template_dir = this_dir / '_templates' / 'autoapi'
import jinja2
from os.path import join, exists, getmtime
class MyLoader(jinja2.FileSystemLoader):
def get_source(self, environment, template):
try:
return super().get_source(environment, template)
except jinja2.TemplateNotFound:
path = template
print(f"LOAD {template}")
mtime = getmtime(template)
with file(template) as f:
source = f.read().decode('utf-8')
return source, template, lambda: mtime == getmtime(template)
def _autoapi_prepare_jinja_env(jinja_env):
tpl_dir = autoapi.settings.TEMPLATE_DIR
jinja_env.filters["base_template"] = lambda value: f'{tpl_dir}/{value}'
jinja_env.loader = MyLoader([tpl_dir, autoapi_template_dir])
This "works" as in I get no error.
Problem is AFAICT my custom get_source
is only called once. For index.rst
.
So bottom line I'm looking for either the problem with my workaround, or how I could generally make this workflow possible in autoapi, less hackish.