Browse Source

Add Twitter Bootstrap markup to templates (#50)

This allows out of the box integration into websites using the Twitter
Bootstrap Frontend Framework.

Resolves: #11
pull/53/head
Dirk Koritnik 9 months ago committed by GitHub
parent
commit
d23f023aa1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      Configuration/TypoScript/ContentElements/Rendering/_base.typoscript
  2. 60
      Resources/Private/Language/de.locallang.xlf
  3. 45
      Resources/Private/Language/locallang.xlf
  4. 136
      Resources/Private/Partials/Frontend/ContentElement/Accessibility.html
  5. 21
      Resources/Private/Partials/Frontend/ContentElement/Address.html
  6. 9
      Resources/Private/Partials/Frontend/ContentElement/Digital.html
  7. 9
      Resources/Private/Partials/Frontend/ContentElement/Languages.html
  8. 9
      Resources/Private/Partials/Frontend/ContentElement/Museum.html
  9. 92
      Resources/Private/Partials/Frontend/ContentElement/Offers.html
  10. 15
      Resources/Private/Partials/Frontend/ContentElement/Opening.html
  11. 8
      Resources/Private/Partials/Frontend/ContentElement/Parking.html
  12. 9
      Resources/Private/Partials/Frontend/ContentElement/Payment.html
  13. 9
      Resources/Private/Partials/Frontend/ContentElement/Photography.html
  14. 9
      Resources/Private/Partials/Frontend/ContentElement/Sanitation.html
  15. 5
      Resources/Private/Partials/Frontend/ContentElement/Service.html
  16. 9
      Resources/Private/Partials/Frontend/ContentElement/Traffic.html
  17. 258
      Resources/Private/Templates/Frontend/ContentElement/TouristAttraction.html
  18. 4
      Tests/Functional/FrontendTest.php

3
Configuration/TypoScript/ContentElements/Rendering/_base.typoscript

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

60
Resources/Private/Language/de.locallang.xlf

@ -91,6 +91,66 @@
<source>Video Guide</source>
<target>Videoguide</target>
</trans-unit>
<trans-unit id="content.tours" xml:space="preserve">
<source>Guided tours</source>
<target>Führungen</target>
</trans-unit>
<trans-unit id="content.address" xml:space="preserve">
<source>Address</source>
<target>Anschrift</target>
</trans-unit>
<trans-unit id="content.openingHours" xml:space="preserve">
<source>Opening hours</source>
<target>Öffnungszeiten</target>
</trans-unit>
<trans-unit id="content.offers" xml:space="preserve">
<source>Offers</source>
<target>Preise</target>
</trans-unit>
<trans-unit id="content.generalInformation" xml:space="preserve">
<source>General Information</source>
<target>Allgemeine Informationen</target>
</trans-unit>
<trans-unit id="content.payment" xml:space="preserve">
<source>Accepted payment</source>
<target>Akzeptierte Bezahlmethoden</target>
</trans-unit>
<trans-unit id="content.languages" xml:space="preserve">
<source>Available languages</source>
<target>Angebotene Sprachen</target>
</trans-unit>
<trans-unit id="content.sanitation" xml:space="preserve">
<source>Sanitation</source>
<target>Sanitäre Anlagen</target>
</trans-unit>
<trans-unit id="content.digital" xml:space="preserve">
<source>Digital offers</source>
<target>Digitale Angebote</target>
</trans-unit>
<trans-unit id="content.museum" xml:space="preserve">
<source>Museum services</source>
<target>Museumsangebote</target>
</trans-unit>
<trans-unit id="content.traffic" xml:space="preserve">
<source>Mobility offers</source>
<target>Mobilitätsangebote</target>
</trans-unit>
<trans-unit id="content.photography" xml:space="preserve">
<source>Photography</source>
<target>Fotografieren</target>
</trans-unit>
<trans-unit id="content.architecture" xml:space="preserve">
<source>Architecture</source>
<target>Architektur</target>
</trans-unit>
<trans-unit id="content.construction" xml:space="preserve">
<source>Year of construction</source>
<target>Baujahr</target>
</trans-unit>
<trans-unit id="content.accessibility" xml:space="preserve">
<source>Information on accessibility</source>
<target>Informationen zur Barrierefreiheit</target>
</trans-unit>
<trans-unit id="content.price.rule.PerPackage" xml:space="preserve">
<source>per package</source>
<target>pro Paket</target>

45
Resources/Private/Language/locallang.xlf

@ -137,6 +137,51 @@
<source>Imported configuration "%1$s". But had at least one error.</source>
</trans-unit>
<trans-unit id="content.tours" xml:space="preserve">
<source>Guided tours</source>
</trans-unit>
<trans-unit id="content.address" xml:space="preserve">
<source>Address</source>
</trans-unit>
<trans-unit id="content.openingHours" xml:space="preserve">
<source>Opening hours</source>
</trans-unit>
<trans-unit id="content.offers" xml:space="preserve">
<source>Offers</source>
</trans-unit>
<trans-unit id="content.generalInformation" xml:space="preserve">
<source>General Information</source>
</trans-unit>
<trans-unit id="content.payment" xml:space="preserve">
<source>Accepted payment</source>
</trans-unit>
<trans-unit id="content.languages" xml:space="preserve">
<source>Available languages</source>
</trans-unit>
<trans-unit id="content.sanitation" xml:space="preserve">
<source>Sanitation</source>
</trans-unit>
<trans-unit id="content.digital" xml:space="preserve">
<source>Digital offers</source>
</trans-unit>
<trans-unit id="content.museum" xml:space="preserve">
<source>Museum services</source>
</trans-unit>
<trans-unit id="content.traffic" xml:space="preserve">
<source>Mobility offers</source>
</trans-unit>
<trans-unit id="content.photography" xml:space="preserve">
<source>Photography</source>
</trans-unit>
<trans-unit id="content.architecture" xml:space="preserve">
<source>Architecture</source>
</trans-unit>
<trans-unit id="content.construction" xml:space="preserve">
<source>Year of construction</source>
</trans-unit>
<trans-unit id="content.accessibility" xml:space="preserve">
<source>Information on accessibility</source>
</trans-unit>
<trans-unit id="content.price.rule.PerPackage" xml:space="preserve">
<source>per package</source>
</trans-unit>

136
Resources/Private/Partials/Frontend/ContentElement/Accessibility.html

@ -0,0 +1,136 @@
<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="accordion" id="accordionShortDescriptions">
<f:if condition="{specification.shortDescriptionAllGenerations}">
<div class="accordion-item">
<h2 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>
</h2>
<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">
<h2 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>
</h2>
<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">
<h2 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>
</h2>
<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">
<h2 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>
</h2>
<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">
<h2 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>
</h2>
<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">
<h2 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>
</h2>
<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>

21
Resources/Private/Partials/Frontend/ContentElement/Address.html

@ -0,0 +1,21 @@
<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>
</p>
</div>
</html>

9
Resources/Private/Partials/Frontend/ContentElement/Digital.html

@ -0,0 +1,9 @@
<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-secondary">{f:translate(id: 'content.digitalOffer.{offer}', default: offer, extensionName: 'Thuecat')}</span>
</f:for>
</p>
</div>
</html>

9
Resources/Private/Partials/Frontend/ContentElement/Languages.html

@ -0,0 +1,9 @@
<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-secondary">{f:translate(id: 'content.availableLanguage.{language}', default: language, extensionName: 'Thuecat')}</span>
</f:for>
</p>
</div>
</html>

9
Resources/Private/Partials/Frontend/ContentElement/Museum.html

@ -0,0 +1,9 @@
<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-secondary">{f:translate(id: 'content.museumService.{service}', default: service, extensionName: 'Thuecat')}</span>
</f:for>
</p>
</div>
</html>

92
Resources/Private/Partials/Frontend/ContentElement/Offers.html

@ -0,0 +1,92 @@
<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">
<div class="accordion-item">
<h2 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} <small>({f:translate(id: 'content.price.type.{offer.type}', default: offer.type, extensionName: 'Thuecat')})</small></f:then><f:else>Preisgruppe</f:else></f:if>
</button>
</h2>
<div class="accordion-collapse collapse" id="offerPriceGroup-{key}-{uid}">
<div class="accordion-body">
<f:if condition="{offer.description}">
<div class="description">
<p><small>{offer.description}</small></p>
</div>
</f:if>
<table class="table">
<f:for each="{offer.prices}" as="price">
<tr>
<td>
<span>{price.title}</span>
</td>
<td>
{price.price -> f:format.currency(decimalSeparator: ',', thousandsSeparator: '.', decimals: 2, currencySign: price.currency)}
<small>{f:translate(id: 'content.price.rule.{price.rules.0}', default: price.rule, extensionName: 'Thuecat')}</small>
</td>
</tr>
<f:if condition="{price.description}">
<tr>
<td colspan="2" class="description">
<small>{price.description}</small>
</td>
</tr>
</f:if>
</f:for>
</table>
</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">
<h6>{offer.title} <small>({f:translate(id: 'content.price.type.{offer.type}', default: offer.type, extensionName: 'Thuecat')})</small></h6>
<f:if condition="{offer.description}">
<div class="description">
<p><small>{offer.description}</small></p>
</div>
</f:if>
<f:for each="{offer.prices}" as="price">
<table class="table">
<f:for each="{offer.prices}" as="price">
<tr>
<td>
<span>{price.title}</span>
</td>
<td>
{price.price -> f:format.currency(decimalSeparator: ',', thousandsSeparator: '.', decimals: 2, currencySign: price.currency)}
<small>{f:translate(id: 'content.price.rule.{price.rules.0}', default: price.rule, extensionName: 'Thuecat')}</small>
</td>
</tr>
<f:if condition="{price.description}">
<tr>
<td colspan="2" class="description">
<small>{price.description}</small>
</td>
</tr>
</f:if>
</f:for>
</table>
</f:for>
</div>
</div>
</f:for>
</f:section>
</html>

