summaryrefslogtreecommitdiff
path: root/sphinx/util/template.py
diff options
context:
space:
mode:
authorTakeshi KOMIYA <i.tkomiya@gmail.com>2020-04-23 01:19:47 +0900
committerTakeshi KOMIYA <i.tkomiya@gmail.com>2020-04-23 02:00:48 +0900
commitb15e3f6639f47d5885a31a65e9d56bf8ce9f4568 (patch)
tree22053de68c0e5bd0c45b1940694f85d0cecc38ff /sphinx/util/template.py
parentfd0a55223f43435bbc72fa80b17d3cd926156dec (diff)
downloadsphinx-git-b15e3f6639f47d5885a31a65e9d56bf8ce9f4568.tar.gz
Fix #7535: sphinx-autogen: crashes when custom template uses inheritance
Diffstat (limited to 'sphinx/util/template.py')
-rw-r--r--sphinx/util/template.py38
1 files changed, 37 insertions, 1 deletions
diff --git a/sphinx/util/template.py b/sphinx/util/template.py
index 1337f407c..2449a60a1 100644
--- a/sphinx/util/template.py
+++ b/sphinx/util/template.py
@@ -10,8 +10,11 @@
import os
from functools import partial
-from typing import Dict, List, Union
+from os import path
+from typing import Callable, Dict, List, Tuple, Union
+from jinja2 import TemplateNotFound
+from jinja2.environment import Environment
from jinja2.loaders import BaseLoader
from jinja2.sandbox import SandboxedEnvironment
@@ -94,3 +97,36 @@ class ReSTRenderer(SphinxRenderer):
self.env.filters['e'] = rst.escape
self.env.filters['escape'] = rst.escape
self.env.filters['heading'] = rst.heading
+
+
+class SphinxTemplateLoader(BaseLoader):
+ """A loader supporting template inheritance"""
+
+ def __init__(self, confdir: str, templates_paths: List[str],
+ system_templates_paths: List[str]) -> None:
+ self.loaders = []
+ self.sysloaders = []
+
+ for templates_path in templates_paths:
+ loader = SphinxFileSystemLoader(path.join(confdir, templates_path))
+ self.loaders.append(loader)
+
+ for templates_path in system_templates_paths:
+ loader = SphinxFileSystemLoader(templates_path)
+ self.loaders.append(loader)
+ self.sysloaders.append(loader)
+
+ def get_source(self, environment: Environment, template: str) -> Tuple[str, str, Callable]:
+ if template.startswith('!'):
+ # search a template from ``system_templates_paths``
+ loaders = self.sysloaders
+ template = template[1:]
+ else:
+ loaders = self.loaders
+
+ for loader in loaders:
+ try:
+ return loader.get_source(environment, template)
+ except TemplateNotFound:
+ pass
+ raise TemplateNotFound(template)