From c9b00e6f10d87cb9b2da101f41edcdf098abefcc Mon Sep 17 00:00:00 2001 From: Oliver Rasche Date: Tue, 10 Nov 2026 11:11:55 +0100 Subject: [PATCH] News-Liste: serverseitige Pagination (Kontrakt 0070-FE) Die Uebersichtsliste (news_newsliststicky/news_pi1 ohne limit und ohne Auswahl, d.h. genau /insights/news) liefert jetzt pro Request nur die Karten der angefragten Seite: ?page=&category=, Antwort additiv mit pagination {page,pages,itemsPerPage,total}, categories[] mit Gesamt-Zaehlern und activeCategory. page klemmt auf die letzte Seite, unbekannte category faellt auf alle zurueck, Sortierung serverseitig datetime DESC, itemsPerPage aus settings.list.paginate (Default 12). Caching: page/category stehen in cacheHash.excludedParameters, der TYPO3-Seitencache unterscheidet die Varianten also nicht - das Element konvertiert sich deshalb im paginierten Fall per convertToUserIntObject() zu USER_INT (EXT:headless wrappt den INT-Marker selbst); ETag/304 je Query-Variante verifiziert, der SSR-Cache haelt eine Variante pro Pfad+Query. Karten im paginierten Modus in schlanker Form (Felderliste aus 0070-FE); media[] traegt jetzt ueberall alternative (Alt-Text-Fallback B5). Teaser-Listen mit limit und Selected-/Search-Listen unveraendert; ohne pagination-Feld bleibt das Frontend beim bisherigen Verhalten. JSON der Liste: 700 kB -> ~100 kB pro Seite. Co-Authored-By: Claude Fable 5 --- .../Classes/UserFunc/NewsJsonRenderer.php | 217 ++++++++++++++++++ 1 file changed, 217 insertions(+) diff --git a/packages/vitec/Classes/UserFunc/NewsJsonRenderer.php b/packages/vitec/Classes/UserFunc/NewsJsonRenderer.php index 43eeec7..5f3dbe6 100644 --- a/packages/vitec/Classes/UserFunc/NewsJsonRenderer.php +++ b/packages/vitec/Classes/UserFunc/NewsJsonRenderer.php @@ -155,7 +155,39 @@ final class NewsJsonRenderer return json_encode($response) ?: ''; } + // Server-side pagination for the big overview list (contract + // 0070-FE/0075-BE): only a plain/sticky list WITHOUT a limit and + // WITHOUT a hand-picked selection paginates. That is exactly the + // /insights/news element (#130); every teaser list carries a + // limit (1-3) and keeps today's full behaviour, as do selected/ + // search lists - the frontend falls back to client-side paging + // wherever the `pagination` key is absent. + $paginated = in_array($type, ['news_pi1', 'news_newsliststicky'], true) + && (int)($settings['limit'] ?? 0) === 0 + && trim((string)($settings['selectedList'] ?? '')) === ''; + + if ($paginated + && $this->cObj !== null + && $this->cObj->getUserObjectType() === ContentObjectRenderer::OBJECTTYPE_USER + ) { + // `page`/`category` sit in cacheHash.excludedParameters, so the + // TYPO3 page cache does NOT distinguish the query variants - + // a cacheable render would bake page 1 in for every URL. As + // USER_INT the element renders per request; EXT:headless wraps + // the INT marker itself (JsonContentObject detects + // '