Success-story migration + new plugins + JSON/UX polish

- Success Stories: full migration from old site (48/48, audited),
  markets n:n, quotation content block, columns content block,
  pretty SEO detail URLs via SuccessStoryPathRewrite middleware,
  list/detail split (list page 4 / story page), detailUrl/backUrl
- New plugins: VITEC Locations (grid/list/map + RTE map text),
  VITEC Customer Logos (color/bw logic, only-show-selected),
  VITEC Card (one plugin for product/story/market/solution
  with reloading FlexForm + custom backend preview renderer)
- Eventlist: layout dropdown (list/grid/teaserbar) in settings
- Hero section CB: Images/Video tabs, background video + overlay
- Product JSON: full category rootline (parents), fixed missing
  ConnectionPool import (all-products crash), category tree map
- Backend preview CSS: container-query responsive (narrow columns)
- Docs: ISO architecture spec, root + extension READMEs

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
khaccountandClaude Fable 5 committed 2026-07-24 09:53:33 +02:00
1 parent aafcb5dcb6
commit eae40f4286
110 files changed
+8502 -279

No files matched your search

@@ -77,16 +77,21 @@ class UsecaseShowJsonRenderer
$layout = (string)($settings['layout'] ?? 'default');
$debugMode = (bool)($settings['debug'] ?? false);
$usecaseUid = (int)($settings['usecase'] ?? 0);
// Fallback: uid/slug from the request (React detail route).
if (!$usecaseUid) {
$params = $GLOBALS['TYPO3_REQUEST']?->getQueryParams() ?? [];
$param = $params['tx_vitec_usecaseshow']['usecase'] ?? null;
if ($param !== null && $param !== '') {
$usecaseUid = is_numeric($param) ? (int)$param : $this->resolveSlug((string)$param);
}
// The story is resolved from the request ONLY (detail route from the
// list plugin's detailUrl): route-enhancer arguments live in the
// `routing` PageArguments, plain GET in query params.
$request = $GLOBALS['TYPO3_REQUEST'] ?? null;
$param = null;
$routing = $request?->getAttribute('routing');
if ($routing instanceof \TYPO3\CMS\Core\Routing\PageArguments) {
$param = $routing->getRouteArguments()['tx_vitec_usecaseshow']['usecase'] ?? null;
}
if ($param === null || $param === '') {
$param = ($request?->getQueryParams() ?? [])['tx_vitec_usecaseshow']['usecase'] ?? null;
}
$usecaseUid = ($param !== null && $param !== '')
? (is_numeric($param) ? (int)$param : $this->resolveSlug((string)$param))
: 0;
if (!$usecaseUid) {
return $debugMode
@@ -114,9 +119,11 @@ class UsecaseShowJsonRenderer
$serializer = GeneralUtility::makeInstance(UsecaseSerializer::class);
$backPid = (int)($settings['backPid'] ?? 0);
$response = [
'usecase' => $serializer->serializeDetail($usecase),
'layout' => $layout,
'backUrl' => $backPid > 0 ? ($this->resolvePageUrl($backPid) ?: null) : null,
];
if ($debugMode) {
@@ -145,4 +152,15 @@ class UsecaseShowJsonRenderer
return (int)($row['uid'] ?? 0);
}
/** Resolve a page uid to its frontend path (route enhancer aware). */
private function resolvePageUrl(int $pageUid): string
{
try {
$cObj = GeneralUtility::makeInstance(\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::class);
return (string)$cObj->typoLink_URL(['parameter' => (string)$pageUid]);
} catch (\Throwable $e) {
return '';
}
}
}