106 lines
3.5 KiB
Python
106 lines
3.5 KiB
Python
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass, field
|
|
from pathlib import Path
|
|
import shutil
|
|
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parents[1]
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class ThemeSpec:
|
|
name: str
|
|
display_name: str
|
|
template_path: Path
|
|
stylesheet_path: Path
|
|
extra_assets: tuple[Path, ...] = field(default_factory=tuple)
|
|
body_class: str = ""
|
|
shell_class: str = ""
|
|
page_class: str = ""
|
|
description: str = ""
|
|
|
|
|
|
def _theme_path(*parts: str) -> Path:
|
|
return REPO_ROOT.joinpath(*parts)
|
|
|
|
|
|
_THEMES: dict[str, ThemeSpec] = {
|
|
"evo-edu": ThemeSpec(
|
|
name="evo-edu",
|
|
display_name="Evo-Edu",
|
|
template_path=_theme_path("theme", "themes", "evo-edu", "base.html"),
|
|
stylesheet_path=_theme_path("theme", "themes", "evo-edu", "style.css"),
|
|
body_class="theme-evo-edu",
|
|
shell_class="site-shell",
|
|
page_class="evo-edu-page",
|
|
description="Warm learning-focused theme derived from the evo-edu.org home page.",
|
|
),
|
|
"talkorigins-modern": ThemeSpec(
|
|
name="talkorigins-modern",
|
|
display_name="TalkOrigins Modern",
|
|
template_path=_theme_path("theme", "themes", "talkorigins-modern", "base.html"),
|
|
stylesheet_path=_theme_path("theme", "themes", "talkorigins-modern", "style.css"),
|
|
extra_assets=(
|
|
_theme_path("theme", "themes", "talkorigins-modern", "assets", "toa.ico"),
|
|
_theme_path("theme", "themes", "talkorigins-modern", "assets", "toa_logo_001_edit_001.png"),
|
|
),
|
|
body_class="theme-talkorigins-modern",
|
|
shell_class="site-shell",
|
|
page_class="talkorigins-preview",
|
|
description="Archive-forward theme derived from the www2.talkorigins.org modernization proof-of-concept.",
|
|
),
|
|
"pandasthumb": ThemeSpec(
|
|
name="pandasthumb",
|
|
display_name="Panda's Thumb",
|
|
template_path=_theme_path("theme", "themes", "pandasthumb", "base.html"),
|
|
stylesheet_path=_theme_path("theme", "themes", "pandasthumb", "style.css"),
|
|
body_class="theme-pandasthumb",
|
|
shell_class="site-shell",
|
|
page_class="pandasthumb-page",
|
|
description="Legacy-archive theme derived from pandasthumb.net.",
|
|
),
|
|
}
|
|
|
|
|
|
def available_themes() -> list[ThemeSpec]:
|
|
return [_THEMES[name] for name in sorted(_THEMES)]
|
|
|
|
|
|
def get_theme(name: str | None) -> ThemeSpec:
|
|
theme_name = name or "evo-edu"
|
|
try:
|
|
return _THEMES[theme_name]
|
|
except KeyError as exc:
|
|
raise KeyError(f"Unknown SciSiteForge theme: {theme_name}") from exc
|
|
|
|
|
|
def materialize_theme(theme: ThemeSpec, output_dir: str | Path) -> dict[str, str]:
|
|
out = Path(output_dir)
|
|
theme_root = out / "theme"
|
|
assets_root = theme_root / "assets"
|
|
assets_root.mkdir(parents=True, exist_ok=True)
|
|
|
|
style_target = theme_root / "style.css"
|
|
shutil.copyfile(theme.stylesheet_path, style_target)
|
|
|
|
copied_assets: list[str] = []
|
|
for asset in theme.extra_assets:
|
|
target = assets_root / asset.name
|
|
shutil.copyfile(asset, target)
|
|
copied_assets.append(target.relative_to(out).as_posix())
|
|
|
|
shared_js = _theme_path("theme", "main.js")
|
|
if shared_js.exists():
|
|
shutil.copyfile(shared_js, theme_root / "main.js")
|
|
|
|
return {
|
|
"theme_name": theme.name,
|
|
"theme_display_name": theme.display_name,
|
|
"theme_description": theme.description,
|
|
"theme_stylesheet_href": "/theme/style.css",
|
|
"theme_script_href": "/theme/main.js",
|
|
"theme_asset_prefix": "/theme/assets",
|
|
"theme_assets": copied_assets,
|
|
}
|