Unify list plugins, add solution list and per-story detail page

- vitec_usecaselist: layout + record selection like marketlist
- new plugin vitec_solutionlist (spec 7.13.3, key "solutions")
- tx_vitec_domain_model_usecase: detail_page -> resolved detailUrl
  (also gives story cards in vitec_modelcard a link for the first time)
- "Show Toolbar" checkbox on product/market/solution/usecase lists
- spec bumped to v1.9

BREAKING: vitec_productlist and vitec_usecaselist now emit an object
instead of a bare array. Consumers must read products.products and
usecases.usecases. Also found: productlist had a configurable layout
that was never serialised; it is emitted now, but keeps its own 0-3
vocabulary instead of grid/list/carousel.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-17 16:29:06 +02:00
parent 4ef3ad0026
commit 12eb40614b
23 changed files with 559 additions and 28 deletions

View File

@@ -5,6 +5,7 @@ declare(strict_types=1);
namespace Evomedien\Vitec\Service;
use Doctrine\DBAL\ParameterType;
use Evomedien\Vitec\Service\LinkResolver;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Resource\ResourceFactory;
use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -42,6 +43,10 @@ final class UsecaseSerializer
'uid' => $uid,
'title' => (string)($u['title'] ?? ''),
'slug' => (string)($u['slug'] ?? ''),
// The story's own detail page, when one is set. null means "none",
// and the list plugin then falls back to its Single PID plus the
// slug - which is how every story behaved before the field existed.
'detailUrl' => LinkResolver::pageUrl((int)($u['detail_page'] ?? 0)),
'subtitle' => (string)($u['subtitle'] ?? ''),
'teaser' => (string)($u['teaser'] ?? ''),
'cardImage' => $this->image($uid, 'card_image', null, true),