1import os
2
3from .exceptions import PageNotFoundError
4from .pages import Page
5
6
7class PagesRegistry:
8 """
9 The registry loads up all the pages at once, so we only have to do a
10 dict key lookup at runtime to get a page.
11 """
12
13 def __init__(self):
14 # url path -> file path
15 self.registered_pages = {}
16
17 def register_page(self, url_path, relative_path, absolute_path):
18 self.registered_pages[url_path] = (url_path, relative_path, absolute_path)
19
20 def url_paths(self):
21 return self.registered_pages.keys()
22
23 def discover_pages(self, pages_dir):
24 for root, dirs, files in os.walk(pages_dir):
25 for file in files:
26 relative_path = os.path.relpath(os.path.join(root, file), pages_dir)
27 url_path = os.path.splitext(relative_path)[0]
28 absolute_path = os.path.join(root, file)
29
30 if os.path.basename(url_path) == "index":
31 url_path = os.path.dirname(url_path)
32
33 self.register_page(url_path, relative_path, absolute_path)
34
35 def get_page(self, url_path):
36 try:
37 url_path, relative_path, absolute_path = self.registered_pages[url_path]
38 # Instantiate the page here, so we don't store a ton of cached data over time
39 # as we render all the pages
40 return Page(url_path, relative_path, absolute_path)
41 except KeyError:
42 raise PageNotFoundError(f"Could not find a page for {url_path}")
43
44
45registry = PagesRegistry()