from pathlib import Path from shutil import copy from typing import Any from jinja2.environment import Environment from jinja2.loaders import FileSystemLoader from jwebsite.content import ContentDirectory class Site: def __init__(self, root_directory: Path) -> None: self.__root_directory = root_directory self.__output_directory = root_directory / "build" self.__environment = Environment(loader=FileSystemLoader(searchpath=root_directory / "src")) self.__environment.filters.update({"output": self.__output}) self.__content = ContentDirectory(root_directory / "content") @property def content(self) -> ContentDirectory: return self.__content def render(self, source: str, output: str | Path, **context: Any) -> None: self.__output_directory.mkdir(parents=True, exist_ok=True) template = self.__environment.get_template(source) content = template.render(site=self, **context) output_path = self.__output_directory / output with open(output_path, "w") as output_file: output_file.write(content) def __output(self, path: str | Path) -> str: path = Path(path) if path.is_absolute(): src_path = path relative_src_path = src_path.relative_to(self.__content.path) else: src_path = self.__content.path / path relative_src_path = path dst_path = self.__output_directory / relative_src_path dst_path.parent.mkdir(parents=True, exist_ok=True) copy(src_path, dst_path, follow_symlinks=True) return f"/{relative_src_path}"