15
Resources/Private/Partials/Frontend/ContentElement/Opening.html

@ -0,0 +1,15 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="openingHours">
<f:for each="{openingHours}" as="openingHour">
<h6>
{openingHour.from -> f:format.date(format: 'd.m.Y')} -
{openingHour.through -> f:format.date(format: 'd.m.Y')}
</h6>
<p>
<f:for each="{openingHour.daysOfWeekWithMondayFirstWeekDay}" as="weekday">
{f:translate(id: 'content.openingHour.weekday.{weekday}', default: weekday, extensionName: 'Thuecat')} {openingHour.opens} - {openingHour.closes}<br>
</f:for>
</p>
</f:for>
</div>
</html>

8
Resources/Private/Partials/Frontend/ContentElement/Parking.html

@ -0,0 +1,8 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<div class="parking">
<f:for each="{parkingFacilitiesNearBy}" as="parkingFacility">
{parkingFacility.title}
{f:render(partial: 'Address', arguments: {address: parkingFacility.address})}
</f:for>
</div>
</html>

9
Resources/Private/Partials/Frontend/ContentElement/Payment.html

@ -0,0 +1,9 @@
<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-secondary">{f:translate(id: 'content.paymentAccepted.{payment}', default: payment, extensionName: 'Thuecat')}</span>
</f:for>
</p>
</div>
</html>

