markemacht/_markemacht.de/scripts/build-site.py
Kevin Adametz 9c6b7ed4f3
Some checks are pending
linter / quality (push) Waiting to run
tests / ci (8.3) (push) Waiting to run
tests / ci (8.4) (push) Waiting to run
tests / ci (8.5) (push) Waiting to run
Optimierung markemacht.de und adametz.media für Live-Deploy.
Beide Sites mit lokalem Font-Hosting, WebP, Build-Pipeline, SEO-Basis,
HSTS, Performance-Tuning und aktualisierten Impressum/Datenschutz-Texten.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-09 09:55:25 +00:00

100 lines
2.6 KiB
Python
Executable file

#!/usr/bin/env python3
"""Synchronisiert head-common, Header und Footer in alle HTML-Seiten."""
from __future__ import annotations
import re
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
VERSION = (ROOT / 'assets' / 'version.txt').read_text().strip()
HEAD_COMMON = ROOT / 'assets' / 'components' / 'head-common.html'
HEADER = ROOT / 'assets' / 'components' / 'header.html'
FOOTER = ROOT / 'assets' / 'components' / 'footer.html'
HEAD_BLOCK = re.compile(
r' <meta property="og:locale" content="de_DE" />.*?"inLanguage": "de-DE"\n \}\n </script>\n',
re.DOTALL,
)
HEADER_MOUNT = re.compile(
r' <div data-site-header></div>\n',
)
FOOTER_MOUNT = re.compile(
r' <div data-site-footer></div>\n',
)
APP_JS = re.compile(
r'<script src="\./assets/js/app\.js(?:\?v=[^"]*)?" defer></script>',
)
def indent_block(text: str, prefix: str = ' ') -> str:
lines = text.strip('\n').splitlines()
return '\n'.join(prefix + line if line.strip() else '' for line in lines) + '\n'
def build_head() -> str:
content = HEAD_COMMON.read_text()
content = content.replace('{{VERSION}}', VERSION)
return indent_block(content)
def process_html(path: Path) -> bool:
text = path.read_text()
if 'data-site-header' not in text and 'og:locale' not in text:
return False
original = text
if 'og:locale' in text:
text = HEAD_BLOCK.sub(build_head(), text, count=1)
if HEADER_MOUNT.search(text):
header = indent_block(HEADER.read_text())
text = HEADER_MOUNT.sub(header, text, count=1)
if FOOTER_MOUNT.search(text):
footer = indent_block(FOOTER.read_text())
text = FOOTER_MOUNT.sub(footer, text, count=1)
text = APP_JS.sub(
f'<script src="./assets/js/app.js?v={VERSION}" defer></script>',
text,
count=1,
)
# Alte statische Preloads + externes theme-init.js entfernen
text = re.sub(
r' <link rel="preload" as="image" href="\./assets/img/start-[^"]+\.webp"[^/]*/>\n',
'',
text,
)
text = re.sub(
r' <script src="\./assets/js/theme-init\.js"></script>\n',
'',
text,
)
if text != original:
path.write_text(text)
return True
return False
def main() -> None:
updated = []
for path in sorted(ROOT.glob('*.html')):
if process_html(path):
updated.append(path.name)
print(f'Version: {VERSION}')
for name in updated:
print(f' aktualisiert: {name}')
if not updated:
print(' keine Änderungen')
if __name__ == '__main__':
main()