Umut hat den Nachbau Detail fuer Detail mit kant-it.de verglichen. Vier Stellen, an denen das CMS etwas nicht konnte oder etwas Falsches tat. Der Slider zeigte eine Rollleiste statt Punkte. Punkte zeichnet jetzt der Browser selbst - scroll-marker-group und ::scroll-marker, ohne Skript, mit erkennbarem aktivem Punkt. Wo ein Browser das noch nicht kennt, bleibt das wischbare Schiebefeld. Pfeile gibt es bewusst nicht: Chrome legt ::scroll-button an den Seitenrand statt in den Slider. Und er rotiert nicht von selbst, weil eine oeffentliche Seite kein JavaScript laedt. Eine Beitragskarte war keine Karte, sondern eine lose Spalte. Jetzt weiss, 18px Ecken, Bild buendig oben im Verhaeltnis 16:10, Text darunter. Die Theme-Schriftskala ueberschrieb die Groessen der Bausteine: jede Kartenueberschrift war so gross wie eine Abschnittsueberschrift. Eine Ueberschrift darf ab v17 ein Wort hervorheben. Dabei waere beinahe eine Luecke entstanden: die Dokumentfassung war in der Schliessung des Filters nicht gebunden, der Filter lief nie, die Ausgabe war schon unescaped. Ein Test mit <script> in einer Ueberschrift hat es gezeigt. Geprueft: 390 PHP-Tests unter 8.2 und 8.4, 18 JS-Tests, Editortest, Browserpruefung, axe ohne Verstoss auf dem Nachbau. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
66 lines
4.4 KiB
Twig
66 lines
4.4 KiB
Twig
<!doctype html>
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>{{ heading }}{% if result.page > 1 %} · Seite {{ result.page }}{% endif %} · Beiträge</title>
|
|
<meta name="description" content="{{ term ? 'Beiträge zu ' ~ term.name : 'Alle Beiträge' }}.">
|
|
<link rel="canonical" href="{{ canonical }}">
|
|
{% if result.page > 1 %}<link rel="prev" href="{{ base }}{{ result.page > 2 ? '?seite=' ~ (result.page - 1) : '' }}">{% endif %}
|
|
{% if result.page < result.pages %}<link rel="next" href="{{ base }}?seite={{ result.page + 1 }}">{% endif %}
|
|
<link rel="alternate" type="application/rss+xml" title="Beiträge" href="/feed.xml">
|
|
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
|
|
<link rel="stylesheet" href="/assets/site.css">
|
|
<link rel="stylesheet" href="/assets/design.css">
|
|
</head>
|
|
{% set consentOpen = not editing|default(false) and consentGate.needsBanner(app.request) %}
|
|
<body class="kant{{ consentOpen ? ' consent-open' : '' }}">
|
|
<a class="skip-link" href="#main">Zum Inhalt springen</a>
|
|
{% if areas.header|default(null) %}
|
|
<header class="site-header{{ siteSettings.load().stickyHeader ? ' is-sticky' : '' }}">
|
|
{% for block in areas.header.blocks %}{% include 'blocks/block.html.twig' with {block: block, postLists: {}, forms: {}, breadcrumbs: [], navigation: navigation|default({}), sections: sections|default({}), richText: true, richHeadings: areas.header.schemaVersion|default(1) >= 17, eagerImage: null} only %}{% endfor %}
|
|
</header>
|
|
{% endif %}
|
|
<main id="main" tabindex="-1">
|
|
<section class="block-section tone-mint width-normal">
|
|
<div class="shell section-inner">
|
|
{% if term %}<p class="post-terms-label">{{ term.kind == 'category' ? 'Kategorie' : 'Schlagwort' }}</p>{% endif %}
|
|
<h1>{{ heading }}</h1>
|
|
<p class="block-text">{{ result.total }} {{ result.total == 1 ? 'Beitrag' : 'Beiträge' }}{% if result.pages > 1 %} · Seite {{ result.page }} von {{ result.pages }}{% endif %}</p>
|
|
</div>
|
|
</section>
|
|
<section class="block-section tone-paper width-normal">
|
|
<div class="shell section-inner">
|
|
{% include 'blocks/post-list.html.twig' with {posts: result.posts} only %}
|
|
{% if result.pages > 1 %}
|
|
<nav class="pagination" aria-label="Seiten">
|
|
{% if result.page > 1 %}<a rel="prev" href="{{ base }}{{ result.page > 2 ? '?seite=' ~ (result.page - 1) : '' }}">← Neuere</a>{% endif %}
|
|
<span>Seite {{ result.page }} von {{ result.pages }}</span>
|
|
{% if result.page < result.pages %}<a rel="next" href="{{ base }}?seite={{ result.page + 1 }}">Ältere →</a>{% endif %}
|
|
</nav>
|
|
{% endif %}
|
|
</div>
|
|
</section>
|
|
</main>
|
|
{% if areas.footer|default(null) %}
|
|
<footer class="site-footer">
|
|
{% for block in areas.footer.blocks %}{% include 'blocks/block.html.twig' with {block: block, postLists: {}, forms: {}, breadcrumbs: [], navigation: navigation|default({}), sections: sections|default({}), richText: true, richHeadings: areas.footer.schemaVersion|default(1) >= 17, eagerImage: null} only %}{% endfor %}
|
|
</footer>
|
|
{% endif %}
|
|
{# Privacy statement, imprint and the way back to the consent decision. All three have to be
|
|
reachable from every page, so they are part of the template and not of the footer area,
|
|
which someone could delete. One labelled landmark, so they are not loose text either. #}
|
|
{% set legal = consentGate.legalLinks() %}
|
|
{% set revocable = not editing|default(false) and consentGate.askedGroups is not empty and not consentGate.needsBanner(app.request) %}
|
|
{% if legal is not empty or revocable %}
|
|
<nav class="legal-bar" aria-label="Rechtliches">
|
|
{% for path, label in legal %}{% if not loop.first %} · {% endif %}<a href="/{{ path }}">{{ label }}</a>{% endfor %}
|
|
{% if revocable %}{% if legal is not empty %} · {% endif %}<a href="/einwilligung">Einwilligung ändern</a>{% endif %}
|
|
</nav>
|
|
{% endif %}
|
|
{% if not editing|default(false) and consentGate.needsBanner(app.request) %}
|
|
{% include 'consent-banner.html.twig' with {consent: consentGate.state(app.request), back: app.request.pathInfo} only %}
|
|
{% endif %}
|
|
</body>
|
|
</html>
|