from __future__ import annotations import json from dataclasses import dataclass, field from .html_utils import SafeHtml, attr, escape, trusted from .icons import _svg_icon DEFAULT_DESCRIPTION = ( "KarlDNS is a small self-hosted Dynamic DNS service for FRITZ!Box routers, " "Linux cron jobs, and home networks." ) @dataclass(frozen=True) class PageOptions: extra_styles: SafeHtml = field(default_factory=lambda: trusted("")) extra_scripts: SafeHtml = field(default_factory=lambda: trusted("")) description: str = DEFAULT_DESCRIPTION preload_logo: bool = False canonical_url: str | None = None image_url: str | None = None image_alt: str | None = None structured_data: dict[str, object] | None = None def _top_nav(label: str | None = None, links: SafeHtml | None = None) -> SafeHtml: account_html = "" if label: account_html = f'{escape(label)}' if links is None: links = trusted( 'API' 'llms.txt' ) theme_toggle = f""" """ return trusted(f""" """) def _site_footer() -> SafeHtml: return trusted(f""" """) def _page( title: str, body: SafeHtml, options: PageOptions | None = None, ) -> str: if not isinstance(body, SafeHtml): raise TypeError("body must be a SafeHtml fragment built by a template helper") options = options or PageOptions() return f""" {_canonical_tag(options.canonical_url)} {_social_meta_tags( title=title, description=options.description, canonical_url=options.canonical_url, image_url=options.image_url, image_alt=options.image_alt, )} {escape(title)} {_logo_preload_tag(options.preload_logo)} {_base_script_tags()} {options.extra_scripts} {_base_style_tags()} {options.extra_styles} {_structured_data_tag(options.structured_data)} {body}{_site_footer()} """ def _canonical_tag(canonical_url: str | None) -> SafeHtml: return trusted(f'') if canonical_url else trusted("") def _logo_preload_tag(preload_logo: bool) -> SafeHtml: if not preload_logo: return trusted("") return trusted('') def _base_script_tags() -> SafeHtml: return trusted(""" """) def _base_style_tags() -> SafeHtml: return trusted(""" """) def _social_meta_tags( *, title: str, description: str, canonical_url: str | None, image_url: str | None, image_alt: str | None, ) -> SafeHtml: if not canonical_url: return trusted("") social_card = "summary_large_image" if image_url else "summary" return trusted(f""" {_social_image_tags(image_url, image_alt or title)} """) def _social_image_tags(image_url: str | None, image_alt: str) -> SafeHtml: if not image_url: return trusted("") return trusted(f""" """) def _structured_data_tag(structured_data: dict[str, object] | None) -> SafeHtml: if not structured_data: return trusted("") payload = json.dumps(structured_data, ensure_ascii=False, separators=(",", ":")) return trusted('")