SEO, Weiterleitungen und strukturierte Daten (Arbeitspaket E)
Migration 20260912000800 ergänzt page.robots, page.og_media_id, website.settings und die Tabelle redirect. Alles Maschinenlesbare wird aus dem veröffentlichten Bestand abgeleitet, nichts separat gepflegt: die Sitemap listet nur veröffentlichte, indexierbare Seiten samt Beitragsübersicht und Begriffsarchiven, und dieselbe Einstellung setzt auch das noindex-Meta - beide Aussagen können nicht auseinanderlaufen. Strukturierte Daten entstehen nur aus gepflegten Werten: ohne Angaben wird kein leerer Organization-Block ausgegeben. JSON-LD ist ein Datenblock, kein Skript, daher bleibt script-src 'none' unberührt. Weiterleitungen greifen vor dem 404, aber nach der Seitensuche: eine vorhandene Seite gewinnt immer, sonst könnte ein alter Eintrag eine neue Seite unerreichbar machen. Ketten werden abgewiesen. robots.txt nimmt zusätzliche Zeilen nur nach festem Muster an, damit ein Eintrag die Datei nicht umdeuten kann. llms.txt ist standardmäßig aus. Geprüft: 128 PHP-Tests / 507 Assertions unter PHP 8.2.12 und 8.4.22, 14 JavaScript-Modelltests, Lint/Format/Container. Dazu eine reine Sichtprüfung im Browser auf einer lokalen Demoseite - weiterhin keine axe- oder Lighthouse-Messung. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d43bd91069
commit
a40c2bb27e
30 files changed
+1012
-38
No files matched your search
@@ -8,7 +8,7 @@
|
||||
<main id="admin-main" class="pages-main" tabindex="-1">
|
||||
<p class="eyebrow">DEINE WEBSITE</p><h1>Gute Inhalte beginnen hier.</h1>
|
||||
<p class="muted">Wähle eine Seite. Gestalte deinen Entwurf. Veröffentliche, wenn alles passt.</p>
|
||||
<p class="admin-links"><a class="secondary" href="{{ path('admin_media') }}">Medienverwaltung</a> <a class="secondary" href="{{ path('admin_menus') }}">Menüs</a> <a class="secondary" href="{{ path('admin_forms') }}">Formulare</a> <a class="secondary" href="/beitraege">Beitragsübersicht ↗</a></p>
|
||||
<p class="admin-links"><a class="secondary" href="{{ path('admin_media') }}">Medienverwaltung</a> <a class="secondary" href="{{ path('admin_menus') }}">Menüs</a> <a class="secondary" href="{{ path('admin_forms') }}">Formulare</a> <a class="secondary" href="{{ path('admin_settings') }}">Einstellungen</a> <a class="secondary" href="/beitraege">Beitragsübersicht ↗</a></p>
|
||||
|
||||
{% for type in ['error', 'success'] %}{% for message in app.flashes(type) %}
|
||||
<p class="notice {{ type == 'error' ? 'error' : 'ok' }}" role="{{ type == 'error' ? 'alert' : 'status' }}">{{ message }}</p>
|
||||
@@ -63,12 +63,21 @@
|
||||
</div>
|
||||
<span class="badge {{ page.published_revision_id == page.draft_revision_id ? 'published' : '' }}">{{ page.published_revision_id is null ? 'Nicht veröffentlicht' : (page.published_revision_id == page.draft_revision_id ? 'Veröffentlicht' : 'Entwurf geändert') }}</span>
|
||||
<a class="secondary" href="{{ path('admin_editor', {id: page.id}) }}" aria-label="{{ page.title }} bearbeiten">Bearbeiten <span aria-hidden="true">→</span></a>
|
||||
{% if page.type == 'post' and is_granted('ROLE_EDITOR') %}
|
||||
{% if is_granted('ROLE_EDITOR') %}
|
||||
<details class="meta-panel">
|
||||
<summary aria-label="Beitragsdaten von {{ page.title }}">Beitragsdaten</summary>
|
||||
<summary aria-label="Seitendaten von {{ page.title }}">{{ page.type == 'post' ? 'Beitragsdaten' : 'Seitendaten' }}</summary>
|
||||
<form action="{{ path('admin_post_meta', {id: page.id}) }}" method="post">
|
||||
<input type="hidden" name="_csrf_token" value="{{ csrf_token('pages') }}">
|
||||
<input type="hidden" name="expectedVersion" value="{{ page.version }}">
|
||||
<label for="robots-{{ page.id }}">Suchmaschinen</label>
|
||||
<select id="robots-{{ page.id }}" name="robots">
|
||||
<option value="index"{{ page.robots != 'noindex' ? ' selected' : '' }}>Darf indexiert werden</option>
|
||||
<option value="noindex"{{ page.robots == 'noindex' ? ' selected' : '' }}>Nicht indexieren</option>
|
||||
</select>
|
||||
<p class="field-help">Nicht indexierte Seiten erscheinen auch nicht in der Sitemap.</p>
|
||||
<label for="og-{{ page.id }}">Vorschaubild beim Teilen</label>
|
||||
<input id="og-{{ page.id }}" name="ogMediaId" maxlength="32" value="{{ page.og_media_id }}" placeholder="ID aus der Mediathek">
|
||||
{% if page.type == 'post' %}
|
||||
<label for="date-{{ page.id }}">Veröffentlicht am</label>
|
||||
<input id="date-{{ page.id }}" name="publishedAt" type="date" value="{{ page.published_at ? page.published_at|date('Y-m-d') : '' }}">
|
||||
<label for="author-{{ page.id }}">Autor</label>
|
||||
@@ -83,7 +92,8 @@
|
||||
<p class="field-help">Mehrere durch Komma trennen. Unbekannte Namen werden angelegt.</p>
|
||||
<label for="media-{{ page.id }}">Beitragsbild</label>
|
||||
<input id="media-{{ page.id }}" name="featuredMediaId" maxlength="32" value="{{ page.featured_media_id }}" placeholder="ID aus der Mediathek">
|
||||
<button class="primary" type="submit">Beitragsdaten speichern</button>
|
||||
{% endif %}
|
||||
<button class="primary" type="submit">Speichern</button>
|
||||
</form>
|
||||
</details>
|
||||
{% endif %}
|
||||
|
||||
Reference in new issue
Block a user