9
Resources/Private/Partials/Frontend/ContentElement/Photography.html

@ -0,0 +1,9 @@
<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-secondary">{f:translate(id: 'content.photography.{photography}', default: photography, extensionName: 'Thuecat')}</span>
</f:for>
</p>
</div>
</html>

9
Resources/Private/Partials/Frontend/ContentElement/Sanitation.html

@ -0,0 +1,9 @@
<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-secondary">{f:translate(id: 'content.sanitation.{sanitation}', default: sanitation, extensionName: 'Thuecat')}</span>
</f:for>
</p>
</div>
</html>

5
Resources/Private/Partials/Frontend/ContentElement/Service.html

@ -0,0 +1,5 @@
<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-secondary">{f:translate(id: 'content.otherService.{service}', default: service, extensionName: 'Thuecat')}</span>
</f:for>
</html>

9
Resources/Private/Partials/Frontend/ContentElement/Traffic.html

@ -0,0 +1,9 @@
<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-secondary">{f:translate(id: 'content.trafficInfrastructure.{trafficInfrastructure}', default: trafficInfrastructure, extensionName: 'Thuecat')}</span>
</f:for>
</p>
</div>
</html>

258
Resources/Private/Templates/Frontend/ContentElement/TouristAttraction.html

@ -1,174 +1,120 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
data-namespace-typo3-fluid="true">
<f:for each="{entities}" as="entity">
<h5>{entity.title} ({entity.town.title})</h5>
{entity.slogan}
{entity.description -> f:format.html()}
<f:if condition="{entity.media.mainImage}">
<f:image src="{entity.media.mainImage.url}" />
</f:if>
<f:for each="{entity.openingHours}" as="openingHour">
<p>
<f:for each="{openingHour.daysOfWeekWithMondayFirstWeekDay}" as="weekday">
{f:translate(id: 'content.openingHour.weekday.{weekday}', default: weekday, extensionName: 'Thuecat')} {openingHour.opens} - {openingHour.closes}<br>
</f:for>
{openingHour.from -> f:format.date(format: 'd.m.Y')} -
{openingHour.through -> f:format.date(format: 'd.m.Y')}
</p>
</f:for>
<f:if condition="{entity.address}">
{f:render(section: 'Address', arguments: {address: entity.address})}
</f:if>
<f:if condition="{entity.offers}">
<f:for each="{entity.offers}" as="offer">
<h3>{offer.title} ({f:translate(id: 'content.price.type.{offer.type}', default: offer.type, extensionName: 'Thuecat')})</h3>
<f:if condition="{offer.description}">
<p>{offer.description}</p>
<div class="row mb-5">
<div class="col-12 col-md-6">
<f:if condition="{entity.slogan}"><span class="badge bg-danger">{entity.slogan}</span></f:if>
<h2>{entity.title} ({entity.town.title})</h2>
{entity.description -> f:format.html()}
</div>
<div class="col-12 col-md-6">
<f:if condition="{entity.media.mainImage}">
<f:image src="{entity.media.mainImage.url}" class="img-fluid"/>
</f:if>
<f:for each="{offer.prices}" as="price">
<h4>{price.title}</h4>
<f:if condition="{price.description}">
<p>{price.description}</p>
</div>
</div>
<div class="row mb-5">
<div class="col-12 col-md-3">
<f:if condition="{entity.address}">
<h5>{f:translate(id: 'content.address', extensionName: 'Thuecat')}</h5>
{f:render(partial: 'Address', arguments: {address: entity.address})}
</f:if>
<f:if condition="{entity.distanceToPublicTransport}">
<h5>{f:translate(id: 'content.distanceToPublicTransport', extensionName: 'Thuecat')}</h5>
<p>
{entity.distanceToPublicTransport.value} {f:translate(id: 'content.unit.{entity.distanceToPublicTransport.unit}', default: entity.distanceToPublicTransport.unit, extensionName: 'Thuecat')}
</p>
</f:if>
<f:if condition="{entity.parkingFacilitiesNearBy}">
<h5>{f:translate(id: 'content.parkingFacilitiesNearBy', extensionName: 'Thuecat')}</h5>
{f:render(partial: 'Parking', arguments: {parkingFacilitiesNearBy: entity.parkingFacilitiesNearBy})}
</f:if>
</div>
<div class="col-12 col-md-3">
<h5>{f:translate(id: 'content.generalInformation', extensionName: 'Thuecat')}</h5>
<p>
<f:if condition="{entity.otherServices}">
{f:render(partial: 'Service', arguments: {otherServices: entity.otherServices})}
</f:if>
{price.price -> f:format.currency(decimalSeparator: ',', thousandsSeparator: '.', decimals: 2, currencySign: price.currency)}
<f:for each="{price.rules}" as="rule">
{f:translate(id: 'content.price.rule.{rule}', default: rule, extensionName: 'Thuecat')}
</f:for>
</f:for>
</f:for>
</f:if>
{entity.startOfConstruction}
<f:for each="{entity.sanitation}" as="sanitation">
{f:translate(id: 'content.sanitation.{sanitation}', default: sanitation, extensionName: 'thuecat')}
</f:for>
<f:for each="{entity.otherServices}" as="service">
{f:translate(id: 'content.otherService.{service}', default: service, extensionName: 'thuecat')}
</f:for>
<span class="badge bg-secondary">{f:translate(id: 'content.petsAllowed.{entity.petsAllowed}', default: entity.petsAllowed, extensionName: 'Thuecat')}</span>
<span class="badge bg-secondary">{f:translate(id: 'content.isAccessibleForFree.{entity.isAccessibleForFree}', default: entity.isAccessibleForFree, extensionName: 'Thuecat')}</span>
<span class="badge bg-secondary">{f:translate(id: 'content.publicAccess.{entity.publicAccess}', default: entity.publicAccess, extensionName: 'Thuecat')}</span>
<span class="badge bg-secondary">{f:translate(id: 'content.accessibilitySpecification.certificationStatus.{entity.accessibilitySpecification.certificationStatus}', default: entity.accessibilitySpecification.certificationStatus, extensionName: 'Thuecat')}</span>
</p>
<f:for each="{entity.museumServices}" as="service">
{f:translate(id: 'content.museumService.{service}', default: service, extensionName: 'thuecat')}
</f:for>
<f:for each="{entity.architecturalStyles}" as="style">
{f:translate(id: 'content.architecturalStyle.{style}', default: style, extensionName: 'thuecat')}
</f:for>
<f:for each="{entity.trafficInfrastructures}" as="trafficInfrastructure">
{f:translate(id: 'content.trafficInfrastructure.{trafficInfrastructure}', default: trafficInfrastructure, extensionName: 'thuecat')}
</f:for>
<f:if condition="{entity.museumServices}">
<h6>{f:translate(id: 'content.museum', extensionName: 'Thuecat')}</h6>
{f:render(partial: 'Museum', arguments: {museumServices: entity.museumServices})}
</f:if>
<f:for each="{entity.paymentAccepted}" as="payment">
{f:translate(id: 'content.paymentAccepted.{payment}', default: payment, extensionName: 'thuecat')}
</f:for>
<f:if condition="{entity.digitalOffer}">
<h6>{f:translate(id: 'content.digital', extensionName: 'Thuecat')}</h6>
{f:render(partial: 'Digital', arguments: {digitalOffer: entity.digitalOffer})}
</f:if>
<f:for each="{entity.digitalOffer}" as="offer">
{f:translate(id: 'content.digitalOffer.{offer}', default: offer, extensionName: 'thuecat')}
</f:for>
<f:if condition="{entity.trafficInfrastructures}">
<h6>{f:translate(id: 'content.traffic', extensionName: 'Thuecat')}</h6>
{f:render(partial: 'Traffic', arguments: {trafficInfrastructures: entity.trafficInfrastructures})}
</f:if>
<f:for each="{entity.photography}" as="photography">
{f:translate(id: 'content.photography.{photography}', default: photography, extensionName: 'thuecat')}
</f:for>
<f:if condition="{entity.paymentAccepted}">
<h6>{f:translate(id: 'content.payment', extensionName: 'Thuecat')}</h6>
{f:render(partial: 'Payment', arguments: {paymentAccepted: entity.paymentAccepted})}
</f:if>
{f:translate(id: 'content.petsAllowed.{entity.petsAllowed}', default: entity.petsAllowed, extensionName: 'thuecat')}
{f:translate(id: 'content.isAccessibleForFree.{entity.isAccessibleForFree}', default: entity.isAccessibleForFree, extensionName: 'thuecat')}
{f:translate(id: 'content.publicAccess.{entity.publicAccess}', default: entity.publicAccess, extensionName: 'thuecat')}
<f:if condition="{entity.availableLanguages}">
<h6>{f:translate(id: 'content.languages', extensionName: 'Thuecat')}</h6>
{f:render(partial: 'Payment', arguments: {availableLanguages: entity.availableLanguages})}
</f:if>
<f:for each="{entity.availableLanguages}" as="language">
{f:translate(id: 'content.availableLanguage.{language}', default: language, extensionName: 'thuecat')}
</f:for>
<f:if condition="{entity.sanitation}">
<h6>{f:translate(id: 'content.sanitation', extensionName: 'Thuecat')}</h6>
{f:render(partial: 'Sanitation', arguments: {sanitation: entity.sanitation})}
</f:if>
<f:if condition="{entity.distanceToPublicTransport}">
{f:translate(id: 'content.distanceToPublicTransport', extensionName: 'thuecat')} {entity.distanceToPublicTransport.value} {f:translate(id: 'content.unit.{entity.distanceToPublicTransport.unit}', default: entity.distanceToPublicTransport.unit, extensionName: 'thuecat')}
</f:if>
<f:if condition="{entity.photography}">
<h6>{f:translate(id: 'content.photography', extensionName: 'Thuecat')}</h6>
{f:render(partial: 'Photography', arguments: {photography: entity.photography})}
</f:if>
<f:if condition="{entity.parkingFacilitiesNearBy}">
{f:translate(id: 'content.parkingFacilitiesNearBy', extensionName: 'Thuecat')}
<f:for each="{entity.parkingFacilitiesNearBy}" as="parkingFacility">
{parkingFacility.title}
{f:render(section: 'Address', arguments: {address: parkingFacility.address})}
</f:for>
</f:if>
<f:if condition="{entity.startOfConstruction}">
<h6>{f:translate(id: 'content.construction', extensionName: 'Thuecat')}</h6>
<p>
<span class="badge bg-secondary">{entity.startOfConstruction}</span>
</p>
</f:if>
<f:if condition="{entity.accessibilitySpecification}">
{f:render(section: 'AccessiblitySpecification', arguments: {specification: entity.accessibilitySpecification})}
<f:if condition="{entity.architecturalStyles}">
<h6>{f:translate(id: 'content.architecture', extensionName: 'Thuecat')}</h6>
<p>
<f:for each="{entity.architecturalStyles}" as="style">
<span class="badge bg-secondary">{f:translate(id: 'content.architecturalStyle.{style}', default: style, extensionName: 'Thuecat')}</span>
</f:for>
</p>
</f:if>
</div>
<div class="col-12 col-md-3">
<f:if condition="{entity.openingHours}">
<h5>{f:translate(id: 'content.openingHours', extensionName: 'Thuecat')}</h5>
{f:render(partial: 'Opening', arguments: {openingHours: entity.openingHours})}
</f:if>
</div>
<div class="col-12 col-md-3">
<f:if condition="{entity.offers}">
<h5>{f:translate(id: 'content.offers', extensionName: 'Thuecat')}</h5>
{f:render(partial: 'Offers', arguments: {offers: entity.offers, uid: entity.uid})}
</f:if>
</div>
</div>
<f:if condition="{entity.accessibilitySpecification.certificationStatus} != ''">
<div class="row">
<div class="col-12">
<h3>{f:translate(id: 'content.accessibility', extensionName: 'Thuecat')}</h3>
{f:render(partial: 'Accessibility', arguments: {specification: entity.accessibilitySpecification, uid: entity.uid})}
</div>
</div>
</f:if>
</f:for>
<f:section name="Address">
<p>
{address.street}<br>
{address.zip} {address.city}<br>
{address.email}<br>
{address.phone}<br>
{address.fax}
</p>
</f:section>
<f:section name="AccessiblitySpecification">
{f:translate(id: 'content.accessibilitySpecification.certificationStatus.{specification.certificationStatus}', default: specification.certificationStatus, extensionName: 'Thuecat')}
<f:if condition="{specification.certificationDeaf}">
{f:translate(id: 'content.accessibilitySpecification.certification.{specification.certificationDeaf}', default: specification.certificationDeaf, extensionName: 'Thuecat')} {f:translate(id: 'content.accessibilitySpecification.certification.deaf', extensionName: 'Thuecat')}
</f:if>
<f:if condition="{specification.certificationMental}">
{f:translate(id: 'content.accessibilitySpecification.certification.{specification.certificationMental}', default: specification.certificationMental, extensionName: 'Thuecat')} {f:translate(id: 'content.accessibilitySpecification.certification.mental', extensionName: 'Thuecat')}
</f:if>
<f:if condition="{specification.certificationPartiallyDeaf}">
{f:translate(id: 'content.accessibilitySpecification.certification.{specification.certificationPartiallyDeaf}', default: specification.certificationPartiallyDeaf, extensionName: 'Thuecat')} {f:translate(id: 'content.accessibilitySpecification.certification.partiallyDeaf', extensionName: 'Thuecat')}
</f:if>
<f:if condition="{specification.certificationPartiallyVisual}">
{f:translate(id: 'content.accessibilitySpecification.certification.{specification.certificationPartiallyVisual}', default: specification.certificationPartiallyVisual, extensionName: 'Thuecat')} {f:translate(id: 'content.accessibilitySpecification.certification.partiallyVisual', extensionName: 'Thuecat')}
</f:if>
<f:if condition="{specification.certificationVisual}">
{f:translate(id: 'content.accessibilitySpecification.certification.{specification.certificationVisual}', default: specification.certificationVisual, extensionName: 'Thuecat')} {f:translate(id: 'content.accessibilitySpecification.certification.visual', extensionName: 'Thuecat')}
</f:if>
<f:if condition="{specification.certificationWalking}">
{f:translate(id: 'content.accessibilitySpecification.certification.{specification.certificationWalking}', default: specification.certificationWalking, extensionName: 'Thuecat')} {f:translate(id: 'content.accessibilitySpecification.certification.walking', extensionName: 'Thuecat')}
</f:if>
<f:if condition="{specification.certificationWheelchair}">
{f:translate(id: 'content.accessibilitySpecification.certification.{specification.certificationWheelchair}', default: specification.certificationWheelchair, extensionName: 'Thuecat')} {f:translate(id: 'content.accessibilitySpecification.certification.wheelchair', extensionName: 'Thuecat')}
</f:if>
<f:if condition="{specification.shortDescriptionAllGenerations}">
{f:translate(id: 'content.accessibilitySpecification.shortDescriptionAllGenerations', extensionName: 'Thuecat')}
<p>{specification.shortDescriptionAllGenerations -> f:format.nl2br()}</p>
</f:if>
<f:if condition="{specification.shortDescriptionAllergic}">
{f:translate(id: 'content.accessibilitySpecification.shortDescriptionAllergic', extensionName: 'Thuecat')}
<p>{specification.shortDescriptionAllergic -> f:format.nl2br()}</p>
</f:if>
<f:if condition="{specification.shortDescriptionDeaf}">
{f:translate(id: 'content.accessibilitySpecification.shortDescriptionDeaf', extensionName: 'Thuecat')}
<p>{specification.shortDescriptionDeaf -> f:format.nl2br()}</p>
</f:if>
<f:if condition="{specification.shortDescriptionMental}">
{f:translate(id: 'content.accessibilitySpecification.shortDescriptionMental', extensionName: 'Thuecat')}
<p>{specification.shortDescriptionMental -> f:format.nl2br()}</p>
</f:if>
<f:if condition="{specification.shortDescriptionVisual}">
{f:translate(id: 'content.accessibilitySpecification.shortDescriptionVisual', extensionName: 'Thuecat')}
<p>{specification.shortDescriptionVisual -> f:format.nl2br()}</p>
</f:if>
<f:if condition="{specification.shortDescriptionWalking}">
{f:translate(id: 'content.accessibilitySpecification.shortDescriptionWalking', extensionName: 'Thuecat')}
<p>{specification.shortDescriptionWalking -> f:format.nl2br()}</p>
</f:if>
<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>
</f:section>
</html>

4
Tests/Functional/FrontendTest.php

@ -74,7 +74,7 @@ class FrontendTest extends FunctionalTestCase
self::assertStringContainsString('Highlight', (string)$result->getBody());
self::assertStringContainsString('<img src="https://cms.thuecat.org/o/adaptive-media/image/5159216/Preview-1280x0/image" />', (string)$result->getBody());
self::assertStringContainsString('<img class="img-fluid" src="https://cms.thuecat.org/o/adaptive-media/image/5159216/Preview-1280x0/image" />', (string)$result->getBody());
self::assertStringContainsString('Beispielstraße 1a', (string)$result->getBody());
self::assertStringContainsString('99084', (string)$result->getBody());
@ -178,7 +178,7 @@ class FrontendTest extends FunctionalTestCase
self::assertStringContainsString('Fotografieren nicht gestattet', (string)$result->getBody());
self::assertStringContainsString('some free text value for photography', (string)$result->getBody());
self::assertStringContainsString('Entfernung zum ÖPNV: 250 Meter', (string)$result->getBody());
self::assertStringContainsString('250 Meter', (string)$result->getBody());
self::assertStringNotContainsString('Keine tiere erlaubt', (string)$result->getBody());
self::assertStringNotContainsString('Tiere erlaubt', (string)$result->getBody());

Loading…
Cancel
Save