Remove content elements

This commit is contained in:
Daniel Siepmann (Codappix) 2024-11-06 08:25:00 +01:00
parent d323a60e7a
commit 0eedec8ca9
SSH key fingerprint: SHA256:nAjx3Dpp8kuAC+S7QXj8BWmqw+KI1Miu+5e40BP3LXA
44 changed files with 64 additions and 692 deletions

View file

@ -47,7 +47,6 @@ class Extension
public static function registerExtLocalconfConfigConfig(): void
{
self::addCaching();
self::addContentElements();
self::addPageTypesExtLocalconf();
}
@ -61,31 +60,6 @@ class Extension
return 'EXT:' . self::EXTENSION_KEY . '/Resources/Public/Icons/';
}
private static function addContentElements(): void
{
$languagePath = self::getLanguagePath() . 'locallang_tca.xlf:tt_content';
// TODO: typo3/cms-core:14.0 Remove this code block as CEs are auto registered.
if (version_compare(GeneralUtility::makeInstance(Typo3Version::class)->__toString(), '13.0', '<')) {
ExtensionManagementUtility::addPageTSConfig('
mod.wizards.newContentElement.wizardItems.thuecat {
header = ' . $languagePath . '.group
show = *
elements {
thuecat_tourist_attraction{
title = ' . $languagePath . '.thuecat_tourist_attraction
description = ' . $languagePath . '.thuecat_tourist_attraction.description
iconIdentifier = tt_content_thuecat_tourist_attraction
tt_content_defValues {
CType = thuecat_tourist_attraction
}
}
}
}
');
}
}
private static function addPageTypesExtTables(): void
{
$registry = GeneralUtility::makeInstance(PageDoktypeRegistry::class);

View file

@ -8,11 +8,6 @@ use WerkraumMedia\ThueCat\Extension;
defined('TYPO3') or die();
(static function (string $extensionKey, string $tableName) {
ExtensionManagementUtility::addStaticFile(
$extensionKey,
'Configuration/TypoScript/ContentElements',
'ThüCAT - Content Elements'
);
ExtensionManagementUtility::addStaticFile(
$extensionKey,
'Configuration/TypoScript/PageTypes',

View file

@ -1,23 +0,0 @@
<?php
declare(strict_types=1);
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use WerkraumMedia\ThueCat\Extension;
defined('TYPO3') or die();
(static function (string $extensionKey, string $tableName) {
$languagePath = Extension::getLanguagePath()
. 'locallang_tca.xlf:' . $tableName;
ExtensionManagementUtility::addTcaSelectItemGroup(
$tableName,
'CType',
Extension::TCA_SELECT_GROUP_IDENTIFIER,
$languagePath . '.group'
);
})(
Extension::EXTENSION_KEY,
'tt_content'
);

View file

@ -1,71 +0,0 @@
<?php
declare(strict_types=1);
use TYPO3\CMS\Core\Utility\ArrayUtility;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use WerkraumMedia\ThueCat\Extension;
defined('TYPO3') or die();
(static function (string $extensionKey, string $tableName, string $cType) {
$languagePath = Extension::getLanguagePath()
. 'locallang_tca.xlf:' . $tableName . '.' . $cType;
ArrayUtility::mergeRecursiveWithOverrule($GLOBALS['TCA'][$tableName], [
'ctrl' => [
'typeicon_classes' => [
$cType => 'tt_content_' . $cType,
],
],
'types' => [
$cType => [
'showitem' => '--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general,'
. '--palette--;;general,'
. '--palette--;;headers,'
. 'records,'
. '--div--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.appearance,'
. '--palette--;;frames,'
. '--palette--;;appearanceLinks,'
. '--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:language,'
. '--palette--;;language,'
. '--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:access,'
. '--palette--;;hidden,'
. '--palette--;;access,'
. '--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:categories,'
. '--div--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_category.tabs.category,'
. 'categories,'
. '--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:notes,'
. 'rowDescription,'
. '--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:extended',
'columnsOverrides' => [
'records' => [
'config' => [
'allowed' => 'tx_thuecat_tourist_attraction',
'suggestOptions' => [
'tx_thuecat_tourist_attraction' => [
'addWhere' => 'sys_language_uid in (0,-1)',
],
],
],
],
],
],
],
]);
ExtensionManagementUtility::addTcaSelectItem(
$tableName,
'CType',
[
'label' => $languagePath,
'value' => $cType,
'icon' => 'tt_content_' . $cType,
'group' => Extension::TCA_SELECT_GROUP_IDENTIFIER,
]
);
})(
Extension::EXTENSION_KEY,
'tt_content',
'thuecat_tourist_attraction'
);

View file

@ -1,13 +0,0 @@
tt_content {
thuecat_tourist_attraction =< lib.thuecatContentElement
thuecat_tourist_attraction {
templateName = TouristAttraction
dataProcessing {
10 = WerkraumMedia\ThueCat\Frontend\DataProcessing\ResolveEntities
10 {
table = tx_thuecat_tourist_attraction
uids.data = field:records
}
}
}
}

View file

@ -1,9 +0,0 @@
lib.thuecatContentElement =< lib.contentElement
lib.thuecatContentElement {
partialRootPaths {
0 = EXT:thuecat/Resources/Private/Partials/Frontend/ContentElement/
}
templateRootPaths {
0 = EXT:thuecat/Resources/Private/Templates/Frontend/ContentElement/
}
}

View file

@ -1 +0,0 @@
@import 'EXT:thuecat/Configuration/TypoScript/ContentElements/Rendering/*.typoscript'

View file

@ -1,10 +1,13 @@
3.1.0
4.0.0
=====
Breaking
--------
Nothing
* Removed content element.
No Content element is provided any longer.
We recommend to build your own tailored content elements instead.
Features
--------

View file

@ -308,16 +308,6 @@
<source>Created</source>
</trans-unit>
<trans-unit id="tt_content.group" xml:space="preserve">
<source>ThüCAT</source>
</trans-unit>
<trans-unit id="tt_content.thuecat_tourist_attraction" xml:space="preserve">
<source>Tourist Attraction</source>
</trans-unit>
<trans-unit id="tt_content.thuecat_tourist_attraction.description" xml:space="preserve">
<source>Renders selected tourist attractions</source>
</trans-unit>
<trans-unit id="pages.group" xml:space="preserve">
<source>ThüCAT</source>
</trans-unit>

View file

@ -1,165 +0,0 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="thuecat">
<f:for each="{entities}" as="entity">
<div class="row thuecat__abstract">
<div class="col-12 col-md-6">
<f:if condition="{entity.slogan}"><span class="badge bg-danger">{entity.slogan}</span></f:if>
<h1>{entity.title} ({entity.town.title})</h1>
{entity.description -> f:format.html()}
</div>
<div class="col-12 col-md-6 order-first order-md-last">
<f:if condition="{entity.media.mainImage}">
<img class="img-fluid" src="{entity.media.mainImage.url}" />
<f:if condition="{entity.media.mainImage.author}">
<p>ⓒ {entity.media.mainImage.author}</p>
</f:if>
</f:if>
</div>
</div>
<div class="row thuecat__address">
<f:if condition="{entity.parkingFacilitiesNearBy -> f:count()} > 3">
<f:then>
<div class="col-md-4">
<f:if condition="{entity.address}">
<img src="{f:uri.resource(path:'Icons/icon-info.svg', extensionName:'Thuecat')}" width="30" class="svg-icon" alt="Address">
<h2>{f:translate(id: 'content.address', extensionName: 'Thuecat')}</h2>
{f:render(partial: 'Address', arguments: {address: entity.address, url: entity.url})}
</f:if>
<f:if condition="{entity.distanceToPublicTransport}">
<div class="distance-transport mt-5">
<img src="{f:uri.resource(path:'Icons/icon-bus.svg', extensionName:'Thuecat')}" width="30" class="svg-icon" alt="Address">
<h2>{f:translate(id: 'content.distanceToPublicTransport', extensionName: 'Thuecat')}</h2>
<p>
{entity.distanceToPublicTransport.value} {f:translate(id: 'content.unit.{entity.distanceToPublicTransport.unit}', default: entity.distanceToPublicTransport.unit, extensionName: 'Thuecat')}
</p>
</div>
</f:if>
</div>
<div class="col-md-8 multiple-parking">
<f:if condition="{entity.parkingFacilitiesNearBy}">
<img src="{f:uri.resource(path:'Icons/icon-parking.svg', extensionName:'Thuecat')}" width="30" class="svg-icon" alt="Address">
<h2>{f:translate(id: 'content.parkingFacilitiesNearBy', extensionName: 'Thuecat')}</h2>
{f:render(partial: 'Parking', arguments: {parkingFacilitiesNearBy: entity.parkingFacilitiesNearBy})}
</f:if>
</div>
</f:then>
<f:else>
<div class="col-md-4">
<f:if condition="{entity.address}">
<img src="{f:uri.resource(path:'Icons/icon-info.svg', extensionName:'Thuecat')}" width="30" class="svg-icon" alt="Address">
<h2>{f:translate(id: 'content.address', extensionName: 'Thuecat')}</h2>
{f:render(partial: 'Address', arguments: {address: entity.address, url: entity.url})}
</f:if>
</div>
<div class="col-md-4">
<f:if condition="{entity.distanceToPublicTransport}">
<img src="{f:uri.resource(path:'Icons/icon-bus.svg', extensionName:'Thuecat')}" width="30" class="svg-icon" alt="Address">
<h2>{f:translate(id: 'content.distanceToPublicTransport', extensionName: 'Thuecat')}</h2>
<p>
{entity.distanceToPublicTransport.value} {f:translate(id: 'content.unit.{entity.distanceToPublicTransport.unit}', default: entity.distanceToPublicTransport.unit, extensionName: 'Thuecat')}
</p>
</f:if>
</div>
<div class="col-md-4">
<f:if condition="{entity.parkingFacilitiesNearBy}">
<img src="{f:uri.resource(path:'Icons/icon-parking.svg', extensionName:'Thuecat')}" width="30" class="svg-icon" alt="Address">
<h2>{f:translate(id: 'content.parkingFacilitiesNearBy', extensionName: 'Thuecat')}</h2>
{f:render(partial: 'Parking', arguments: {parkingFacilitiesNearBy: entity.parkingFacilitiesNearBy})}
</f:if>
</div>
</f:else>
</f:if>
</div>
<div class="row thuecat__services">
<f:if condition="{entity.generalInformation} || {entity.otherServices} || {entity.petsAllowed} || {entity.isAccessibleForFree}
|| {entity.publicAccess} || {entity.accessibilitySpecification.certificationStatus} || {entity.museumServices}
|| {entity.digitalOffer} || {entity.trafficInfrastructures} || {entity.paymentAccepted} || {entity.availableLanguages}
|| {entity.sanitation} || {entity.photography} || {entity.startOfConstruction} || {entity.architecturalStyles}"
>
<div class="col-md-6">
<h2>{f:translate(id: 'content.generalInformation', extensionName: 'Thuecat')}</h2>
<p>
<f:if condition="{entity.otherServices}">
{f:render(partial: 'Service', arguments: {otherServices: entity.otherServices})}
</f:if>
<span class="badge bg-light">{f:translate(id: 'content.petsAllowed.{entity.petsAllowed}', default: entity.petsAllowed, extensionName: 'Thuecat')}</span>
<span class="badge bg-light">{f:translate(id: 'content.isAccessibleForFree.{entity.isAccessibleForFree}', default: entity.isAccessibleForFree, extensionName: 'Thuecat')}</span>
<span class="badge bg-light">{f:translate(id: 'content.publicAccess.{entity.publicAccess}', default: entity.publicAccess, extensionName: 'Thuecat')}</span>
<span class="badge bg-light">{f:translate(id: 'content.accessibilitySpecification.certificationStatus.{entity.accessibilitySpecification.certificationStatus}', default: entity.accessibilitySpecification.certificationStatus, extensionName: 'Thuecat')}</span>
</p>
<f:if condition="{entity.museumServices}">
<h3>{f:translate(id: 'content.museum', extensionName: 'Thuecat')}</h3>
{f:render(partial: 'Museum', arguments: {museumServices: entity.museumServices})}
</f:if>
<f:if condition="{entity.digitalOffer}">
<h3>{f:translate(id: 'content.digital', extensionName: 'Thuecat')}</h3>
{f:render(partial: 'Digital', arguments: {digitalOffer: entity.digitalOffer})}
</f:if>
<f:if condition="{entity.trafficInfrastructures}">
<h3>{f:translate(id: 'content.traffic', extensionName: 'Thuecat')}</h3>
{f:render(partial: 'Traffic', arguments: {trafficInfrastructures: entity.trafficInfrastructures})}
</f:if>
<f:if condition="{entity.paymentAccepted}">
<h3>{f:translate(id: 'content.payment', extensionName: 'Thuecat')}</h3>
{f:render(partial: 'Payment', arguments: {paymentAccepted: entity.paymentAccepted})}
</f:if>
<f:if condition="{entity.availableLanguages}">
<h3>{f:translate(id: 'content.languages', extensionName: 'Thuecat')}</h3>
{f:render(partial: 'Payment', arguments: {availableLanguages: entity.availableLanguages})}
</f:if>
<f:if condition="{entity.sanitation}">
<h3>{f:translate(id: 'content.sanitation', extensionName: 'Thuecat')}</h3>
sanitation
{f:render(partial: 'Sanitation', arguments: {sanitation: entity.sanitation})}
</f:if>
<f:if condition="{entity.photography}">
<h3>{f:translate(id: 'content.photography', extensionName: 'Thuecat')}</h3>
{f:render(partial: 'Photography', arguments: {photography: entity.photography})}
</f:if>
<f:if condition="{entity.startOfConstruction}">
<h3>{f:translate(id: 'content.construction', extensionName: 'Thuecat')}</h3>
<p>
<span class="badge bg-light">{entity.startOfConstruction}</span>
</p>
</f:if>
<f:if condition="{entity.architecturalStyles}">
<h3>{f:translate(id: 'content.architecture', extensionName: 'Thuecat')}</h3>
<p>
<f:for each="{entity.architecturalStyles}" as="style">
<span class="badge bg-light">{f:translate(id: 'content.architecturalStyle.{style}', default: style, extensionName: 'Thuecat')}</span>
</f:for>
</p>
</f:if>
</div>
</f:if>
<f:if condition="{entity.openingHours}">
<div class="col-md-6">
<h2>{f:translate(id: 'content.openingHours', extensionName: 'Thuecat')}</h2>
{f:render(partial: 'Opening', arguments: {openingHours: entity.openingHours})}
</div>
</f:if>
<f:if condition="{entity.specialOpeningHours}">
<div class="col-md-6">
<h2>{f:translate(id: 'content.specialOpeningHours', extensionName: 'Thuecat')}</h2>
{f:render(partial: 'Opening', arguments: {openingHours: entity.specialOpeningHours})}
</div>
</f:if>
</div>
<div class="thuecat__offers">
<f:if condition="{entity.offers}">
<div class="row">
<h2 class="text-center">{f:translate(id: 'content.offers', extensionName: 'Thuecat')}</h2>
{f:render(partial: 'Offers', arguments: {offers: entity.offers, uid: entity.uid})}
</div>
</f:if>
<f:if condition="{entity.accessibilitySpecification.certificationStatus} != ''">
<div class="row">
<h2 class="text-center">{f:translate(id: 'content.accessibility', extensionName: 'Thuecat')}</h2>
{f:render(partial: 'Accessibility', arguments: {specification: entity.accessibilitySpecification, uid: entity.uid})}
</div>
</f:if>
</div>
</f:for>
</div>
</html>

View file

@ -0,0 +1,28 @@
{
"name": "werkraummedia/example",
"description": "Example extension for functional tests",
"type": "typo3-cms-extension",
"license": "GPL-2.0-or-later",
"homepage": "https://github.com/werkraum-media/thuecat",
"authors": [
{
"name": "Daniel Siepmann",
"email": "coding@daniel-siepmann.de",
"homepage": "https://daniel-siepmann.de/",
"role": "Developer"
}
],
"autoload": {
"psr-4": {
"WerkraumMedia\\Example\\": "Classes/"
}
},
"require": {
"werkraummedia/thuecat": "*"
},
"extra": {
"typo3/cms": {
"extension-key": "example"
}
}
}

View file

@ -1,11 +1,23 @@
page = PAGE
page.10 < styles.content.get
lib.thuecatContentElement {
partialRootPaths {
0 = EXT:thuecat/Tests/Functional/Fixtures/Frontend/Resources/Private/Partials/ContentElement/
}
templateRootPaths {
0 = EXT:thuecat/Tests/Functional/Fixtures/Frontend/Resources/Private/Templates/ContentElement/
tt_content.thuecat_tourist_attraction =< lib.contentElement
tt_content.thuecat_tourist_attraction {
templateName = TouristAttraction
dataProcessing {
10 = WerkraumMedia\ThueCat\Frontend\DataProcessing\ResolveEntities
10 {
table = tx_thuecat_tourist_attraction
uids.data = field:records
}
}
}
lib.contentElement {
partialRootPaths {
10 = EXT:example/Resources/Private/Partials/ContentElement/
}
templateRootPaths {
10 = EXT:example/Resources/Private/Templates/ContentElement/
}
}

View file

@ -1,136 +0,0 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="accessibility">
<div class="row">
<div class="col-12 col-md-6">
<f:if condition="{specification.searchCriteria}">
<ul>
<f:for each="{specification.searchCriteria}" key="id" as="criterias">
<f:for each="{criterias}" as="criteria">
<li>{f:translate(id: 'content.accessibilitySpecification.searchCriteria.criteria.{criteria}', default: criteria, extensionName: 'Thuecat')}</li>
</f:for>
</f:for>
</ul>
</f:if>
</div>
<div class="col-12 col-md-6">
<ul>
<f:if condition="{specification.certificationDeaf}">
<li>{f:translate(id: 'content.accessibilitySpecification.certification.{specification.certificationDeaf}', default: specification.certificationDeaf, extensionName: 'Thuecat')} {f:translate(id: 'content.accessibilitySpecification.certification.deaf', extensionName: 'Thuecat')}</li>
</f:if>
<f:if condition="{specification.certificationMental}">
<li>{f:translate(id: 'content.accessibilitySpecification.certification.{specification.certificationMental}', default: specification.certificationMental, extensionName: 'Thuecat')} {f:translate(id: 'content.accessibilitySpecification.certification.mental', extensionName: 'Thuecat')}</li>
</f:if>
<f:if condition="{specification.certificationPartiallyDeaf}">
<li>{f:translate(id: 'content.accessibilitySpecification.certification.{specification.certificationPartiallyDeaf}', default: specification.certificationPartiallyDeaf, extensionName: 'Thuecat')} {f:translate(id: 'content.accessibilitySpecification.certification.partiallyDeaf', extensionName: 'Thuecat')}</li>
</f:if>
<f:if condition="{specification.certificationPartiallyVisual}">
<li>{f:translate(id: 'content.accessibilitySpecification.certification.{specification.certificationPartiallyVisual}', default: specification.certificationPartiallyVisual, extensionName: 'Thuecat')} {f:translate(id: 'content.accessibilitySpecification.certification.partiallyVisual', extensionName: 'Thuecat')}</li>
</f:if>
<f:if condition="{specification.certificationVisual}">
<li>{f:translate(id: 'content.accessibilitySpecification.certification.{specification.certificationVisual}', default: specification.certificationVisual, extensionName: 'Thuecat')} {f:translate(id: 'content.accessibilitySpecification.certification.visual', extensionName: 'Thuecat')}</li>
</f:if>
<f:if condition="{specification.certificationWalking}">
<li>{f:translate(id: 'content.accessibilitySpecification.certification.{specification.certificationWalking}', default: specification.certificationWalking, extensionName: 'Thuecat')} {f:translate(id: 'content.accessibilitySpecification.certification.walking', extensionName: 'Thuecat')}</li>
</f:if>
<f:if condition="{specification.certificationWheelchair}">
<li>{f:translate(id: 'content.accessibilitySpecification.certification.{specification.certificationWheelchair}', default: specification.certificationWheelchair, extensionName: 'Thuecat')} {f:translate(id: 'content.accessibilitySpecification.certification.wheelchair', extensionName: 'Thuecat')}</li>
</f:if>
</ul>
</div>
</div>
<div class="row accordion" id="accordionShortDescriptions">
<f:if condition="{specification.shortDescriptionAllGenerations}">
<div class="accordion-item">
<h3 class="accordion-header" id="headingAllGenerations">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#shortDescriptionAllGenerations-{uid}" role="button" aria-expanded="false" aria-controls="shortDescriptionAllGenerations-{uid}">
{f:translate(id: 'content.accessibilitySpecification.shortDescriptionAllGenerations', extensionName: 'Thuecat')}
</button>
</h3>
<div class="accordion-collapse collapse" id="shortDescriptionAllGenerations-{uid}">
<div class="accordion-body">
<p>{specification.shortDescriptionAllGenerations -> f:format.nl2br()}</p>
</div>
</div>
</div>
</f:if>
<f:if condition="{specification.shortDescriptionAllergic}">
<div class="accordion-item">
<h3 class="accordion-header" id="headingAllergic">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#shortDescriptionAllergic-{uid}" role="button" aria-expanded="false" aria-controls="shortDescriptionAllergic-{uid}">
{f:translate(id: 'content.accessibilitySpecification.shortDescriptionAllergic', extensionName: 'Thuecat')}
</button>
</h3>
<div class="accordion-collapse collapse" id="shortDescriptionAllergic-{uid}">
<div class="accordion-body">
<p>{specification.shortDescriptionAllergic -> f:format.nl2br()}</p>
</div>
</div>
</div>
</f:if>
<f:if condition="{specification.shortDescriptionDeaf}">
<div class="accordion-item">
<h3 class="accordion-header" id="headingDeaf">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#shortDescriptionDeaf-{uid}" role="button" aria-expanded="false" aria-controls="shortDescriptionDeaf-{uid}">
{f:translate(id: 'content.accessibilitySpecification.shortDescriptionDeaf', extensionName: 'Thuecat')}
</button>
</h3>
<div class="accordion-collapse collapse" id="shortDescriptionDeaf-{uid}">
<div class="accordion-body">
<p>{specification.shortDescriptionDeaf -> f:format.nl2br()}</p>
</div>
</div>
</div>
</f:if>
<f:if condition="{specification.shortDescriptionMental}">
<div class="accordion-item">
<h3 class="accordion-header" id="headingMetal">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" href="#shortDescriptionMental-{uid}" role="button" aria-expanded="false" aria-controls="shortDescriptionMental-{uid}">
{f:translate(id: 'content.accessibilitySpecification.shortDescriptionMental', extensionName: 'Thuecat')}
</button>
</h3>
<div class="accordion-collapse collapse" id="shortDescriptionMental-{uid}">
<div class="accordion-body">
<p>{specification.shortDescriptionMental -> f:format.nl2br()}</p>
</div>
</div>
</div>
</f:if>
<f:if condition="{specification.shortDescriptionVisual}">
<div class="accordion-item">
<h3 class="accordion-header" id="headingVisual">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" href="#shortDescriptionVisual-{uid}" role="button" aria-expanded="false" aria-controls="shortDescriptionVisual-{uid}">
{f:translate(id: 'content.accessibilitySpecification.shortDescriptionVisual', extensionName: 'Thuecat')}
</button>
</h3>
<div class="accordion-collapse collapse" id="shortDescriptionVisual-{uid}">
<div class="accordion-body">
<p>{specification.shortDescriptionVisual -> f:format.nl2br()}</p>
</div>
</div>
</div>
</f:if>
<f:if condition="{specification.shortDescriptionWalking}">
<div class="accordion-item">
<h3 class="accordion-header" id="headingVisual">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" href="#shortDescriptionWalking-{uid}" role="button" aria-expanded="false" aria-controls="shortDescriptionWalking-{uid}">
{f:translate(id: 'content.accessibilitySpecification.shortDescriptionWalking', extensionName: 'Thuecat')}
</button>
</h3>
<div class="accordion-collapse collapse" id="shortDescriptionWalking-{uid}">
<div class="accordion-body">
<p>{specification.shortDescriptionWalking -> f:format.nl2br()}</p>
</div>
</div>
</div>
</f:if>
</div>
</div>
</html>

View file

@ -1,24 +0,0 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="address">
<p>
<f:if condition="{address.street}">
{address.street}<br>
</f:if>
<f:if condition="{address.zip} && {address.city}">
{address.zip} {address.city}<br>
</f:if>
<f:if condition="{address.email}">
<f:link.email email="{address.email}">{address.email}</f:link.email><br>
</f:if>
<f:if condition="{address.phone}">
<a href="tel:{address.phone}">{address.phone}</a><br>
</f:if>
<f:if condition="{address.fax}">
{address.fax}
</f:if>
<f:if condition="{url}">
<a href="{url}" referrerpolicy="no-referrer" rel="noreferrer noopener">{f:translate(id: 'content.url', extensionName: 'Thuecat')}</a>
</f:if>
</p>
</div>
</html>

View file

@ -1,9 +0,0 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="digital">
<p>
<f:for each="{digitalOffer}" as="offer">
<span class="badge bg-light">{f:translate(id: 'content.digitalOffer.{offer}', default: offer, extensionName: 'Thuecat')}</span>
</f:for>
</p>
</div>
</html>

View file

@ -1,9 +0,0 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="languages">
<p>
<f:for each="{availableLanguages}" as="language">
<span class="badge bg-light">{f:translate(id: 'content.availableLanguage.{language}', default: language, extensionName: 'Thuecat')}</span>
</f:for>
</p>
</div>
</html>

View file

@ -1,9 +0,0 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="museum">
<p>
<f:for each="{museumServices}" as="service">
<span class="badge bg-light">{f:translate(id: 'content.museumService.{service}', default: service, extensionName: 'Thuecat')}</span>
</f:for>
</p>
</div>
</html>

View file

@ -1,80 +0,0 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="offers">
<f:if condition="{offers -> f:count()} > 1">
<f:then>
<f:render section="MultiOffers" arguments="{offers: offers, uid: uid}" />
</f:then>
<f:else>
<f:render section="SingleOffer" arguments="{offers: offers}" />
</f:else>
</f:if>
</div>
<f:section name="MultiOffers">
<div class="accordion" id="accordionOfferPrices">
<f:for each="{offers}" as="offer" key="key" iteration="iterator">
<div class="accordion-item">
<h3 class="accordion-header">
<button class="accordion-button collapsed" data-bs-toggle="collapse" data-bs-target="#offerPriceGroup-{key}-{uid}" role="button" aria-expanded="false" aria-controls="offerGroup-{key}-{uid}">
<f:if condition="{offer.title}"><f:then>{offer.title} <span class="ps-1">({f:translate(id: 'content.price.type.{offer.type}', default: offer.type, extensionName: 'Thuecat')})</span></f:then><f:else>Preisgruppe</f:else></f:if>
</button>
</h3>
<div class="accordion-collapse collapse" id="offerPriceGroup-{key}-{uid}">
<div class="accordion-body row">
<f:if condition="{offer.description}">
<div class="description col-md-4">
<p><small>{offer.description}</small></p>
</div>
</f:if>
<div class="prices col-md-8">
<div class="row">
<f:for each="{offer.prices}" as="price">
<div class="price-item col-md-5">
<strong>{price.title}</strong>
<span>{price.price -> f:format.currency(decimalSeparator: ',', thousandsSeparator: '.', decimals: 2, currencySign: price.currency)}</span>
<small>{f:translate(id: 'content.price.rule.{price.rules.0}', default: price.rule, extensionName: 'Thuecat')}</small>
<f:if condition="{price.description}">
<p><small>{price.description}</small></p>
</f:if>
</div>
</f:for>
</div>
</div>
</div>
</div>
</div>
</f:for>
</div>
</f:section>
<f:section name="SingleOffer">
<f:for each="{offers}" as="offer" key="key">
<div class="offer-group">
<div class="content">
<h3>{offer.title} <span class="ps-1">({f:translate(id: 'content.price.type.{offer.type}', default: offer.type, extensionName: 'Thuecat')})</span></h3>
<div class="row">
<f:if condition="{offer.description}">
<div class="description col-md-4">
<p><small>{offer.description}</small></p>
</div>
</f:if>
<div class="prices col-md-8">
<div class="masonry-prices row">
<f:for each="{offer.prices}" as="price">
<div class="price-item col-md-5">
<strong>{price.title}</strong>
<span>{price.price -> f:format.currency(decimalSeparator: ',', thousandsSeparator: '.', decimals: 2, currencySign: price.currency)}</span>
<small>{f:translate(id: 'content.price.rule.{price.rules.0}', default: price.rule, extensionName: 'Thuecat')}</small>
<f:if condition="{price.description}">
<p><small>{price.description}</small></p>
</f:if>
</div>
</f:for>
</div>
</div>
</div>
</div>
</div>
</f:for>
</f:section>
</html>

View file

@ -1,27 +0,0 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="openingHours row">
<f:for each="{openingHours}" as="openingHour">
<f:if condition="{openingHours -> f:count()} == 1">
<f:then>
<div class="col-12">
</f:then>
<f:else>
<div class="col-md-6">
</f:else>
</f:if>
<h3>
{openingHour.from -> f:format.date(format: 'd.m.Y')} -
{openingHour.through -> f:format.date(format: 'd.m.Y')}
</h3>
<div>
<f:for each="{openingHour.daysOfWeekWithMondayFirstWeekDay}" as="weekday">
<div class="day-row">
<div class="day"><span>{f:translate(id: 'content.openingHour.weekday.{weekday}', default: weekday, extensionName: 'Thuecat')}</span></div>
<div class="time"><span>{openingHour.opens} - {openingHour.closes}</span></div>
</div>
</f:for>
</div>
</div>
</f:for>
</div>
</html>

View file

@ -1,22 +0,0 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="parking">
<f:if condition="{parkingFacilitiesNearBy -> f:count()} > 3">
<f:then>
<div class="row">
<f:for each="{parkingFacilitiesNearBy}" as="parkingFacility">
<div class="col-md-6">
{parkingFacility.title}
{f:render(partial: 'Address', arguments: {address: parkingFacility.address})}
</div>
</f:for>
</div>
</f:then>
<f:else>
<f:for each="{parkingFacilitiesNearBy}" as="parkingFacility">
{parkingFacility.title}
{f:render(partial: 'Address', arguments: {address: parkingFacility.address})}
</f:for>
</f:else>
</f:if>
</div>
</html>

View file

@ -1,9 +0,0 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="payment">
<p>
<f:for each="{paymentAccepted}" as="payment">
<span class="badge bg-light">{f:translate(id: 'content.paymentAccepted.{payment}', default: payment, extensionName: 'Thuecat')}</span>
</f:for>
</p>
</div>
</html>

View file

@ -1,9 +0,0 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="photography">
<p>
<f:for each="{photography}" as="photography">
<span class="badge bg-light">{f:translate(id: 'content.photography.{photography}', default: photography, extensionName: 'Thuecat')}</span>
</f:for>
</p>
</div>
</html>

View file

@ -1,9 +0,0 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="sanitation">
<p>
<f:for each="{sanitation}" as="sanitation">
<span class="badge bg-light">{f:translate(id: 'content.sanitation.{sanitation}', default: sanitation, extensionName: 'Thuecat')}</span>
</f:for>
</p>
</div>
</html>

View file

@ -1,5 +0,0 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<f:for each="{otherServices}" as="service">
<span class="badge bg-light">{f:translate(id: 'content.otherService.{service}', default: service, extensionName: 'Thuecat')}</span>
</f:for>
</html>

View file

@ -1,9 +0,0 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="traffic">
<p>
<f:for each="{trafficInfrastructures}" as="trafficInfrastructure">
<span class="badge bg-light">{f:translate(id: 'content.trafficInfrastructure.{trafficInfrastructure}', default: trafficInfrastructure, extensionName: 'Thuecat')}</span>
</f:for>
</p>
</div>
</html>

View file

@ -42,6 +42,7 @@ class FrontendTest extends FunctionalTestCase
$this->testExtensionsToLoad = [
'werkraummedia/thuecat',
'typo3conf/ext/thuecat/Tests/Functional/Fixtures/Frontend/Extensions/example/',
];
$this->pathsToLinkInTestInstance = [

View file

@ -74,6 +74,12 @@
"phpstan/extension-installer": true
}
},
"scripts": {
"post-autoload-dump": [
"mkdir -p .Build/web/typo3conf/ext/",
"[ -L .Build/web/typo3conf/ext/thuecat ] || ln -snvf ../../../../. .Build/web/typo3conf/ext/thuecat"
]
},
"extra": {
"typo3/cms": {
"cms-package-dir": "{$vendor-dir}/typo3/cms",

View file

@ -10,7 +10,7 @@ $EM_CONF['thuecat'] = [
'author' => 'Daniel Siepmann',
'author_email' => 'coding@daniel-siepmann.de',
'author_company' => '',
'version' => '3.1.0',
'version' => '4.0.0',
'constraints' => [
'depends' => [
'core' => '',

View file

@ -1,5 +1,7 @@
<?php
declare(strict_types=1);
use WerkraumMedia\ThueCat\Extension;
Extension::registerExtTablesConfig();

View file

@ -1,7 +1,7 @@
{ pkgs ? import <nixpkgs> { } }:
let
php = pkgs.php82.buildEnv {
php = pkgs.php83.buildEnv {
extensions = { enabled, all }: enabled ++ (with all; [
xdebug
]);
@ -11,7 +11,7 @@ let
memory_limit = 4G
'';
};
inherit(pkgs.php82Packages) composer;
inherit(php.packages) composer;
projectInstall = pkgs.writeShellApplication {
name = "project-install";
@ -49,7 +49,7 @@ let
'';
};
in pkgs.mkShell {
in pkgs.mkShellNoCC {
name = "TYPO3 Extension ThüCAT";
buildInputs = [
php