Translate pages, areas, menus, forms and posts field by field instead of rebuilding them
A site can have further languages (Settings → Languages). A page is built once; each language adds only its texts, keyed by the stable block IDs, plus its own address under /en/… (ADR 111, document schema v27, migration 20261009000100 for page_translation). - Editor: DE | EN switch, a list of all texts with original, state (missing, translated, original changed) and filter; structure stays with the main language. Undo, drafts, publishing and revisions cover all languages at once. - Website: /en and translated slugs, lang, canonical, hreflang with x-default, og:locale, sitemap; links to translated pages follow the language; a language switch block. - Header, footer and linked sections translate the same way; menu entries carry labels per language; fixed template texts come from a small dictionary. - Forms: labels, help, options, button and success message per language; messages and the step script speak the language, the submission and the email stay in the main language. - Posts, archives, category names, consent text and the 404 page follow the language. - Single-language sites see none of it and never touch the new table. The forms administration becomes an overview with one row per form and its own edit page; fields are one line each with details collapsed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c7705b7083
commit
e15b2517b1
51 files changed
+3045
-219
No files matched your search
@@ -52,6 +52,53 @@
|
||||
{% else %}<p class="field-help">Die Zuordnung kann von einem Benutzer mit Veröffentlichungsrechten geändert werden.</p>{% endif %}
|
||||
</div>
|
||||
</section>
|
||||
<section class="stack-section" id="sprachen" aria-labelledby="sprachen-title">
|
||||
<div class="section-head"><h2 id="sprachen-title">Sprachen</h2><span class="muted">Hauptsprache: {{ mainLanguage.name }}</span></div>
|
||||
<div class="card card-body">
|
||||
<p>Jede weitere Sprache übersetzt dieselben Seiten: Aufbau und Gestaltung bleiben, je Sprache kommen nur die Texte und eine eigene Adresse dazu – zum Beispiel <code>/en/services</code>. Übersetzt wird im Editor über den Sprachumschalter. Eine Seite erscheint in einer Sprache erst, wenn ihre Übersetzung veröffentlicht ist.</p>
|
||||
{% if is_granted('ROLE_ADMIN') %}
|
||||
<form action="{{ path('admin_languages_save') }}" method="post">
|
||||
<input type="hidden" name="_csrf_token" value="{{ csrf_token('settings') }}">
|
||||
<fieldset class="check-grid">
|
||||
<legend>Weitere Sprachen</legend>
|
||||
{% for sprache in languageCatalog %}
|
||||
<label class="check-label"><input type="checkbox" name="languages[]" value="{{ sprache.code }}"{{ sprache.code in extraLanguages ? ' checked' : '' }}> {{ sprache.name }} <span class="muted" lang="{{ sprache.code }}">{{ sprache.native }}</span></label>
|
||||
{% endfor %}
|
||||
</fieldset>
|
||||
<p class="field-help">Ohne Häkchen bleibt die Website einsprachig, und nirgends erscheint etwas davon. Wird eine Sprache wieder abgewählt, verschwinden ihre Seiten von der Website; die Übersetzungen bleiben gespeichert. Damit Besucher die Sprache wechseln können, setze den Baustein „Sprachwahl“ in den Kopfbereich.</p>
|
||||
<button class="primary" type="submit">Sprachen speichern</button>
|
||||
</form>
|
||||
{% if extraLanguages %}
|
||||
<form action="{{ path('admin_language_texts_save') }}" method="post" class="language-texts">
|
||||
<input type="hidden" name="_csrf_token" value="{{ csrf_token('settings') }}">
|
||||
<h3>Texte in den weiteren Sprachen</h3>
|
||||
<p class="field-help">Seiten, Kopf und Fuß übersetzt du im Editor, Menüs unter Menüs, Formulare unter Formulare. Hier stehen die Texte, die zur Website als Ganzes gehören. Leer heißt: wie in {{ mainLanguage.name }}.</p>
|
||||
{% for code in extraLanguages %}
|
||||
{% set name = languageCatalog|filter(s => s.code == code)|first.name %}
|
||||
<fieldset class="language-text-group">
|
||||
<legend>{{ name }}</legend>
|
||||
{% if settings.consentBanner %}
|
||||
<label for="consent-title-{{ code }}">Überschrift des Einwilligungshinweises</label>
|
||||
<input id="consent-title-{{ code }}" name="consentTexts[{{ code }}][title]" maxlength="80" lang="{{ code }}" value="{{ settings.consentTexts[code].title|default('') }}" placeholder="{{ settings.consentTitle ?: 'Externe Inhalte und Einwilligung' }}">
|
||||
<label for="consent-text-{{ code }}">Text des Einwilligungshinweises</label>
|
||||
<textarea id="consent-text-{{ code }}" name="consentTexts[{{ code }}][text]" maxlength="600" rows="3" lang="{{ code }}" placeholder="{{ settings.consentText }}">{{ settings.consentTexts[code].text|default('') }}</textarea>
|
||||
{% endif %}
|
||||
{% for term in terms %}
|
||||
{% set key = term.kind ~ ':' ~ term.slug %}
|
||||
<label for="term-{{ code }}-{{ term.id }}">{{ term.kind == 'category' ? 'Kategorie' : 'Schlagwort' }} „{{ term.name }}“</label>
|
||||
<input id="term-{{ code }}-{{ term.id }}" name="termNames[{{ code }}][{{ key }}]" maxlength="120" lang="{{ code }}" value="{{ settings.termNames[code][key]|default('') }}" placeholder="{{ term.name }}">
|
||||
{% endfor %}
|
||||
{% if not settings.consentBanner and terms is empty %}<p class="field-help">Ohne Einwilligungshinweis und ohne Kategorien gibt es hier nichts zu übersetzen.</p>{% endif %}
|
||||
</fieldset>
|
||||
{% endfor %}
|
||||
<button class="primary" type="submit">Übersetzungen speichern</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<p class="field-help">{{ extraLanguages ? 'Weitere Sprachen: ' ~ extraLanguages|map(c => c|upper)|join(', ') ~ '.' : 'Die Website ist einsprachig.' }} Ändern kann das ein Administrator.</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</section>
|
||||
<section class="stack-section">
|
||||
<div class="section-head"><h2>Unternehmensdaten</h2><span class="muted">Grundlage für Organization und LocalBusiness</span></div>
|
||||
{% if is_granted('ROLE_ADMIN') %}
|
||||
|
||||
Reference in new issue
Block a user