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

@@ -28,11 +28,24 @@
<label>Carousel</label>
<value>carousel</value>
</numIndex>
<numIndex index="3">
<label>50 / 50</label>
<value>50-50</value>
</numIndex>
</items>
<default>grid</default>
</config>
</settings.layout>
<settings.showtoolbar>
<label>Show Toolbar</label>
<description>Show the toolbar above the list.</description>
<config>
<type>check</type>
<default>0</default>
</config>
</settings.showtoolbar>
<settings.markets>
<label>Markets</label>
<description>Leave empty to show all markets alphabetically. If you select markets, exactly those are shown — in the order you arrange them here (use the arrows to sort).</description>

View File

@@ -92,6 +92,14 @@
</items>
</config>
</settings.layout>
<settings.showtoolbar>
<label>Show Toolbar</label>
<description>Show the toolbar above the list.</description>
<config>
<type>check</type>
<default>0</default>
</config>
</settings.showtoolbar>
</el>
</ROOT>
</sDEF>

View File

@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<T3DataStructure>
<sheets>
<sDEF>
<ROOT>
<sheetTitle>Solution List Settings</sheetTitle>
<type>array</type>
<el>
<settings.layout>
<label>Layout</label>
<description>Display variant for the solution cards.</description>
<config>
<type>select</type>
<renderType>selectSingle</renderType>
<items>
<numIndex index="0">
<label>Grid</label>
<value>grid</value>
</numIndex>
<numIndex index="1">
<label>List</label>
<value>list</value>
</numIndex>
<numIndex index="2">
<label>Carousel</label>
<value>carousel</value>
</numIndex>
<numIndex index="3">
<label>50 / 50</label>
<value>50-50</value>
</numIndex>
</items>
<default>grid</default>
</config>
</settings.layout>
<settings.showtoolbar>
<label>Show Toolbar</label>
<description>Show the toolbar above the list.</description>
<config>
<type>check</type>
<default>0</default>
</config>
</settings.showtoolbar>
<settings.solutions>
<label>Solutions</label>
<description>Leave empty to show all solutions alphabetically. If you select solutions, exactly those are shown — in the order you arrange them here (use the arrows to sort).</description>
<config>
<type>select</type>
<renderType>selectMultipleSideBySide</renderType>
<foreign_table>tx_vitec_domain_model_solution</foreign_table>
<foreign_table_where>AND tx_vitec_domain_model_solution.hidden = 0 AND tx_vitec_domain_model_solution.deleted = 0 ORDER BY tx_vitec_domain_model_solution.title</foreign_table_where>
<size>8</size>
<minitems>0</minitems>
<maxitems>999</maxitems>
</config>
</settings.solutions>
<settings.debug>
<label>Allow Debug Output</label>
<config>
<type>check</type>
<default>0</default>
</config>
</settings.debug>
</el>
</ROOT>
</sDEF>
</sheets>
</T3DataStructure>

View File

@@ -6,6 +6,57 @@
<sheetTitle>Usecase List</sheetTitle>
<type>array</type>
<el>
<settings.layout>
<label>Layout</label>
<description>Display variant for the success story cards.</description>
<config>
<type>select</type>
<renderType>selectSingle</renderType>
<items>
<numIndex index="0">
<label>Grid</label>
<value>grid</value>
</numIndex>
<numIndex index="1">
<label>List</label>
<value>list</value>
</numIndex>
<numIndex index="2">
<label>Carousel</label>
<value>carousel</value>
</numIndex>
<numIndex index="3">
<label>50 / 50</label>
<value>50-50</value>
</numIndex>
</items>
<default>grid</default>
</config>
</settings.layout>
<settings.showtoolbar>
<label>Show Toolbar</label>
<description>Show the toolbar above the list.</description>
<config>
<type>check</type>
<default>0</default>
</config>
</settings.showtoolbar>
<settings.usecases>
<label>Success Stories</label>
<description>Leave empty to show all stories (featured first, then alphabetically). If you select stories, exactly those are shown — in the order you arrange them here (use the arrows to sort).</description>
<config>
<type>select</type>
<renderType>selectMultipleSideBySide</renderType>
<foreign_table>tx_vitec_domain_model_usecase</foreign_table>
<foreign_table_where>AND tx_vitec_domain_model_usecase.hidden = 0 AND tx_vitec_domain_model_usecase.deleted = 0 AND tx_vitec_domain_model_usecase.hideonwebsite = 0 ORDER BY tx_vitec_domain_model_usecase.title</foreign_table_where>
<size>8</size>
<minitems>0</minitems>
<maxitems>999</maxitems>
</config>
</settings.usecases>
<settings.singlePid>
<label>Single PID (detail page)</label>
<description>Page that holds the "Show single VITEC Success Story" plugin. Used to build the detail links in the JSON output.</description>

View File

@@ -84,6 +84,10 @@ return [
'provider' => SvgIconProvider::class,
'source' => 'EXT:vitec/Resources/Public/Icons/vitec-plugin-marketlist.svg',
],
'vitec-plugin-solutionlist' => [
'provider' => SvgIconProvider::class,
'source' => 'EXT:vitec/Resources/Public/Icons/vitec-plugin-solutionlist.svg',
],
'vitec-import' => [
'provider' => SvgIconProvider::class,
'source' => 'EXT:vitec/Resources/Public/Icons/vitec-import.svg',

View File

@@ -113,6 +113,18 @@ tt_content {
}
}
vitec_solutionlist < lib.contentElementWithHeader
vitec_solutionlist {
fields {
content {
fields {
solutions = USER
solutions.userFunc = Evomedien\Vitec\UserFunc\SolutionListJsonRenderer->render
}
}
}
}
vitec_solutionshow < lib.contentElementWithHeader
vitec_solutionshow {
fields {

View File

@@ -111,6 +111,16 @@ use TYPO3\CMS\Extbase\Utility\ExtensionUtility;
'FILE:EXT:vitec/Configuration/FlexForms/Marketlist.xml'
);
ExtensionUtility::registerPlugin(
'Vitec',
'Solutionlist',
'VITEC Solution List',
'vitec-plugin-solutionlist',
'vitec',
'All solutions as grid, list or carousel.',
'FILE:EXT:vitec/Configuration/FlexForms/Solutionlist.xml'
);
// Change frame_class to allow multiple selections.
$GLOBALS['TCA']['tt_content']['columns']['frame_class']['config']['renderType'] = 'selectCheckBox';

View File

@@ -26,7 +26,7 @@ return [
'1' => [
'showitem' =>
'--div--;General,
title, slug, subtitle,
title, slug, detail_page, subtitle,
--div--;List view,
card_image, customer_logo, teaser,
--div--;Detail · Hero,
@@ -109,6 +109,17 @@ return [
'eval' => 'uniqueInPid',
],
],
'detail_page' => [
'exclude' => true,
'label' => 'Detail Page',
'description' => 'Page that presents this story. Resolved to a URL in the JSON output; leave empty to keep using the list plugin\'s Single PID plus the slug.',
'config' => [
'type' => 'group',
'allowed' => 'pages',
'size' => 1,
'maxitems' => 1,
],
],
'subtitle' => [
'label' => 'Subtitle',
'config' => ['type' => 'input', 'size' => 40, 'eval' => 'trim', 'default' => ''],