Files
onepager/templates/base.html
mAi 29965c1164 mAi: #9 - GEO Schema-Slot {{schema_jsonld}} in templates/base.html + render.sh
Schema-Markup-Mechanismus für templated Sites (custom Sites bleiben unberührt).

- templates/base.html: {{schema_jsonld}} Slot im <head>.
- site.yaml: optionaler `schema:` Block. `type:` -> `@type`, `@context`
  wird automatisch ergänzt. Fehlt der Block, bleibt der Slot leer.
- render.sh: liest schema via `yq -o=json`, transformiert mit jq, fügt
  Template-Default für `type` ein (person-* -> Person, product-* -> Product,
  editorial -> Article).
- render.sh: literal-string replace (lreplace) statt awk gsub für multiline-
  Substitution. Behebt nebenbei einen latenten Bug, bei dem `&copy;` im
  template_body als `{{body}}copy;` corrupted wurde (gsub interpretierte
  `&` als matched text).
- tests/schema-test.sh + 4 Fixtures: validiert explicit type, Template-
  Defaults für 3 Templates, leerer Slot ohne schema-Block.
- README.md: Schema.org-Konvention dokumentiert (Block-Format, Defaults,
  Custom-Sites-Hinweis, Schema.org-Validator-Link).

QA: ./build.sh -> 59 sites OK, custom Sites byte-identical zur Source,
3 templated Fixtures rendern valides JSON-LD (Person/Product/Article),
no-schema-Fixture produziert keinen <script>-Tag.

Closes #9 nicht - head reviewed + merged.
2026-04-30 02:50:08 +02:00

26 lines
812 B
HTML

<!DOCTYPE html>
<html lang="{{lang}}">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title{{title_i18n}}>{{title}}</title>
<meta name="description" content="{{description}}"{{description_i18n}}>
<meta name="robots" content="index, follow">
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>{{favicon}}</text></svg>">
{{fonts}}
{{schema_jsonld}}
<style>
{{css_variables}}
{{css_responsive}}
{{css_animations}}
{{css_noise}}
{{template_css}}
</style>
</head>
<body class="noise-overlay">
{{body}}
<script src="/shared/ai-disclosure.js" data-tone="{{disclosure_tone}}"></script>
<script src="/shared/i18n.js"></script>
</body>
</html>