Add sitemap generation

This commit is contained in:
2026-08-26 04:11:56 +02:00
parent 728b1ee1bf
commit a5de93576a
7 changed files with 52 additions and 0 deletions
+2
View File
@@ -7,6 +7,7 @@ from omicron.ssg.output.memory import Memory
from omicron.ssg.output.directory import Directory from omicron.ssg.output.directory import Directory
from omicron.ssg.output.symlink import Symlink from omicron.ssg.output.symlink import Symlink
from omicron.ssg.output.tags import Tags, discover_tags from omicron.ssg.output.tags import Tags, discover_tags
from omicron.ssg.output.sitemap import Sitemap
__all__ = [ __all__ = [
"Output", "Output",
@@ -23,4 +24,5 @@ __all__ = [
"Symlink", "Symlink",
"Tags", "Tags",
"discover_tags", "discover_tags",
"Sitemap",
] ]
+1
View File
@@ -44,6 +44,7 @@ class Content(Output):
self.tags: set[str] = tags self.tags: set[str] = tags
self.summary: str | None = summary self.summary: str | None = summary
self.draft: bool = draft self.draft: bool = draft
self.in_sitemap = True
@staticmethod @staticmethod
def build_path(section: str, slug: str) -> Path: def build_path(section: str, slug: str) -> Path:
+1
View File
@@ -30,6 +30,7 @@ class Index(Output):
self.page_num = page_num self.page_num = page_num
self.total_pages = total_pages self.total_pages = total_pages
self.label = label self.label = label
self.in_sitemap = kind != "tag" and page_num == 1
def pagination_url(self, n: int) -> str: def pagination_url(self, n: int) -> str:
path = Index.build_path(self.kind, n, self.label) path = Index.build_path(self.kind, n, self.label)
+2
View File
@@ -31,6 +31,8 @@ class Output(ABC):
url = url.parent url = url.parent
self.url = url.as_posix() self.url = url.as_posix()
self.in_sitemap = False
@property @property
def site(self) -> Site: def site(self) -> Site:
obj = self._site_ref() obj = self._site_ref()
+38
View File
@@ -0,0 +1,38 @@
import logging
from pathlib import Path
from typing import TYPE_CHECKING
from xml.etree.ElementTree import Element, ElementTree, SubElement
from omicron.ssg.output.output import Output
from omicron.ssg.output.content import Content
log = logging.getLogger(__name__)
if TYPE_CHECKING:
from omicron.ssg.site import Site
else:
Site = "omicron.ssg.site.Site"
class Sitemap(Output):
PATH = Path("sitemap.xml")
NAMESPACE = "http://www.sitemaps.org/schemas/sitemap/0.9"
def __init__(self, site: Site):
super().__init__(site, Sitemap.PATH)
def write(self) -> None:
urlset = Element("urlset", xmlns=Sitemap.NAMESPACE)
for entry in self.site.by_path.values():
if not entry.in_sitemap:
continue
url = SubElement(urlset, "url")
SubElement(url, "loc").text = f"{self.site.origin}{entry.url}"
if isinstance(entry, Content):
lastmod = entry.updated or entry.created
SubElement(url, "lastmod").text = lastmod.isoformat()
dest = self.site.output_path / self.destination
dest.parent.mkdir(parents=True, exist_ok=True)
ElementTree(urlset).write(dest, encoding="utf-8", xml_declaration=True)
log.debug("Wrote %s", dest)
+1
View File
@@ -17,6 +17,7 @@ class Tags(Output):
def __init__(self, site: Site, tags: list[tuple[str, int]]): def __init__(self, site: Site, tags: list[tuple[str, int]]):
super().__init__(site, Tags.PATH) super().__init__(site, Tags.PATH)
self.tags = tags self.tags = tags
self.in_sitemap = True
def write(self) -> None: def write(self) -> None:
template = self.site.jinja_env.get_template("tags.html") template = self.site.jinja_env.get_template("tags.html")
+7
View File
@@ -15,6 +15,7 @@ from omicron.ssg.output import (
Index, Index,
Tags, Tags,
Memory, Memory,
Sitemap,
discover_index, discover_index,
discover_tags, discover_tags,
) )
@@ -194,6 +195,12 @@ class Site:
tags_page = discover_tags(self) tags_page = discover_tags(self)
self.add_by_path(tags_page) self.add_by_path(tags_page)
self.other_outputs.append(tags_page) self.other_outputs.append(tags_page)
if self.origin:
sitemap = Sitemap(self)
self.add_by_path(sitemap)
self.other_outputs.append(sitemap)
else:
log.debug("Skipping sitemap, base_url has no domain name")
log.info("Discovered %d content items", len(self.content)) log.info("Discovered %d content items", len(self.content))
def clean(self) -> None: def clean(self) -> None: