Skip to content

Commit c7e09b4

Browse files
Merge pull request #1 from encode/templates
Add `Template` class.
2 parents 5be49e2 + 6c7c420 commit c7e09b4

1 file changed

Lines changed: 47 additions & 39 deletions

File tree

src/mkdocs/mkdocs.py

Lines changed: 47 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,6 @@ def load_paths(self) -> list[pathlib.Path]:
4949
"""
5050
return []
5151

52-
def load_templates(self) -> jinja2.BaseLoader | None:
53-
"""
54-
Optionally return a jinja2 loader that this handler provides.
55-
"""
56-
return None
57-
5852
def read(self, path: pathlib.Path) -> bytes:
5953
"""
6054
Load the resource content given it's path.
@@ -73,19 +67,14 @@ class Directory(Handler):
7367
def __init__(self, dir: pathlib.Path | None = None) -> None:
7468
self._dir = pathlib.Path.cwd() if dir is None else pathlib.Path(dir)
7569
self._dir_repr = '[CWD]' if dir is None else f"{dir!r}"
76-
self._template_dir = 'templates'
7770

7871
def load_paths(self) -> list[pathlib.Path]:
7972
return sorted([
8073
f.relative_to(self._dir)
8174
for f in self._dir.rglob("[!.]*")
82-
if f.is_file() and not f.parts[0] == self._template_dir
75+
if f.is_file()
8376
])
8477

85-
def load_templates(self) -> jinja2.BaseLoader | None:
86-
t = self._dir.joinpath(self._template_dir)
87-
return jinja2.FileSystemLoader(t) if t.exists() and t.is_dir() else None
88-
8978
def read(self, path: pathlib.Path) -> bytes:
9079
return self._dir.joinpath(path).read_bytes()
9180

@@ -104,7 +93,6 @@ class Package(Handler):
10493
def __init__(self, pkg: str = 'mkdocs') -> None:
10594
self._pkg = pkg
10695
self._files = importlib.resources.files(pkg).joinpath('theme')
107-
self._templates = importlib.resources.files(pkg).joinpath('theme', 'templates')
10896

10997
def _load_paths(self, subdir: str) -> list[pathlib.Path]:
11098
files = []
@@ -119,14 +107,7 @@ def _load_paths(self, subdir: str) -> list[pathlib.Path]:
119107
return files
120108

121109
def load_paths(self) -> list[pathlib.Path]:
122-
return sorted([
123-
p for p in self._load_paths(subdir='')
124-
if not p.parts[0] == 'templates'
125-
])
126-
127-
def load_templates(self) -> jinja2.BaseLoader | None:
128-
exists = self._templates.exists() and self._templates.is_dir()
129-
return jinja2.PackageLoader(self._pkg, 'theme/templates') if exists else None
110+
return sorted(self._load_paths(subdir=''))
130111

131112
def read(self, path: pathlib.Path) -> bytes:
132113
return self._files.joinpath(path).read_bytes()
@@ -138,6 +119,8 @@ def __repr__(self):
138119
return f'<Package {self._pkg!r}>'
139120

140121

122+
# Resources & Templates...
123+
141124
class Resource:
142125
def __init__(self, path: pathlib.Path, url: str, handler: Handler) -> None:
143126
self.path = path
@@ -157,6 +140,31 @@ def __repr__(self) -> str:
157140
return f'<Resource {self.url!r} {self.path.as_posix()!r} [{self.handler.name()}]>'
158141

159142

143+
class Template:
144+
def __init__(self, name: str, path: pathlib.Path, handler: Handler) -> None:
145+
self.name = name
146+
self.path = path
147+
self.handler = handler
148+
149+
def read(self) -> bytes:
150+
return self.handler.read(self.path)
151+
152+
def __repr__(self) -> str:
153+
return f'<Template {self.path.as_posix()!r} [{self.handler.name()}]>'
154+
155+
156+
class TemplateLoader(jinja2.BaseLoader):
157+
def __init__(self, templates: list[Template]):
158+
self.templates = templates
159+
160+
def get_source(self, environment, template: str):
161+
for t in self.templates:
162+
if t.name == template:
163+
source = t.read().decode('utf-8')
164+
return source, t.path, None
165+
raise jinja2.TemplateNotFound(template)
166+
167+
160168
class MkDocs:
161169
def __init__(self):
162170
self.content_types = {
@@ -255,21 +263,21 @@ def load_handlers(self, config: dict) -> list[Handler]:
255263
Directory('docs'),
256264
]
257265

258-
def load_resources(self, handlers: list[Handler]) -> list[Resource]:
266+
def load_resources(self, handlers: list[Handler]) -> tuple[list[Resource], list[Template]]:
259267
resources = {}
268+
templates = {}
260269
for handler in handlers:
261270
for path in handler.load_paths():
262-
url = self.path_to_url(path)
263-
resources[path] = Resource(path, url, handler)
264-
return list(resources.values())
265-
266-
def load_env(self, handlers: list[Handler]) -> jinja2.Environment:
267-
loaders: list[jinja2.BaseLoader] = []
268-
for handler in reversed(handlers):
269-
t = handler.load_templates()
270-
if t is not None:
271-
loaders.append(t)
272-
loader = jinja2.ChoiceLoader(loaders)
271+
if path.parts[0] == 'templates':
272+
name = str(pathlib.Path(*path.parts[1:]))
273+
templates[path] = Template(name, path, handler)
274+
else:
275+
url = self.path_to_url(path)
276+
resources[path] = Resource(path, url, handler)
277+
return (list(resources.values()), list(templates.values()))
278+
279+
def load_env(self, templates: list[Template]) -> jinja2.Environment:
280+
loader = TemplateLoader(templates)
273281
return jinja2.Environment(loader=loader, auto_reload=True)
274282

275283
def load_md(self, config) -> markdown.Markdown:
@@ -313,11 +321,11 @@ def build(self):
313321
"""
314322
config = self.load_config('mkdocs.toml')
315323
handlers = self.load_handlers(config)
316-
resources = self.load_resources(handlers)
317-
env = self.load_env(config)
324+
resources, templates = self.load_resources(handlers)
325+
env = self.load_env(templates)
318326
md = self.load_md(config)
319-
buildpath = pathlib.Path('site')
320327

328+
buildpath = pathlib.Path('site')
321329
for resource in resources:
322330
output = self.render(resource, resources, config, env, md)
323331
build_path = buildpath.joinpath(resource.output_path)
@@ -331,11 +339,11 @@ def serve(self):
331339
"""
332340
config = self.load_config('mkdocs.toml')
333341
handlers = self.load_handlers(config)
334-
resources = self.load_resources(handlers)
335-
env = self.load_env(handlers)
342+
resources, templates = self.load_resources(handlers)
343+
env = self.load_env(templates)
336344
md = self.load_md(config)
337-
urls = {resource.url: resource for resource in resources}
338345

346+
urls = {resource.url: resource for resource in resources}
339347
def app(request):
340348
path = request.url.path
341349
resource = urls.get(path)

0 commit comments

Comments
 (0)