diff --git a/omicron/ssg/output/article.py b/omicron/ssg/output/article.py index 993a126..e97c35d 100644 --- a/omicron/ssg/output/article.py +++ b/omicron/ssg/output/article.py @@ -13,11 +13,11 @@ else: class Article(Content): - def __init__(self, path: Path, meta: dict[str, Any]): + def __init__(self, source: Path, meta: dict[str, Any]): if "tags" not in meta: - log.warning("no tags for article in '%s'", path) + log.warning("no tags for article in '%s'", source) super().__init__( - path, + source, meta["section"], meta["slug"], meta["date"], @@ -35,7 +35,7 @@ class Article(Content): template = site.jinja_env.get_template("article.html") html = template.render(article=self, content=content, site=site) - out_path = site.output_path / self.uri + out_path = site.output_path / self.destination out_path.parent.mkdir(parents=True, exist_ok=True) out_path.write_text(html, encoding="utf-8") log.debug("Rendered %s -> %s", self.source, out_path) diff --git a/omicron/ssg/output/content.py b/omicron/ssg/output/content.py index f880d58..6de01da 100644 --- a/omicron/ssg/output/content.py +++ b/omicron/ssg/output/content.py @@ -13,7 +13,7 @@ class Content(Output): def __init__( self, - path: Path, + source: Path, section: str, slug: str, created: date, @@ -21,10 +21,10 @@ class Content(Output): tags: set[str] | None = None, summary: str | None = None, ): - super().__init__(Content.build_uri(section, slug)) + super().__init__(Content.build_path(section, slug)) if tags is None: tags = set() - self.source = path + self.source = source self.section: str = section self.created = created self.updated = updated @@ -32,11 +32,11 @@ class Content(Output): self.summary: str | None = summary @staticmethod - def build_uri(section: str, slug: str) -> str: + def build_path(section: str, slug: str) -> Path: if not Content._SECTION_RE.match(section): raise ContentError(f"Invalid section '{section}'") - uri = f"{section}/{slug}.html" - return uri + path = Path(f"{section}/{slug}.html") + return path def read_body(self) -> str: with self.source.open("r", encoding="utf-8") as f: diff --git a/omicron/ssg/output/file.py b/omicron/ssg/output/file.py index 763ca84..e470dad 100644 --- a/omicron/ssg/output/file.py +++ b/omicron/ssg/output/file.py @@ -13,12 +13,12 @@ else: class File(Output): - def __init__(self, uri: str, source: Path): - super().__init__(uri) + def __init__(self, path: Path, source: Path): + super().__init__(path) self.source = source def write(self, site: Site) -> None: - dest = site.output_path / self.uri + dest = site.output_path / self.destination dest.parent.mkdir(parents=True, exist_ok=True) shutil.copyfile(self.source, dest) log.debug("Copied %s -> %s", self.source, dest) diff --git a/omicron/ssg/output/index.py b/omicron/ssg/output/index.py index a169979..094c0ac 100644 --- a/omicron/ssg/output/index.py +++ b/omicron/ssg/output/index.py @@ -1,4 +1,5 @@ import logging +from pathlib import Path from math import ceil from itertools import batched from typing import TYPE_CHECKING, Literal @@ -22,7 +23,7 @@ class Index(Output): total_pages: int, label: str | None, ): - super().__init__(Index.build_uri(kind, page_num, label)) + super().__init__(Index.build_path(kind, page_num, label)) self.kind = kind self.items = items self.page_num = page_num @@ -30,25 +31,25 @@ class Index(Output): self.label = label @staticmethod - def build_uri( + def build_path( kind: Literal["root", "section", "tag"], page_num: int, label: str | None, - ) -> str: + ) -> Path: if page_num == 1: - file = "index.html" + file = Path("index.html") else: - file = f"page-{page_num}.html" + file = Path(f"page-{page_num}.html") if kind == "root": - uri = file + path = file elif kind == "section": assert label, "label can't be None if kind is not root" - uri = f"{label}/{file}" + path = Path(label) / file else: assert label, "label can't be None if kind is not root" - uri = f"tags/{label}/{file}" - return uri + path = Path("tags") / label / file + return path def write(self, site: Site) -> None: template = site.jinja_env.get_template("index.html") @@ -60,7 +61,7 @@ class Index(Output): kind=self.kind, label=self.label, ) - dest = site.output_path / self.uri + dest = site.output_path / self.destination dest.parent.mkdir(parents=True, exist_ok=True) dest.write_text(html, encoding="utf-8") log.debug("Wrote %s", dest) diff --git a/omicron/ssg/output/memory.py b/omicron/ssg/output/memory.py index b43e9ca..8d6f5c4 100644 --- a/omicron/ssg/output/memory.py +++ b/omicron/ssg/output/memory.py @@ -1,4 +1,5 @@ import logging +from pathlib import Path from typing import TYPE_CHECKING from omicron.ssg.output.output import Output @@ -11,12 +12,12 @@ else: class Memory(Output): - def __init__(self, uri: str, content: str): - super().__init__(uri) + def __init__(self, destination: Path, content: str): + super().__init__(destination) self.content = content def write(self, site: Site) -> None: - dest = site.output_path / self.uri + dest = site.output_path / self.destination dest.parent.mkdir(parents=True, exist_ok=True) dest.write_text(self.content, encoding="utf-8") log.debug("Wrote %s", dest) diff --git a/omicron/ssg/output/output.py b/omicron/ssg/output/output.py index 1256f70..2140104 100644 --- a/omicron/ssg/output/output.py +++ b/omicron/ssg/output/output.py @@ -1,5 +1,6 @@ from typing import TYPE_CHECKING from abc import ABC, abstractmethod +from pathlib import Path if TYPE_CHECKING: from omicron.ssg.site import Site # for static checking with mypy @@ -8,8 +9,13 @@ else: class Output(ABC): - def __init__(self, uri: str): - self.uri = uri + def __init__(self, destination: Path): + self.destination = destination + url = "/" + destination.as_posix() + url = url.removesuffix("/index.html") + if url == "": + url = "/" + self.url = url @abstractmethod def write(self, site: Site) -> None: diff --git a/omicron/ssg/output/tags.py b/omicron/ssg/output/tags.py index 806b3f0..5ac2f40 100644 --- a/omicron/ssg/output/tags.py +++ b/omicron/ssg/output/tags.py @@ -1,4 +1,5 @@ import logging +from pathlib import Path from typing import TYPE_CHECKING from omicron.ssg.output.output import Output @@ -12,13 +13,13 @@ else: class Tags(Output): def __init__(self, tags: list[tuple[str, int]]): - super().__init__("tags/index.html") + super().__init__(Path("tags/index.html")) self.tags = tags def write(self, site: Site) -> None: template = site.jinja_env.get_template("tags.html") html = template.render(site=site, tags=self.tags) - dest = site.output_path / self.uri + dest = site.output_path / self.destination dest.parent.mkdir(parents=True, exist_ok=True) dest.write_text(html, encoding="utf-8") log.debug("Wrote %s", dest) diff --git a/omicron/ssg/site.py b/omicron/ssg/site.py index 54e0745..d700494 100644 --- a/omicron/ssg/site.py +++ b/omicron/ssg/site.py @@ -32,7 +32,7 @@ class Site: self.content: list[Content] = [] self.other_outputs: list[Output] = [] self.by_tag: dict[str, list[Content]] = {} - self.by_uri: dict[str, Output] = {} + self.by_path: dict[Path, Output] = {} self.by_section: dict[str, list[Content]] = {} self.tags_by_count: list[tuple[str, int]] = [] @@ -40,7 +40,7 @@ class Site: self.name: str = config["name"] self.template: str = config["template"] self.items_per_page: int = int(config.get("items_per_page", 20)) - self.origin, self.base_dir = Site.parse_base_uri(config.get("base_uri")) + self.origin, self.base_dir = Site.parse_base_url(config.get("base_url")) self.template_path: Path = Site.resolve_template_path(self.template) self.output_path: Path = self.site_path / "output" self.jinja_env = Environment(loader=FileSystemLoader(self.template_path)) @@ -59,9 +59,9 @@ class Site: return cast(dict[str, Any], config) @staticmethod - def parse_base_uri(value: str | None) -> tuple[str, str]: + def parse_base_url(value: str | None) -> tuple[str, str]: if not value: - return ("", "/") + return ("", "") parsed = urlparse(value) if parsed.scheme and parsed.netloc: origin = f"{parsed.scheme}://{parsed.netloc}" @@ -70,9 +70,7 @@ class Site: else: origin = "" - path = parsed.path - if not path.endswith("/"): - path += "/" + path = parsed.path.removesuffix("/") return (origin, path) @staticmethod @@ -93,12 +91,12 @@ class Site: self.by_tag[tag] = [] self.by_tag[tag].append(content) - def add_by_uri(self, output: Output) -> None: - if output.uri in self.by_uri: + def add_by_path(self, output: Output) -> None: + if output.destination in self.by_path: raise ContentError( - f"uri '{output.uri}' is already claimed by another output" + f"path '{output.destination}' is already claimed by another output" ) - self.by_uri[output.uri] = output + self.by_path[output.destination] = output def update_tags_by_count(self) -> None: tags = [(tag, len(items)) for tag, items in self.by_tag.items()] @@ -111,43 +109,43 @@ class Site: return for file in assets_path.rglob("*"): if file.is_file(): - uri = "assets/" + file.relative_to(assets_path).as_posix() - asset = File(uri, file) - self.add_by_uri(asset) + path = Path("assets") / file.relative_to(assets_path) + asset = File(path, file) + self.add_by_path(asset) self.other_outputs.append(asset) - log.debug("Discovered template asset %s", uri) + log.debug("Discovered template asset %s", path) def discover(self) -> None: log.info("Discovering content...") self.discover_assets() - pygments = Memory("assets/pygments.css", highlight_style()) + pygments = Memory(Path("assets/pygments.css"), highlight_style()) self.other_outputs.append(pygments) - self.add_by_uri(pygments) + self.add_by_path(pygments) content_path = self.site_path / "content" for file in content_path.rglob("*"): if file.is_file() and is_content(file): content = create_content(file) - self.add_by_uri(content) + self.add_by_path(content) self.add_by_section(content) self.add_by_tag(content) self.content.append(content) self.update_tags_by_count() for index in discover_index(self): - self.add_by_uri(index) + self.add_by_path(index) self.other_outputs.append(index) tags_page = discover_tags(self) - self.add_by_uri(tags_page) + self.add_by_path(tags_page) self.other_outputs.append(tags_page) log.info("Discovered %d content items", len(self.content)) def build(self) -> None: if not self.origin: log.warning( - "base_uri config value is missing a domain name, " - "can't add canonical uri to content" + "base_url config value is missing a domain name, " + "can't add canonical url to content" ) - if not self.base_dir.startswith("/"): - raise ConfigError("base_uri config value must be an absolute path") + 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: diff --git a/omicron/ssg/templates/plain/article.html b/omicron/ssg/templates/plain/article.html index 3ff1587..7727a48 100644 --- a/omicron/ssg/templates/plain/article.html +++ b/omicron/ssg/templates/plain/article.html @@ -2,12 +2,12 @@ {% block title %}{{ article.title }} — {{ site.name }}{% endblock %} -{% block head %}{% endblock %} +{% block head %}{% endblock %} {% block breadcrumb %} {% endblock %} @@ -25,7 +25,7 @@ {% if article.tags %} {% endif %} diff --git a/omicron/ssg/templates/plain/base.html b/omicron/ssg/templates/plain/base.html index e73da3f..9f6760a 100644 --- a/omicron/ssg/templates/plain/base.html +++ b/omicron/ssg/templates/plain/base.html @@ -4,13 +4,13 @@ {% block title %}{{ site.name }}{% endblock %} - - + + {% block head %}{% endblock %}
- {% block breadcrumb %}{{ site.name }}{% endblock %} + {% block breadcrumb %}{{ site.name }}{% endblock %}
{% block main %}{% endblock %} diff --git a/omicron/ssg/templates/plain/index.html b/omicron/ssg/templates/plain/index.html index 2f6e023..1d55df7 100644 --- a/omicron/ssg/templates/plain/index.html +++ b/omicron/ssg/templates/plain/index.html @@ -1,24 +1,24 @@ {% extends "base.html" %} -{% set prefix = (label + "/") if kind == "section" else (("tags/" + label + "/") if kind == "tag" else "") %} +{% set base_path = ("/" + label) if kind == "section" else (("/tags/" + label) if kind == "tag" else "") %} {% set heading = label or "" %} {% block title %}{% if heading %}{{ heading }} — {% endif %}{{ site.name }}{% if page_num > 1 %} — Page {{ page_num }}{% endif %}{% endblock %} {% block head %} - + {% if page_num > 1 %}{% endif %} {% endblock %} {% block breadcrumb %} {% if kind == "section" %} {% elif kind == "tag" %} {% else %} @@ -31,7 +31,7 @@ {% for item in items %}
-

{{ item.title }}

+

{{ item.title }}

{% if item.summary %}

{{ item.summary }}

{% endif %} @@ -40,15 +40,15 @@ {% if total_pages > 1 %} {% endif %} diff --git a/omicron/ssg/templates/plain/tags.html b/omicron/ssg/templates/plain/tags.html index 62f5e86..948596e 100644 --- a/omicron/ssg/templates/plain/tags.html +++ b/omicron/ssg/templates/plain/tags.html @@ -3,12 +3,12 @@ {% block title %}Tags — {{ site.name }}{% endblock %} {% block head %} - + {% endblock %} {% block breadcrumb %} {% endblock %} @@ -17,7 +17,7 @@

Tags

{% endblock %}