@@ -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+
141124class 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+
160168class 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