Add sitemap generation
This commit is contained in:
@@ -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",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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)
|
||||||
@@ -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")
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
Reference in New Issue
Block a user