diff --git a/omicron/ssg/site.py b/omicron/ssg/site.py index 78cabd6..0d173b3 100644 --- a/omicron/ssg/site.py +++ b/omicron/ssg/site.py @@ -4,8 +4,10 @@ from urllib.parse import urlparse from omicron.ssg.output import ( Output, + OutputError, Content, ContentError, + Directory, is_content, create_content, File, @@ -32,6 +34,7 @@ class Site: def __init__(self, site: Path): self.site_path = site.absolute() self.content: list[Content] = [] + self.directories: list[Directory] = [] self.other_outputs: list[Output] = [] self.by_tag: dict[str, list[Content]] = {} self.by_path: dict[Path, Output] = {} @@ -98,7 +101,23 @@ class Site: raise ContentError( f"path '{output.destination}' is already claimed by another output" ) + new_dirs: list[Directory] = [] + for parent in output.destination.parents: + if parent == Path("."): + break + if parent in self.by_path: + if not isinstance(self.by_path[parent], Directory): + raise OutputError( + f"path '{parent}' is claimed by a file but needed as a directory" + ) + break + new_dirs.append(Directory(self, parent)) self.by_path[output.destination] = output + if isinstance(output, Directory): + self.directories.append(output) + for d in new_dirs: + self.by_path[d.destination] = d + self.directories.append(d) def home_url(self) -> str: return self.base_dir or "/" @@ -163,8 +182,8 @@ class Site: if self.base_dir and not self.base_dir.startswith("/"): raise ConfigError("base_url config value must be an absolute path") self.discover() - self.output_path.mkdir(parents=True, exist_ok=True) - for content in self.content: - content.write() + outputs: list[Output] = [*self.directories, *self.content] + for output in sorted(outputs, key=lambda o: o.destination.as_posix()): + output.write() for output in self.other_outputs: output.write()