Plain is headed towards 1.0! Subscribe for development updates →

 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()