Compare commits
9
Commits
f9e94231a7
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9b3550ec40 | ||
|
|
d9943619f6 | ||
|
|
e33b57c9f1 | ||
|
|
dc594efee1 | ||
|
|
432d8da350 | ||
|
|
5b338eeab6 | ||
|
|
05ceae5100 | ||
|
|
f005272242 | ||
|
|
7d856d1031 |
+77
-41
@@ -1,9 +1,8 @@
|
||||
name: ep-reisen
|
||||
type: typo3
|
||||
docroot: public
|
||||
php_version: "7.4"
|
||||
webserver_type: nginx-fpm
|
||||
router_http_port: "80"
|
||||
router_https_port: "443"
|
||||
xdebug_enabled: false
|
||||
additional_hostnames:
|
||||
- ep-events
|
||||
@@ -16,36 +15,57 @@ additional_hostnames:
|
||||
additional_fqdns: []
|
||||
database:
|
||||
type: mariadb
|
||||
version: "10.2"
|
||||
version: "11.4"
|
||||
hooks:
|
||||
post-start:
|
||||
- exec: .ddev/claude-code/install.sh
|
||||
- exec: .ddev/codex-cli/install.sh
|
||||
webimage_extra_packages: [ripgrep, bubblewrap, socat]
|
||||
use_dns_when_possible: true
|
||||
timezone: Europe/Berlin
|
||||
composer_version: "2"
|
||||
web_environment:
|
||||
- TYPO3_CONTEXT=Development
|
||||
nodejs_version: "18"
|
||||
corepack_enable: false
|
||||
|
||||
# Key features of DDEV's config.yaml:
|
||||
|
||||
# name: <projectname> # Name of the project, automatically provides
|
||||
# http://projectname.ddev.site and https://projectname.ddev.site
|
||||
# If the name is omitted, the project will take the name of the enclosing directory,
|
||||
# which is useful if you want to have a copy of the project side by side with this one.
|
||||
|
||||
# type: <projecttype> # drupal6/7/8, backdrop, typo3, wordpress, php
|
||||
# type: <projecttype> # asterios, backdrop, cakephp, codeigniter, craftcms, drupal, drupal6, drupal7, drupal8, drupal9, drupal10, drupal11, drupal12, generic, joomla, laravel, magento, magento2, maho, modx, php, shopware6, silverstripe, symfony, typo3, wordpress, wp-bedrock
|
||||
# See https://docs.ddev.com/en/stable/users/quickstart/ for more
|
||||
# information on the different project types
|
||||
|
||||
# docroot: <relative_path> # Relative path to the directory containing index.php.
|
||||
|
||||
# php_version: "8.1" # PHP version to use, "5.6", "7.0", "7.1", "7.2", "7.3", "7.4", "8.0", "8.1", "8.2", "8.3"
|
||||
# php_version: "8.4" # PHP version to use, "5.6" through "8.5"
|
||||
|
||||
# You can explicitly specify the webimage but this
|
||||
# is not recommended, as the images are often closely tied to DDEV's' behavior,
|
||||
# is not recommended, as the images are often closely tied to DDEV's behavior,
|
||||
# so this can break upgrades.
|
||||
|
||||
# webimage: <docker_image> # nginx/php docker image.
|
||||
# webimage: <docker_image>
|
||||
# It’s unusual to change this option, and we don’t recommend it without Docker experience and a good reason.
|
||||
# Typically, this means additions to the existing web image using a .ddev/web-build/Dockerfile.*
|
||||
|
||||
# database:
|
||||
# type: <dbtype> # mysql, mariadb, postgres
|
||||
# version: <version> # database version, like "10.4" or "8.0"
|
||||
# MariaDB versions can be 5.5-10.8 and 10.11, MySQL versions can be 5.5-8.0
|
||||
# PostgreSQL versions can be 9-16.
|
||||
# version: <version> # database version, like "10.11" or "8.0"
|
||||
# MariaDB versions can be 5.5-10.8, 10.11, 11.4, 11.8, 12.3
|
||||
# MySQL versions can be 5.5-8.0, 8.4, 9.7
|
||||
# PostgreSQL versions can be 9-18
|
||||
|
||||
# You can explicitly specify the dbimage but this
|
||||
# is not recommended, as the images are often closely tied to DDEV's behavior,
|
||||
# so this can break upgrades.
|
||||
|
||||
# dbimage: <docker_image>
|
||||
# It’s unusual to change this option, and we don’t recommend it without Docker experience and a good reason.
|
||||
# Typically, this means additions to the existing db image using a .ddev/db-build/Dockerfile.*
|
||||
|
||||
# router_http_port: <port> # Port to be used for http (defaults to global configuration, usually 80)
|
||||
# router_https_port: <port> # Port for https (defaults to global configuration, usually 443)
|
||||
@@ -55,14 +75,24 @@ nodejs_version: "18"
|
||||
# "ddev xdebug" to enable Xdebug and "ddev xdebug off" to disable it work better,
|
||||
# as leaving Xdebug enabled all the time is a big performance hit.
|
||||
|
||||
# xhprof_enabled: false # Set to true to enable Xhprof and "ddev start" or "ddev restart"
|
||||
# Note that for most people the commands
|
||||
# "ddev xhprof" to enable Xhprof and "ddev xhprof off" to disable it work better,
|
||||
# as leaving Xhprof enabled all the time is a big performance hit.
|
||||
# xhgui_http_port: "8143"
|
||||
# xhgui_https_port: "8142"
|
||||
# The XHGui ports can be changed from the default 8143 and 8142
|
||||
# Very rarely used
|
||||
|
||||
# webserver_type: nginx-fpm, apache-fpm, or nginx-gunicorn
|
||||
# host_xhgui_port: "8142"
|
||||
# Can be used to change the host binding port of the XHGui
|
||||
# application. Rarely used; only when port conflict and
|
||||
# bind_all_ports is used (normally with router disabled)
|
||||
|
||||
# xhprof_mode: [prepend|xhgui|global]
|
||||
# Default is "xhgui"
|
||||
|
||||
# webserver_type: nginx-fpm, apache-fpm, generic
|
||||
|
||||
# timezone: Europe/Berlin
|
||||
# If timezone is unset, DDEV will attempt to derive it from the host system timezone
|
||||
# using the $TZ environment variable or the /etc/localtime symlink.
|
||||
# This is the timezone used in the containers and by PHP;
|
||||
# it can be set to any valid timezone,
|
||||
# see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
||||
@@ -74,22 +104,27 @@ nodejs_version: "18"
|
||||
# commands are executed.
|
||||
|
||||
# composer_version: "2"
|
||||
# You can set it to "" or "2" (default) for Composer v2 or "1" for Composer v1
|
||||
# You can set it to "" or "2" (default) for Composer v2
|
||||
# to use the latest major version available at the time your container is built.
|
||||
# It is also possible to use each other Composer version channel. This includes:
|
||||
# It is also possible to use any other Composer version channel. This includes:
|
||||
# - 2.2 (latest Composer LTS version)
|
||||
# - stable
|
||||
# - preview
|
||||
# - snapshot
|
||||
# Alternatively, an explicit Composer version may be specified, for example "2.2.18".
|
||||
# To reinstall Composer after the image was built, run "ddev debug refresh".
|
||||
# To reinstall Composer after the image was built, run "ddev utility rebuild".
|
||||
|
||||
# nodejs_version: "18"
|
||||
# change from the default system Node.js version to another supported version, like 16, 18, 20.
|
||||
# Note that you can use 'ddev nvm' or nvm inside the web container to provide nearly any
|
||||
# Node.js version, including v6, etc.
|
||||
# You only need to configure this if you are not using nvm and you want to use a major
|
||||
# version that is not the default.
|
||||
# nodejs_root: <relative_path>
|
||||
# Relative path to the directory containing the Node.js version file from the
|
||||
# project root. Only used with "nodejs_version: auto" or "nodejs_version: engine".
|
||||
|
||||
# nodejs_version: "24"
|
||||
# change from the default system Node.js version to any other version.
|
||||
# See https://docs.ddev.com/en/stable/users/configuration/config/#nodejs_version for more information
|
||||
# and https://www.npmjs.com/package/n#specifying-nodejs-versions for the full documentation.
|
||||
|
||||
# corepack_enable: false
|
||||
# Change to 'true' to 'corepack enable' and gain access to latest versions of yarn/pnpm
|
||||
|
||||
# additional_hostnames:
|
||||
# - somename
|
||||
@@ -119,7 +154,7 @@ nodejs_version: "18"
|
||||
|
||||
# ddev_version_constraint: ""
|
||||
# Example:
|
||||
# ddev_version_constraint: ">= 1.22.4"
|
||||
# ddev_version_constraint: ">= 1.24.8"
|
||||
# This will enforce that the running ddev version is within this constraint.
|
||||
# See https://github.com/Masterminds/semver#checking-version-constraints for
|
||||
# supported constraint formats
|
||||
@@ -146,10 +181,8 @@ nodejs_version: "18"
|
||||
# - "global": uses the value from the global config.
|
||||
# - "none": disables performance optimization for this project.
|
||||
# - "mutagen": enables Mutagen for this project.
|
||||
# - "nfs": enables NFS for this project.
|
||||
#
|
||||
# See https://ddev.readthedocs.io/en/latest/users/install/performance/#nfs
|
||||
# See https://ddev.readthedocs.io/en/latest/users/install/performance/#mutagen
|
||||
# See https://docs.ddev.com/en/stable/users/install/performance/#mutagen
|
||||
|
||||
# fail_on_hook_fail: False
|
||||
# Decide whether 'ddev start' should be interrupted by a failing hook
|
||||
@@ -178,10 +211,10 @@ nodejs_version: "18"
|
||||
# The mailpit port is not normally bound on the host at all, instead being routed
|
||||
# through ddev-router, but it can be bound directly to localhost if specified here.
|
||||
|
||||
# webimage_extra_packages: [php7.4-tidy, php-bcmath]
|
||||
# webimage_extra_packages: ['php${DDEV_PHP_VERSION}-tidy', 'php${DDEV_PHP_VERSION}-yac']
|
||||
# Extra Debian packages that are needed in the webimage can be added here
|
||||
|
||||
# dbimage_extra_packages: [telnet,netcat]
|
||||
# dbimage_extra_packages: [netcat, telnet, sudo]
|
||||
# Extra Debian packages that are needed in the dbimage can be added here
|
||||
|
||||
# use_dns_when_possible: true
|
||||
@@ -193,22 +226,25 @@ nodejs_version: "18"
|
||||
# project_tld: ddev.site
|
||||
# The top-level domain used for project URLs
|
||||
# The default "ddev.site" allows DNS lookup via a wildcard
|
||||
# If you prefer you can change this to "ddev.local" to preserve
|
||||
# pre-v1.9 behavior.
|
||||
|
||||
# ngrok_args: --basic-auth username:pass1234
|
||||
# Provide extra flags to the "ngrok http" command, see
|
||||
# https://ngrok.com/docs/ngrok-agent/config or run "ngrok http -h"
|
||||
# share_default_provider: ngrok
|
||||
# The default share provider to use for "ddev share"
|
||||
# Defaults to global configuration, usually "ngrok"
|
||||
# Can be "ngrok" or "cloudflared" or the name of a custom provider from .ddev/share-providers/
|
||||
|
||||
# share_provider_args: --basic-auth username:pass1234
|
||||
# Provide extra flags to the share provider script
|
||||
# See https://docs.ddev.com/en/stable/users/configuration/config/#share_provider_args
|
||||
|
||||
# disable_settings_management: false
|
||||
# If true, DDEV will not create CMS-specific settings files like
|
||||
# Drupal's settings.php/settings.ddev.php or TYPO3's AdditionalConfiguration.php
|
||||
# Drupal's settings.php/settings.ddev.php or TYPO3's additional.php
|
||||
# In this case the user must provide all such settings.
|
||||
|
||||
# You can inject environment variables into the web container with:
|
||||
# web_environment:
|
||||
# - SOMEENV=somevalue
|
||||
# - SOMEOTHERENV=someothervalue
|
||||
# - SOMEENV=somevalue
|
||||
# - SOMEOTHERENV=someothervalue
|
||||
|
||||
# no_project_mount: false
|
||||
# (Experimental) If true, DDEV will not mount the project into the web container;
|
||||
@@ -260,7 +296,7 @@ nodejs_version: "18"
|
||||
# override_config: false
|
||||
# By default, config.*.yaml files are *merged* into the configuration
|
||||
# But this means that some things can't be overridden
|
||||
# For example, if you have 'use_dns_when_possible: true'' you can't override it with a merge
|
||||
# For example, if you have 'use_dns_when_possible: true' you can't override it with a merge
|
||||
# and you can't erase existing hooks or all environment variables.
|
||||
# However, with "override_config: true" in a particular config.*.yaml file,
|
||||
# 'use_dns_when_possible: false' can override the existing values, and
|
||||
@@ -270,13 +306,13 @@ nodejs_version: "18"
|
||||
# web_environment: []
|
||||
# or
|
||||
# additional_hostnames: []
|
||||
# can have their intended affect. 'override_config' affects only behavior of the
|
||||
# can have their intended effect. 'override_config' affects only behavior of the
|
||||
# config.*.yaml file it exists in.
|
||||
|
||||
# Many DDEV commands can be extended to run tasks before or after the
|
||||
# DDEV command is executed, for example "post-start", "post-import-db",
|
||||
# "pre-composer", "post-composer"
|
||||
# See https://ddev.readthedocs.io/en/stable/users/extend/custom-commands/ for more
|
||||
# See https://docs.ddev.com/en/stable/users/extend/custom-commands/ for more
|
||||
# information on the commands that can be extended and the tasks you can define
|
||||
# for them. Example:
|
||||
#hooks:
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
# http://download.redis.io/redis-stable/redis.conf
|
||||
# http://download.redis.io/redis-stable/sentinel.conf
|
||||
|
||||
maxmemory 2048mb
|
||||
maxmemory-policy allkeys-lfu
|
||||
maxmemory 128mb
|
||||
maxmemory-policy allkeys-lru
|
||||
|
||||
# to disable Redis persistence, remove ddev-generated from this file,
|
||||
# and uncomment the two lines below:
|
||||
|
||||
-3284
File diff suppressed because it is too large
Load Diff
+2
-1
@@ -15,6 +15,7 @@
|
||||
"ext-json": "*",
|
||||
"ext-libxml": "*",
|
||||
"ext-pdo": "*",
|
||||
"ext-redis": "*",
|
||||
"ext-simplexml": "*",
|
||||
"b13/container": "^1.3",
|
||||
"blueways/bw-captcha": "^3.1",
|
||||
@@ -97,7 +98,7 @@
|
||||
"config": {
|
||||
"sort-packages": true,
|
||||
"platform": {
|
||||
"php": "7.4.13"
|
||||
"php": "7.4.33"
|
||||
},
|
||||
"allow-plugins": {
|
||||
"typo3/cms-composer-installers": true,
|
||||
|
||||
Generated
+3
-2
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "e3a433b77a2142f116e57b54c4172ffa",
|
||||
"content-hash": "38fb94ebf504e8413d37c94f929e4b47",
|
||||
"packages": [
|
||||
{
|
||||
"name": "b13/container",
|
||||
@@ -9647,11 +9647,12 @@
|
||||
"ext-json": "*",
|
||||
"ext-libxml": "*",
|
||||
"ext-pdo": "*",
|
||||
"ext-redis": "*",
|
||||
"ext-simplexml": "*"
|
||||
},
|
||||
"platform-dev": {},
|
||||
"platform-overrides": {
|
||||
"php": "7.4.13"
|
||||
"php": "7.4.33"
|
||||
},
|
||||
"plugin-api-version": "2.9.0"
|
||||
}
|
||||
|
||||
Generated
-18
@@ -21,10 +21,8 @@
|
||||
"glightbox": "^3.0.9",
|
||||
"htmx.org": "^1.9.12",
|
||||
"jquery": "^3.6.0",
|
||||
"lazysizes": "^5.3.2",
|
||||
"leaflet": "^1.7.1",
|
||||
"normalize.css": "^8.0.1",
|
||||
"picturefill": "^3.0.3",
|
||||
"slick-carousel": "^1.8.1",
|
||||
"sticky-js": "^1.3.0",
|
||||
"stimulus-use": "^0.52.0",
|
||||
@@ -6017,12 +6015,6 @@
|
||||
"shell-quote": "^1.8.4"
|
||||
}
|
||||
},
|
||||
"node_modules/lazysizes": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/lazysizes/-/lazysizes-5.3.2.tgz",
|
||||
"integrity": "sha512-22UzWP+Vedi/sMeOr8O7FWimRVtiNJV2HCa+V8+peZOw6QbswN9k58VUhd7i6iK5bw5QkYrF01LJbeJe0PV8jg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/leaflet": {
|
||||
"version": "1.9.4",
|
||||
"resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz",
|
||||
@@ -6963,16 +6955,6 @@
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/picturefill": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/picturefill/-/picturefill-3.0.3.tgz",
|
||||
"integrity": "sha512-JDdx+3i4fs2pkqwWZJgGEM2vFWsq+01YsQFT9CKPGuv2Q0xSdrQZoxi9XwyNARTgxiOdgoAwWQRluLRe/JQX2g==",
|
||||
"deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/pify": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
|
||||
|
||||
@@ -24,10 +24,8 @@
|
||||
"glightbox": "^3.0.9",
|
||||
"htmx.org": "^1.9.12",
|
||||
"jquery": "^3.6.0",
|
||||
"lazysizes": "^5.3.2",
|
||||
"leaflet": "^1.7.1",
|
||||
"normalize.css": "^8.0.1",
|
||||
"picturefill": "^3.0.3",
|
||||
"slick-carousel": "^1.8.1",
|
||||
"sticky-js": "^1.3.0",
|
||||
"stimulus-use": "^0.52.0",
|
||||
|
||||
@@ -47,22 +47,42 @@ if (getenv('IS_DDEV_PROJECT') == 'true') {
|
||||
);
|
||||
}
|
||||
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_pages'] = [
|
||||
// Fail fast instead of blocking indefinitely when redis is unreachable.
|
||||
$redisOptions['connectionTimeout'] = 2;
|
||||
|
||||
// Note: the cache identifiers must stay unprefixed ('pages', not 'cache_pages'). These
|
||||
// assignments replace the definitions from LocalConfiguration.php wholesale, so 'groups'
|
||||
// and the compression/lifetime options have to be repeated here.
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['pages'] = [
|
||||
'frontend' => \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class,
|
||||
'backend' => \TYPO3\CMS\Core\Cache\Backend\RedisBackend::class,
|
||||
'options' => $redisOptions + ['database' => 0],
|
||||
'options' => $redisOptions + [
|
||||
'database' => 0,
|
||||
'compression' => true,
|
||||
],
|
||||
'groups' => ['pages'],
|
||||
];
|
||||
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_hash'] = [
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['hash'] = [
|
||||
'frontend' => \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class,
|
||||
'backend' => \TYPO3\CMS\Core\Cache\Backend\RedisBackend::class,
|
||||
'options' => $redisOptions + ['database' => 1],
|
||||
'options' => $redisOptions + [
|
||||
'database' => 1,
|
||||
],
|
||||
'groups' => ['pages'],
|
||||
];
|
||||
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['cache_rootline'] = [
|
||||
// Own database: RedisBackend::flush() issues FLUSHDB and the keys carry no per-cache
|
||||
// prefix, so two caches sharing a database flush each other.
|
||||
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['rootline'] = [
|
||||
'frontend' => \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class,
|
||||
'backend' => \TYPO3\CMS\Core\Cache\Backend\RedisBackend::class,
|
||||
'options' => $redisOptions + ['database' => 1],
|
||||
'options' => $redisOptions + [
|
||||
'database' => 2,
|
||||
'compression' => true,
|
||||
'defaultLifetime' => 2592000,
|
||||
],
|
||||
'groups' => ['pages'],
|
||||
];
|
||||
|
||||
// suppress php deprecation warnings flooding typo3 logs
|
||||
|
||||
@@ -4,9 +4,6 @@ import Vue from 'vue'
|
||||
import $ from 'jquery'
|
||||
import VueSession from 'vue-session'
|
||||
|
||||
import 'lazysizes';
|
||||
import 'lazysizes/plugins/attrchange/ls.attrchange';
|
||||
|
||||
const slick = require('slick-carousel');
|
||||
const Sticky = require('sticky-js');
|
||||
const $window = $(window);
|
||||
|
||||
+3
-3
@@ -38,9 +38,9 @@
|
||||
<div class="card card--no-form offerlist-item__card">
|
||||
<div class="card__inner">
|
||||
<picture>
|
||||
<source media="(max-width: 512px)" :data-srcset="offer.teaserImageMobile + ' 500w'"/>
|
||||
<img class="card__image scale lazyload" data-sizes="auto"
|
||||
:data-src="offer.teaserImage" alt="">
|
||||
<source media="(max-width: 512px)" :srcset="offer.teaserImageMobile"/>
|
||||
<img class="card__image scale"
|
||||
:src="offer.teaserImage" alt="" loading="lazy">
|
||||
</picture>
|
||||
<div class="card__caption">
|
||||
<span class="card__subtitle" v-html="offer.name"></span>
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace EP\EpTheme\ViewHelpers;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Fluid\ViewHelpers\ImageViewHelper;
|
||||
|
||||
class LazyLoadImageViewHelper extends ImageViewHelper
|
||||
{
|
||||
public function initializeArguments()
|
||||
{
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('loaderimg', 'string', '', false);
|
||||
}
|
||||
|
||||
public function render(): string
|
||||
{
|
||||
parent::render();
|
||||
|
||||
$src = $this->tag->getAttribute('src');
|
||||
$this->tag->removeAttribute('src');
|
||||
$this->tag->addAttribute('data', ['src' => $src], false);
|
||||
|
||||
if (isset($this->arguments['loaderimg'])) {
|
||||
$loaderImage = $this->imageService->getImage($this->arguments['loaderimg'], null, false);
|
||||
$processingInstructions = [
|
||||
'width' => $this->arguments['width'],
|
||||
'height' => $this->arguments['height'],
|
||||
'minWidth' => $this->arguments['minWidth'],
|
||||
'minHeight' => $this->arguments['minHeight'],
|
||||
'maxWidth' => $this->arguments['maxWidth'],
|
||||
'maxHeight' => $this->arguments['maxHeight'],
|
||||
];
|
||||
$processedLoaderImage = $this->imageService->applyProcessingInstructions($loaderImage, $processingInstructions);
|
||||
$loaderImageUri = $this->imageService->getImageUri($processedLoaderImage, $this->arguments['absolute']);
|
||||
$this->tag->addAttribute('src', $loaderImageUri);
|
||||
}
|
||||
|
||||
$classes = $this->tag->getAttribute('class');
|
||||
$classItems = GeneralUtility::trimExplode(' ', $classes, true);
|
||||
$classItems[] = 'lazyload';
|
||||
$classes = implode(' ', array_unique($classItems));
|
||||
$this->tag->addAttribute('class', $classes);
|
||||
// ensure a11y compliance
|
||||
$this->tag->removeAttribute('title');
|
||||
|
||||
return $this->tag->render();
|
||||
}
|
||||
}
|
||||
@@ -15,3 +15,10 @@ module.tx_form.settings.yamlConfigurations {
|
||||
1630994710 = EXT:ep_theme/Configuration/Yaml/FormsBase.yaml
|
||||
1630994711 = EXT:ep_theme/Configuration/Yaml/FormFinishersBackend.yaml
|
||||
}
|
||||
|
||||
plugin.tx_bwcaptcha.settings {
|
||||
charset = abcdefghjkmnpqrtuvwxy34679
|
||||
length = 4
|
||||
width = 220
|
||||
height = 60
|
||||
}
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
// Import dependencies
|
||||
require('lazysizes')
|
||||
require('lazysizes/plugins/unveilhooks/ls.unveilhooks')
|
||||
// require('picturefill')
|
||||
|
||||
// Polyfills
|
||||
// import smoothscroll from 'smoothscroll-polyfill'
|
||||
// smoothscroll.polyfill()
|
||||
|
||||
-791
@@ -1,791 +0,0 @@
|
||||
<template>
|
||||
<div class="relative">
|
||||
<div class="mb-8"
|
||||
v-show="!submitted">
|
||||
<label class="mb-2 font-bold">
|
||||
Zeitraum
|
||||
</label>
|
||||
<input type="text"
|
||||
class="form-field"
|
||||
placeholder="von... bis" ref="picker"/>
|
||||
<p class="text-sm mt-2" v-if="mainSeasonFrom && mainSeasonTo">
|
||||
in der Hauptsaison {{ mainSeasonFrom }}-{{ mainSeasonTo }} mind. {{ minBookingDays }} Tage
|
||||
</p>
|
||||
<p class="text-sm italic mt-2"
|
||||
v-show="nightsCount === 1">
|
||||
Einzelne Nächte sind nur auf Anfrage buchbar
|
||||
</p>
|
||||
</div>
|
||||
<div class="mb-8 grid sm:grid-cols-2 gap-8"
|
||||
v-show="!submitted">
|
||||
<div>
|
||||
<label class="mb-2 font-bold">
|
||||
Personenzahl
|
||||
</label>
|
||||
<input type="number"
|
||||
class="form-field"
|
||||
min="30"
|
||||
v-model.number="selectedPax"
|
||||
@change="onPaxUpdated()"
|
||||
v-show="nightsCount > 0"/>
|
||||
<p class="text-sm italic"
|
||||
v-show="nightsCount === 0">
|
||||
Bitte zuerst einen Zeitraum wählen
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<label class="mb-2 font-bold">
|
||||
davon Kinder 0-3 Jahre
|
||||
</label>
|
||||
<input type="number"
|
||||
class="form-field"
|
||||
min="0"
|
||||
v-model.number="childrenCount"
|
||||
@change="onPaxUpdated()"
|
||||
v-show="nightsCount > 0"/>
|
||||
<p class="text-sm italic"
|
||||
v-show="nightsCount === 0">
|
||||
Bitte zuerst einen Zeitraum wählen
|
||||
</p>
|
||||
<p class="text-sm italic"
|
||||
v-show="nightsCount > 0">
|
||||
Kinder werden nur bei Strom- und Abfallgebühren berücksichtigt.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<label class="mb-2 font-bold">
|
||||
davon Kinder 4-5 Jahre*
|
||||
</label>
|
||||
<input type="number"
|
||||
class="form-field"
|
||||
min="0"
|
||||
v-model.number="minorsCount"
|
||||
@change="onPaxUpdated()"
|
||||
v-show="nightsCount > 0"/>
|
||||
<p class="text-sm italic"
|
||||
v-show="nightsCount === 0">
|
||||
Bitte zuerst einen Zeitraum wählen
|
||||
</p>
|
||||
</div>
|
||||
<div v-if="adolescentsAge > 0">
|
||||
<label class="mb-2 font-bold">
|
||||
davon Kinder 6-{{ adolescentsAge }} Jahre*
|
||||
</label>
|
||||
<input type="number"
|
||||
class="form-field"
|
||||
min="0"
|
||||
v-model.number="adolescentsCount"
|
||||
@change="onPaxUpdated()"
|
||||
v-show="nightsCount > 0"/>
|
||||
<p class="text-sm italic"
|
||||
v-show="nightsCount === 0">
|
||||
Bitte zuerst einen Zeitraum wählen
|
||||
</p>
|
||||
</div>
|
||||
<div class="sm:col-span-2 text-sm">
|
||||
*Die Kosten für Essen und Kurtaxe werden wir entsprechend der Altersstruktur der Gäste in der Rechnung
|
||||
anpassen.
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-8"
|
||||
v-show="options.length > 0 && !submitted">
|
||||
<div class="mb-2 font-bold">
|
||||
Optionale Zusatzleistungen
|
||||
</div>
|
||||
<ul class="mb-0 p-0 space-y-2">
|
||||
<li v-for="option of options" :key="option.uid">
|
||||
<label class="flex items-start">
|
||||
<input type="checkbox"
|
||||
class="w-5 h-5 border-ep-primary-light ring-0 bg-transparent focus:ring-0 focus:border-none text-ep-primary"
|
||||
v-model="selectedOptions"
|
||||
:value="option">
|
||||
<span class="pl-2 leading-none">{{ option.title }}{{ formatOptionPriceType(option) }}</span>
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="mb-8"
|
||||
v-show="boards.length > 0 && !submitted">
|
||||
<label class="mb-2 font-bold">
|
||||
Verpflegungsleistungen
|
||||
</label>
|
||||
<select class="form-field"
|
||||
v-model="selectedBoard"
|
||||
v-if="selectedPax >= 30">
|
||||
<option :value="null" disabled>bitte auswählen</option>
|
||||
<option v-for="board of boards"
|
||||
:value="board"
|
||||
:key="board.uid">
|
||||
{{ board.title }} ({{ formatCurrency(board.price) }} pro Person und Nacht)
|
||||
</option>
|
||||
</select>
|
||||
<div class="text-sm text-red-600 mt-1"
|
||||
v-show="formErrors.board"
|
||||
v-html="formErrors.board"></div>
|
||||
<div v-show="selectedPax < 30">
|
||||
<span class="text-red-600">Erst ab 30 Personen buchbar.</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-8">
|
||||
<div class="pb-2" v-if="submitted">
|
||||
<p class="text-lg font-bold pb-2">
|
||||
Vielen Dank für Deine {{ mode === 'booking' ? 'Buchung' : 'Anfrage' }}.
|
||||
</p>
|
||||
<p>
|
||||
Für folgendes habt ihr euch entschieden:
|
||||
</p>
|
||||
</div>
|
||||
<div class="p-2 uppercase bg-ep-primary-dark text-white w-full">
|
||||
Preise
|
||||
</div>
|
||||
<div class="bg-zinc-100 p-2 mb-2">
|
||||
<table class="w-full" v-show="nightsCount > 0">
|
||||
<tbody>
|
||||
<tr class="odd:bg-zinc-100">
|
||||
<th class="text-left py-2">Zeitraum</th>
|
||||
<td>{{ rangeFormatted }}, {{ nightsCount }} Nächte</td>
|
||||
</tr>
|
||||
<tr class="odd:bg-zinc-100">
|
||||
<th class="text-left py-2">Personenzahl</th>
|
||||
<td>
|
||||
{{ selectedPax }}<span v-if="childrenCount > 0">, davon Kinder {{ childrenCount }}</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="odd:bg-zinc-100">
|
||||
<th class="text-left py-2">Basispreis</th>
|
||||
<td>{{ formatCurrency(pricePax.base) }}</td>
|
||||
</tr>
|
||||
<tr class="odd:bg-zinc-100"
|
||||
v-if="pricePax.additional.EUR > 0 || pricePax.additional.CHF > 0">
|
||||
<th class="text-left py-2">Aufpreis Personenzahl</th>
|
||||
<td>{{ formatCurrency(pricePax.additional) }}</td>
|
||||
</tr>
|
||||
<tr class="odd:bg-zinc-100"
|
||||
v-if="priceShortTerm.EUR > 0 || priceShortTerm.CHF > 0">
|
||||
<th class="text-left py-2">Aufpreis Kurzzeit</th>
|
||||
<td>{{ formatCurrency(priceShortTerm) }}</td>
|
||||
</tr>
|
||||
<tr class="odd:bg-zinc-100"
|
||||
v-for="selectedOption in selectedOptions">
|
||||
<th class="text-left py-2">{{ selectedOption.title }}</th>
|
||||
<td>{{ formatCurrency(calculateOptionPrice(selectedOption)) }}</td>
|
||||
</tr>
|
||||
<tr class="odd:bg-zinc-100"
|
||||
v-if="priceBoard.EUR > 0 || priceBoard.CHF > 0">
|
||||
<th class="text-left py-2">{{ selectedBoard.title }}</th>
|
||||
<td>{{ formatCurrency(priceBoard) }}</td>
|
||||
</tr>
|
||||
<tr class="odd:bg-zinc-100"
|
||||
v-if="false === isSelfCatering && undersubscriptionLimit > 0">
|
||||
<th class="text-left py-2">Verpflegungs-Aufschlag für Gruppen unter {{ undersubscriptionLimit }} Personen</th>
|
||||
<td>{{ formatCurrency(pricePax.undersubscription) }}</td>
|
||||
</tr>
|
||||
<tr class="odd:bg-zinc-100"
|
||||
v-if="priceRunningCosts.EUR > 0 || priceRunningCosts.CHF > 0">
|
||||
<th class="text-left py-2">Strom- und Abfallgebühren</th>
|
||||
<td>{{ formatCurrency(priceRunningCosts) }}</td>
|
||||
</tr>
|
||||
<tr class="odd:bg-zinc-100">
|
||||
<th class="text-left py-2">Gesamtpreis</th>
|
||||
<td>
|
||||
<strong>{{ formatCurrency(priceTotal) }}</strong>
|
||||
<br>
|
||||
<small>{{ taxLabel }}</small>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p class="text-sm italic"
|
||||
v-show="nightsCount === 0">
|
||||
Bitte zuerst einen Zeitraum wählen
|
||||
</p>
|
||||
</div>
|
||||
<div v-if="mode === 'booking' && submitted">
|
||||
Bitte beachtet, dass die Buchung bei uns eingegangen, aber <strong>noch nicht bestätigt</strong> ist.
|
||||
Wir behalten uns vor, die Buchungen auf Verfügbarkeit und Länge des gewünschten Aufenthalts zu prüfen.
|
||||
Erst wenn wir euch die Buchung per Mail bestätigt haben, wird sie bindend.
|
||||
</div>
|
||||
<div v-if="mode === 'inquiry' && submitted">
|
||||
Die Anfrage ist bei uns eingegangen und wird schnellstmöglich bearbeitet. Wir melden uns telefonisch
|
||||
oder per Mail bei euch.
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-8"
|
||||
v-show="nightsCount > 0 && !submitted">
|
||||
<div class="p-2 uppercase bg-ep-primary-dark text-white w-full">
|
||||
Jetzt <span v-if="!forceInquiry">buchen</span><span v-if="forceInquiry">anfragen</span>
|
||||
</div>
|
||||
<div class="bg-zinc-100 p-2">
|
||||
<div class="grid md:grid-cols-2 gap-4 mb-4">
|
||||
<div :class="{ 'has-error': formErrors.name }">
|
||||
<label class="font-bold mb-2">
|
||||
Name*
|
||||
</label>
|
||||
<input type="text"
|
||||
class="form-field"
|
||||
v-model="name">
|
||||
<div class="text-sm text-red-600 mt-1"
|
||||
v-show="formErrors.name"
|
||||
v-html="formErrors.name"></div>
|
||||
</div>
|
||||
<div :class="{ 'has-error': formErrors.street }">
|
||||
<label class="font-bold mb-2">
|
||||
Strasse, Nr.*
|
||||
</label>
|
||||
<input type="text"
|
||||
class="form-field"
|
||||
v-model="street">
|
||||
<div class="text-sm text-red-600 mt-1"
|
||||
v-show="formErrors.street"
|
||||
v-html="formErrors.street"></div>
|
||||
</div>
|
||||
<div :class="{ 'has-error': formErrors.postcode }">
|
||||
<label class="font-bold mb-2">
|
||||
Postleitzahl*
|
||||
</label>
|
||||
<input type="text"
|
||||
class="form-field"
|
||||
v-model="postcode">
|
||||
<div class="text-sm text-red-600 mt-1"
|
||||
v-show="formErrors.postcode"
|
||||
v-html="formErrors.postcode"></div>
|
||||
</div>
|
||||
<div :class="{ 'has-error': formErrors.city }">
|
||||
<label class="font-bold mb-2">
|
||||
Ort*
|
||||
</label>
|
||||
<input type="text"
|
||||
class="form-field"
|
||||
v-model="city">
|
||||
<div class="text-sm text-red-600 mt-1"
|
||||
v-show="formErrors.city"
|
||||
v-html="formErrors.city"></div>
|
||||
</div>
|
||||
<div :class="{ 'has-error': formErrors.group }">
|
||||
<label class="font-bold mb-2">
|
||||
Name der Gruppe*
|
||||
</label>
|
||||
<input type="text"
|
||||
class="form-field"
|
||||
v-model="group">
|
||||
<div class="text-sm text-red-600 mt-1"
|
||||
v-show="formErrors.group"
|
||||
v-html="formErrors.group"></div>
|
||||
</div>
|
||||
<div :class="{ 'has-error': formErrors.email }">
|
||||
<label class="font-bold mb-2">
|
||||
E-Mail*
|
||||
</label>
|
||||
<input type="text"
|
||||
class="form-field"
|
||||
v-model="email">
|
||||
<div class="text-sm text-red-600 mt-1"
|
||||
v-show="formErrors.email"
|
||||
v-html="formErrors.email"></div>
|
||||
</div>
|
||||
<div :class="{ 'has-error': formErrors.phone }">
|
||||
<label class="font-bold mb-2">
|
||||
Telefon*
|
||||
</label>
|
||||
<input type="text"
|
||||
class="form-field"
|
||||
v-model="phone">
|
||||
<div class="text-sm text-red-600 mt-1"
|
||||
v-show="formErrors.phone"
|
||||
v-html="formErrors.phone"></div>
|
||||
</div>
|
||||
<div>
|
||||
<label class="font-bold mb-2">
|
||||
Bemerkungen/Wünsche
|
||||
</label>
|
||||
<textarea class="form-field"
|
||||
cols="30"
|
||||
rows="3"
|
||||
v-model="remarks"/>
|
||||
</div>
|
||||
<div v-if="mode === 'booking'" :class="{ 'has-error': formErrors.confirmation }">
|
||||
<label for="confirmation" class="flex items-start">
|
||||
<input type="checkbox" v-model="confirmation" name="confirmation" id="confirmation">
|
||||
<span class="block ml-2">
|
||||
Durch Anklicken des Buttons 'Buchung abschicken' bestätige ich, dass ich die
|
||||
<a :href="termsUrls[countryCode]"
|
||||
class="text-ep-primary" target="_blank">
|
||||
Allgemeinen Geschäftsbedingungen (AGB)
|
||||
</a> gelesen habe und damit einverstanden bin, dass eine
|
||||
kostenpflichtige Buchung zustande kommt.
|
||||
</span>
|
||||
</label>
|
||||
<div class="text-sm text-red-600 mt-1"
|
||||
v-show="formErrors.confirmation"
|
||||
v-html="formErrors.confirmation"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="py-4">
|
||||
Ihr erhaltet von uns eine Bestätigung. Wir behalten uns vor die Buchung zu prüfen. Erst nach
|
||||
Rückbestätigung von uns gilt die Buchung auch von unserer Seite als bindend.
|
||||
</div>
|
||||
<div class="flex items-center space-x-2">
|
||||
<button class="button bg-button"
|
||||
type="submit"
|
||||
v-if="!forceInquiry"
|
||||
@click.prevent="submitForm('booking')">
|
||||
Buchung abschicken
|
||||
</button>
|
||||
<button class="button bg-button"
|
||||
:class="{ 'button--small bg-ep-secondary': !forceInquiry }"
|
||||
type="submit"
|
||||
@click.prevent="submitForm('inquiry')">
|
||||
als Anfrage senden
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<img :src="logoAt" alt="" v-if="countryCode === 'AT'" class="block w-full h-auto max-w-24">
|
||||
<img :src="logoCh" alt="" v-if="countryCode === 'CH'" class="block w-full h-auto max-w-24">
|
||||
</div>
|
||||
<div class="fixed top-0 left-0 inset-0 bg-white/85 flex items-center justify-center" v-show="processing">
|
||||
<img :src="loaderUri" alt="Loading...">
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import dayjs from 'dayjs'
|
||||
import 'dayjs/locale/de'
|
||||
import 'flatpickr';
|
||||
import {German} from 'flatpickr/dist/l10n/de';
|
||||
import Vue from 'vue';
|
||||
|
||||
export default {
|
||||
name: 'GroupsPriceCalculator',
|
||||
props: {
|
||||
loaderUri: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
endpoint: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
logoAt: {
|
||||
type: String,
|
||||
},
|
||||
logoCh: {
|
||||
type: String,
|
||||
},
|
||||
configsJson: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
boardsJson: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
optionsJson: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
runningCostsFactorEur: {
|
||||
type: Number,
|
||||
default: 2.5,
|
||||
},
|
||||
runningCostsFactorChf: {
|
||||
type: Number,
|
||||
default: 2.9,
|
||||
},
|
||||
undersubscription30Eur: {
|
||||
type: Number,
|
||||
default: 5.0,
|
||||
},
|
||||
undersubscription30Chf: {
|
||||
type: Number,
|
||||
default: 5.0,
|
||||
},
|
||||
undersubscription40Eur: {
|
||||
type: Number,
|
||||
default: 2.5,
|
||||
},
|
||||
undersubscription40Chf: {
|
||||
type: Number,
|
||||
default: 2.5,
|
||||
},
|
||||
countryCode: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
shortTermFactors: {
|
||||
type: Array,
|
||||
default() {
|
||||
return [
|
||||
{ nights: 1, factor: 0.3 },
|
||||
{ nights: 2, factor: 0.2 },
|
||||
{ nights: 3, factor: 0.1 },
|
||||
]
|
||||
}
|
||||
},
|
||||
mainSeasonFrom: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
mainSeasonTo: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
minBookingDays: {
|
||||
type: Number,
|
||||
default: 5,
|
||||
},
|
||||
taxLabel: {
|
||||
type: String,
|
||||
default: 'zzgl. vorab zu entrichtender Ortstaxe',
|
||||
},
|
||||
adolescentsAge: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
configs: JSON.parse(this.configsJson),
|
||||
boards: JSON.parse(this.boardsJson),
|
||||
options: JSON.parse(this.optionsJson),
|
||||
processing: false,
|
||||
submitted: false,
|
||||
picker: null,
|
||||
formErrors: {},
|
||||
selectedFrom: null,
|
||||
selectedTo: null,
|
||||
selectedRange: [],
|
||||
selectedPax: 30,
|
||||
childrenCount: 0,
|
||||
minorsCount: 0,
|
||||
adolescentsCount: 0,
|
||||
selectedOptions: [],
|
||||
selectedBoard: null,
|
||||
name: '',
|
||||
email: '',
|
||||
phone: '',
|
||||
remarks: '',
|
||||
group: '',
|
||||
street: '',
|
||||
postcode: '',
|
||||
city: '',
|
||||
mode: 'booking',
|
||||
confirmation: false,
|
||||
termsUrls: {
|
||||
AT: 'https://www.ep-reisen.de/fileadmin/user_upload/allgemein/AGB_Gruppen/AGB_Gruppen_CLLT_Touristik_GmbH.pdf',
|
||||
CH: 'https://www.ep-reisen.de/fileadmin/user_upload/allgemein/AGB_Gruppen/AVB_Gruppen_AlpineVacation_GmbH.pdf',
|
||||
IT: 'https://www.ep-reisen.de/fileadmin/user_upload/allgemein/AGB_Gruppen/AGB_Gruppen_E_P_Reisen.pdf',
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
formatCurrency({ EUR, CHF }) {
|
||||
let price
|
||||
|
||||
if ('CH' === this.countryCode) {
|
||||
let formatter = new Intl.NumberFormat('de-DE', {
|
||||
style: 'currency',
|
||||
currency: 'CHF',
|
||||
})
|
||||
price = formatter.format(CHF)
|
||||
} else {
|
||||
let formatter = new Intl.NumberFormat('de-DE', {
|
||||
style: 'currency',
|
||||
currency: 'EUR',
|
||||
})
|
||||
price = formatter.format(EUR)
|
||||
}
|
||||
|
||||
return price
|
||||
},
|
||||
calculateOptionPrice(option) {
|
||||
let price = {
|
||||
EUR: 0,
|
||||
CHF: 0,
|
||||
};
|
||||
let optionPriceEUR = option.price.EUR
|
||||
let optionPriceCHF = option.price.CHF
|
||||
if (1 === option.type) {
|
||||
price.EUR = optionPriceEUR;
|
||||
price.CHF = optionPriceCHF;
|
||||
} else if (2 === option.type) {
|
||||
price.EUR = optionPriceEUR * this.paxCount;
|
||||
price.CHF = optionPriceCHF * this.paxCount;
|
||||
} else if (3 === option.type) {
|
||||
price.EUR = optionPriceEUR * this.nightsCount;
|
||||
price.CHF = optionPriceCHF * this.nightsCount;
|
||||
} else if (4 === option.type) {
|
||||
price.EUR = optionPriceEUR * this.nightsCount * this.paxCount;
|
||||
price.CHF = optionPriceCHF * this.nightsCount * this.paxCount;
|
||||
}
|
||||
return price;
|
||||
},
|
||||
formatOptionPriceType(option) {
|
||||
if (2 === option.type) {
|
||||
return ` (${this.formatCurrency(option.price)} pro Person)`
|
||||
}
|
||||
if (3 === option.type) {
|
||||
return ` (${this.formatCurrency(option.price)} pro Nacht)`
|
||||
}
|
||||
if (4 === option.type) {
|
||||
return ` (${this.formatCurrency(option.price)} pro Person und Nacht)`
|
||||
}
|
||||
|
||||
return ` (${this.formatCurrency(option.price)})`
|
||||
},
|
||||
initSelectableRanges() {
|
||||
let enabledDates = [];
|
||||
for (let config of this.configs) {
|
||||
const dateFrom = dayjs(config.dateFrom);
|
||||
const dateTo = dayjs(config.dateTo);
|
||||
enabledDates.push({
|
||||
from: dateFrom.format('DD.MM.YYYY'),
|
||||
to: dateTo.format('DD.MM.YYYY')
|
||||
});
|
||||
}
|
||||
this.picker.set('enable', enabledDates);
|
||||
if (enabledDates.length > 0) {
|
||||
const firstDate = enabledDates[0].from;
|
||||
this.picker.set('minDate', firstDate);
|
||||
}
|
||||
},
|
||||
updateSelectedRange() {
|
||||
let range = [];
|
||||
let currentDate = this.selectedFrom;
|
||||
while (currentDate < this.selectedTo) {
|
||||
range.push(currentDate);
|
||||
currentDate = currentDate.add(1, 'day');
|
||||
}
|
||||
this.selectedRange = range;
|
||||
},
|
||||
onPaxUpdated() {
|
||||
if (this.selectedPax < 30) {
|
||||
this.selectedBoard = null;
|
||||
}
|
||||
},
|
||||
submitForm(mode) {
|
||||
this.mode = mode
|
||||
let confirmation = 'inquiry' === mode ? true : this.confirmation
|
||||
let formData = new URLSearchParams({
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][mode]': mode,
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][confirmation]': confirmation ? '1' : '0',
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][name]': this.name ? this.name : '',
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][group]': this.group ? this.group : '',
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][street]': this.street ? this.street : '',
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][postcode]': this.postcode ? this.postcode : '',
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][city]': this.city ? this.city : '',
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][email]': this.email? this.email : '',
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][phone]': this.phone ? this.phone : '',
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][remarks]': this.remarks,
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][dateFrom]': this.selectedFrom.format('DD.MM.YYYY'),
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][dateTo]': this.selectedTo.format('DD.MM.YYYY'),
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][nights]': this.nightsCount,
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][pax]': this.selectedPax,
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][children]': this.childrenCount,
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][minors]': this.minorsCount,
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][adolescents]': this.adolescentsCount,
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][summary][paxBase]': this.formatCurrency(this.pricePax.base),
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][summary][paxAdditional]': this.formatCurrency(this.pricePax.additional),
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][summary][undersubscription]': this.formatCurrency(this.pricePax.undersubscription),
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][summary][shortTerm]': this.formatCurrency(this.priceShortTerm),
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][summary][options]': this.formatCurrency(this.priceOptions),
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][summary][board]': this.formatCurrency(this.priceBoard),
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][summary][runningCosts]': this.formatCurrency(this.priceRunningCosts),
|
||||
'tx_epproducts_ajax[groupsPriceInquiry][summary][total]': this.formatCurrency(this.priceTotal),
|
||||
})
|
||||
if (this.selectedBoard) {
|
||||
formData.append('tx_epproducts_ajax[groupsPriceInquiry][board]', this.selectedBoard.uid)
|
||||
}
|
||||
this.selectedOptions.map(option => (
|
||||
formData.append('tx_epproducts_ajax[groupsPriceInquiry][options][]', option.uid)
|
||||
))
|
||||
this.processing = true;
|
||||
this.submitted = false;
|
||||
fetch(this.endpoint, { method: 'POST', body: formData })
|
||||
.then(response => response.json())
|
||||
.then((json) => {
|
||||
if ('validation' === json.status) {
|
||||
this.formErrors = json.errors
|
||||
} else {
|
||||
this.submitted = true;
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
dataLayer.push({
|
||||
'event': 'Preisberechnung'
|
||||
})
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.processing = false
|
||||
})
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
isSelfCatering() {
|
||||
let selectedBoard = this.selectedBoard
|
||||
if (null === selectedBoard) {
|
||||
return true
|
||||
}
|
||||
if ('CH' === this.countryCode) {
|
||||
return selectedBoard.price.CHF === 0
|
||||
} else {
|
||||
return selectedBoard.price.EUR === 0
|
||||
}
|
||||
},
|
||||
undersubscriptionLimit() {
|
||||
if (this.paxCount < 40) {
|
||||
return 40
|
||||
} else if (this.paxCount < 50) {
|
||||
return 50
|
||||
}
|
||||
|
||||
return 0
|
||||
},
|
||||
paxCount() {
|
||||
// subtract number of children from pax for price calculation, but minimum 30 pax
|
||||
return Math.max(this.selectedPax - this.childrenCount, 30)
|
||||
},
|
||||
nightsCount() {
|
||||
return this.selectedRange.length;
|
||||
},
|
||||
forceInquiry() {
|
||||
return 1 === this.selectedRange.length
|
||||
},
|
||||
rangeFormatted() {
|
||||
if (null === this.selectedFrom || null === this.selectedTo) {
|
||||
return '-';
|
||||
}
|
||||
|
||||
return this.selectedFrom.format('DD.MM.YYYY') + ' - ' + this.selectedTo.format('DD.MM.YYYY');
|
||||
},
|
||||
pricePax() {
|
||||
let base = {
|
||||
EUR: 0,
|
||||
CHF: 0,
|
||||
}
|
||||
let additional = {
|
||||
EUR: 0,
|
||||
CHF: 0,
|
||||
}
|
||||
let undersubscription = {
|
||||
EUR: 0,
|
||||
CHF: 0,
|
||||
}
|
||||
for (let date of this.selectedRange) {
|
||||
for (let config of this.configs) {
|
||||
if (date >= dayjs(config.dateFrom) && date < dayjs(config.dateTo)) {
|
||||
base.EUR += config.price.EUR
|
||||
base.CHF += config.price.CHF
|
||||
let included = config.personsIncluded
|
||||
if (this.paxCount > included) {
|
||||
let additionalPax = this.paxCount - included
|
||||
additional.EUR += additionalPax * config.priceAdditionalPerson.EUR
|
||||
additional.CHF += additionalPax * config.priceAdditionalPerson.CHF
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (false === this.isSelfCatering) {
|
||||
if (this.paxCount < 40) {
|
||||
undersubscription.EUR = this.paxCount * this.undersubscription30Eur * this.selectedRange.length
|
||||
undersubscription.CHF = this.paxCount * this.undersubscription30Chf * this.selectedRange.length
|
||||
} else if (this.paxCount < 50) {
|
||||
undersubscription.EUR = this.paxCount * this.undersubscription40Eur * this.selectedRange.length
|
||||
undersubscription.CHF = this.paxCount * this.undersubscription40Chf * this.selectedRange.length
|
||||
}
|
||||
}
|
||||
|
||||
return {base, additional, undersubscription}
|
||||
},
|
||||
priceOptions() {
|
||||
let price = {
|
||||
EUR: 0,
|
||||
CHF: 0,
|
||||
};
|
||||
for (let option of this.selectedOptions) {
|
||||
let optionPrice = this.calculateOptionPrice(option)
|
||||
price.EUR += optionPrice.EUR;
|
||||
price.CHF += optionPrice.CHF;
|
||||
}
|
||||
return price;
|
||||
},
|
||||
priceBoard() {
|
||||
let price = {
|
||||
EUR: 0,
|
||||
CHF: 0,
|
||||
}
|
||||
if (this.selectedBoard) {
|
||||
price.EUR = this.selectedBoard.price.EUR * this.nightsCount * this.paxCount;
|
||||
price.CHF = this.selectedBoard.price.CHF * this.nightsCount * this.paxCount;
|
||||
}
|
||||
return price
|
||||
},
|
||||
priceShortTerm() {
|
||||
let price = {
|
||||
EUR: 0,
|
||||
CHF: 0,
|
||||
}
|
||||
const totalPricePax = this.pricePax.base.EUR + this.pricePax.additional.EUR;
|
||||
const totalPricePaxCHF = this.pricePax.base.CHF + this.pricePax.additional.CHF;
|
||||
const shorTermFactor = this.shortTermFactors.find(element => element.nights === this.nightsCount);
|
||||
if (undefined !== shorTermFactor) {
|
||||
price.EUR = totalPricePax * shorTermFactor.factor;
|
||||
price.CHF = totalPricePaxCHF * shorTermFactor.factor;
|
||||
}
|
||||
return price
|
||||
},
|
||||
priceRunningCosts() {
|
||||
return {
|
||||
EUR: this.nightsCount * this.selectedPax * this.runningCostsFactorEur,
|
||||
CHF: this.nightsCount * this.selectedPax * this.runningCostsFactorChf,
|
||||
}
|
||||
},
|
||||
priceTotal() {
|
||||
let totalEUR = this.pricePax.base.EUR
|
||||
+ this.pricePax.additional.EUR
|
||||
+ this.pricePax.undersubscription.EUR
|
||||
+ this.priceOptions.EUR
|
||||
+ this.priceBoard.EUR
|
||||
+ this.priceShortTerm.EUR
|
||||
+ this.priceRunningCosts.EUR
|
||||
|
||||
let totalCHF = 0
|
||||
|
||||
// calculate CHF price when pax price in CHF is available since CHF prices may not be provided via CMS yet
|
||||
if (0 < this.pricePax.base.CHF) {
|
||||
totalCHF = this.pricePax.base.CHF
|
||||
+ this.pricePax.additional.CHF
|
||||
+ this.pricePax.undersubscription.CHF
|
||||
+ this.priceOptions.CHF
|
||||
+ this.priceBoard.CHF
|
||||
+ this.priceShortTerm.CHF
|
||||
+ this.priceRunningCosts.CHF
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
EUR: totalEUR,
|
||||
CHF: totalCHF,
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
Vue.nextTick(() => {
|
||||
this.picker = flatpickr(this.$refs.picker, {
|
||||
mode: 'range',
|
||||
dateFormat: 'd.m.Y',
|
||||
locale: German,
|
||||
onChange: selectedDates => {
|
||||
if (2 === selectedDates.length) {
|
||||
this.selectedFrom = dayjs(selectedDates[0]);
|
||||
this.selectedTo = dayjs(selectedDates[1]);
|
||||
this.updateSelectedRange();
|
||||
}
|
||||
}
|
||||
});
|
||||
this.initSelectableRanges();
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,10 +0,0 @@
|
||||
// Initialize vue app
|
||||
import Vue from 'vue'
|
||||
import vueCustomElement from 'vue-custom-element'
|
||||
import 'document-register-element/build/document-register-element'
|
||||
import GroupsPriceCalculator from './components/GroupsPriceCalculator'
|
||||
|
||||
Vue.use(vueCustomElement)
|
||||
Vue.config.productionTip = false
|
||||
|
||||
Vue.customElement('groups-price-calculator', GroupsPriceCalculator)
|
||||
@@ -3,7 +3,3 @@
|
||||
@apply block w-full h-auto;
|
||||
}
|
||||
|
||||
img.lazyloading {
|
||||
background: url(../../images/lazy.png) no-repeat top center;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,12 +18,12 @@
|
||||
</f:if>
|
||||
<f:if condition="{image}">
|
||||
<f:then>
|
||||
<ep:lazyLoadImage image="{image}"
|
||||
loaderimg="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
class="block w-full h-full object-cover"
|
||||
width="400c"
|
||||
height="300c"
|
||||
alt="{city.name}" />
|
||||
<f:image image="{image}"
|
||||
loading="lazy"
|
||||
class="block w-full h-full object-cover"
|
||||
width="400c"
|
||||
height="300c"
|
||||
alt="{city.name}" />
|
||||
</f:then>
|
||||
<f:else>
|
||||
<f:image src="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<html data-namespace-typo3-fluid="true" lang="en"
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers"
|
||||
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
|
||||
|
||||
<f:section name="Teaser">
|
||||
@@ -18,12 +17,12 @@
|
||||
</f:if>
|
||||
<f:if condition="{image}">
|
||||
<f:then>
|
||||
<ep:lazyLoadImage image="{image}"
|
||||
loaderimg="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
class="block w-full h-full object-cover"
|
||||
width="400c"
|
||||
height="300c"
|
||||
alt="{concept.name}" />
|
||||
<f:image image="{image}"
|
||||
loading="lazy"
|
||||
class="block w-full h-full object-cover"
|
||||
width="400c"
|
||||
height="300c"
|
||||
alt="{concept.name}" />
|
||||
</f:then>
|
||||
<f:else>
|
||||
<f:image src="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
|
||||
@@ -13,12 +13,12 @@
|
||||
<div class="col-span-2 md:col-span-1">
|
||||
<div class="relative max-w-md mx-auto mb-8">
|
||||
<f:if condition="{image}">
|
||||
<ep:lazyLoadImage image="{image}"
|
||||
loaderimg="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
class="block w-full h-auto rounded-full"
|
||||
width="400"
|
||||
height="400c"
|
||||
alt="{image.alternative}" />
|
||||
<f:image image="{image}"
|
||||
loading="lazy"
|
||||
class="block w-full h-auto rounded-full"
|
||||
width="400"
|
||||
height="400c"
|
||||
alt="{image.alternative}" />
|
||||
</f:if>
|
||||
<a href="tel:{settings.phoneNumber -> v:format.pregReplace(pattern: '/[\-\s]/', replacement: '')}"
|
||||
rel="nofollow"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<html data-namespace-typo3-fluid="true" lang="en"
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers"
|
||||
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
|
||||
|
||||
<f:alias map="{button: data.flexForm.buttons.0}">
|
||||
@@ -11,11 +10,11 @@
|
||||
<div class="col-md-6">
|
||||
<a href="{f:uri.typolink(parameter: button.container.link)}" title="{button.container.label -> f:format.raw()}">
|
||||
<f:if condition="{image}">
|
||||
<ep:lazyLoadImage image="{image}"
|
||||
loaderimg="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
class="block w-full h-auto rounded-full"
|
||||
width="400"
|
||||
alt="{image.alternative}" />
|
||||
<f:image image="{image}"
|
||||
loading="lazy"
|
||||
class="block w-full h-auto rounded-full"
|
||||
width="400"
|
||||
alt="{image.alternative}" />
|
||||
</f:if>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -11,12 +11,12 @@
|
||||
<div class="md:flex md:items-start py-4">
|
||||
<div class="px-16 pb-4 md:px-4 md:pb-0 md:w-1/6">
|
||||
<f:if condition="{image}">
|
||||
<ep:lazyLoadImage image="{image}"
|
||||
loaderimg="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
class="block w-full h-auto rounded-full"
|
||||
width="400"
|
||||
height="400c"
|
||||
alt="{image.alternative}" />
|
||||
<f:image image="{image}"
|
||||
loading="lazy"
|
||||
class="block w-full h-auto rounded-full"
|
||||
width="400"
|
||||
height="400c"
|
||||
alt="{image.alternative}" />
|
||||
</f:if>
|
||||
</div>
|
||||
<div class="px-16 md:px-4 md:w-5/6 md:pl-8 text-center text-white md:text-left" data-rte-content>
|
||||
|
||||
@@ -14,12 +14,12 @@
|
||||
<div class="col-span-2 md:col-span-1">
|
||||
<div class="relative max-w-md mx-auto mb-8">
|
||||
<f:if condition="{teaserImage}">
|
||||
<ep:lazyLoadImage image="{teaserImage}"
|
||||
loaderimg="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
class="block w-full h-auto rounded-full"
|
||||
width="400"
|
||||
height="400c"
|
||||
alt="{teaserImage.alternative}" />
|
||||
<f:image image="{teaserImage}"
|
||||
loading="lazy"
|
||||
class="block w-full h-auto rounded-full"
|
||||
width="400"
|
||||
height="400c"
|
||||
alt="{teaserImage.alternative}" />
|
||||
</f:if>
|
||||
<a href="tel:{settings.phoneNumber -> v:format.pregReplace(pattern: '/[\-\s]/', replacement: '')}"
|
||||
rel="nofollow"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<html data-namespace-typo3-fluid="true" lang="en"
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers"
|
||||
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
|
||||
|
||||
<f:alias map="{button: data.flexForm.buttons.0}">
|
||||
@@ -11,11 +10,11 @@
|
||||
<div class="col-md-6">
|
||||
<a href="{f:uri.typolink(parameter: button.container.link)}" title="{button.container.label -> f:format.raw()}">
|
||||
<f:if condition="{teaserImage}">
|
||||
<ep:lazyLoadImage image="{teaserImage}"
|
||||
loaderimg="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
class="block w-full h-auto rounded-full"
|
||||
width="400"
|
||||
alt="{teaserImage.alternative}" />
|
||||
<f:image image="{teaserImage}"
|
||||
loading="lazy"
|
||||
class="block w-full h-auto rounded-full"
|
||||
width="400"
|
||||
alt="{teaserImage.alternative}" />
|
||||
</f:if>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -11,12 +11,12 @@
|
||||
<div class="md:flex md:items-start py-4">
|
||||
<div class="px-16 pb-4 md:px-4 md:pb-0 md:w-1/6">
|
||||
<f:if condition="{teaserImage}">
|
||||
<ep:lazyLoadImage image="{teaserImage}"
|
||||
loaderimg="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
class="block w-full h-auto rounded-full"
|
||||
width="400"
|
||||
height="400c"
|
||||
alt="{teaserImage.alternative}" />
|
||||
<f:image image="{teaserImage}"
|
||||
loading="lazy"
|
||||
class="block w-full h-auto rounded-full"
|
||||
width="400"
|
||||
height="400c"
|
||||
alt="{teaserImage.alternative}" />
|
||||
</f:if>
|
||||
</div>
|
||||
<div class="px-16 md:px-4 md:w-5/6 md:pl-8 text-center text-white md:text-left" data-rte-content>
|
||||
|
||||
@@ -158,11 +158,11 @@
|
||||
target="_blank"
|
||||
rel="nofollow"
|
||||
title="Global Compact">
|
||||
<ep:lazyLoadImage src="EXT:ep_theme/Resources/Public/images/global_compact.png"
|
||||
loaderimg="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
class="block w-full h-auto"
|
||||
width="100"
|
||||
alt="Global Compact" />
|
||||
<f:image src="EXT:ep_theme/Resources/Public/images/global_compact.png"
|
||||
loading="lazy"
|
||||
class="block w-full h-auto"
|
||||
width="100"
|
||||
alt="Global Compact" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -184,8 +184,10 @@
|
||||
<f:format.raw>{totalRatings.jsonData->f:format.json()}</f:format.raw>
|
||||
</script>
|
||||
|
||||
<f:if condition="{site.identifier} == 'ep-reisen'">
|
||||
<f:render partial="Chatbot" arguments="{_all}"/>
|
||||
</f:if>
|
||||
<f:comment><!--
|
||||
<f:if condition="{site.identifier} == 'ep-reisen'">
|
||||
<f:render partial="Chatbot" arguments="{_all}"/>
|
||||
</f:if>
|
||||
--></f:comment>
|
||||
|
||||
</html>
|
||||
|
||||
@@ -9,12 +9,12 @@
|
||||
{ep:icon(icon: 'flag-{hotel.country.code -> f:format.case(mode: \'lower\')}', class: 'w-8 h-6 absolute top-0 left-0')}
|
||||
<f:if condition="{hotel.images.original.0}">
|
||||
<f:then>
|
||||
<ep:lazyLoadImage image="{hotel.images.original.0}"
|
||||
loaderimg="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
class="block w-full h-full object-cover"
|
||||
width="400c"
|
||||
height="300c"
|
||||
alt="{hotel.name}" />
|
||||
<f:image image="{hotel.images.original.0}"
|
||||
loading="lazy"
|
||||
class="block w-full h-full object-cover"
|
||||
width="400c"
|
||||
height="300c"
|
||||
alt="{hotel.name}" />
|
||||
</f:then>
|
||||
<f:else>
|
||||
<f:image src="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
|
||||
@@ -15,12 +15,12 @@
|
||||
<a href="{f:uri.image(image: image, cropVariant: 'zoom', maxWidth: '2560')}"
|
||||
title="{image.title}"
|
||||
data-action="lightbox#open">
|
||||
<ep:lazyLoadImage image="{image}"
|
||||
loaderimg="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
class="block w-full h-auto"
|
||||
width="770"
|
||||
height="430c+100"
|
||||
alt="{image.alternative}"/>
|
||||
<f:image image="{image}"
|
||||
loading="lazy"
|
||||
class="block w-full h-auto"
|
||||
width="770"
|
||||
height="430c+100"
|
||||
alt="{image.alternative}"/>
|
||||
</a>
|
||||
</f:alias>
|
||||
<f:if condition="{thumbnails}">
|
||||
@@ -35,12 +35,12 @@
|
||||
data-lightbox-caption="{image.originalResource.description}"
|
||||
title="{image.title}"
|
||||
class="block">
|
||||
<ep:lazyLoadImage image="{image}"
|
||||
loaderimg="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
class="block w-full h-auto"
|
||||
width="150"
|
||||
height="85c+100"
|
||||
alt="{image.alternative}"/>
|
||||
<f:image image="{image}"
|
||||
loading="lazy"
|
||||
class="block w-full h-auto"
|
||||
width="150"
|
||||
height="85c+100"
|
||||
alt="{image.alternative}"/>
|
||||
</a>
|
||||
</f:if>
|
||||
</f:for>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<html data-namespace-typo3-fluid="true" lang="en"
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers"
|
||||
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
|
||||
|
||||
<div class="odd:bg-zinc-50 p-4" data-rte-content>
|
||||
@@ -18,12 +17,12 @@
|
||||
</h3>
|
||||
{journey.byCar -> f:format.html()}
|
||||
<f:if condition="{journey.image}">
|
||||
<ep:lazyLoadImage image="{journey.image}"
|
||||
loaderimg="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
class="block w-full h-auto"
|
||||
width="770"
|
||||
height="430c+100"
|
||||
alt="{journey.image.alternative}" />
|
||||
<f:image image="{journey.image}"
|
||||
loading="lazy"
|
||||
class="block w-full h-auto"
|
||||
width="770"
|
||||
height="430c+100"
|
||||
alt="{journey.image.alternative}" />
|
||||
</f:if>
|
||||
</f:if>
|
||||
</div>
|
||||
|
||||
@@ -10,8 +10,9 @@
|
||||
<f:then>
|
||||
<f:if condition="{newsItem.mediaPreviews.0}">
|
||||
<f:alias map="{mediaElement: '{newsItem.mediaPreviews.0}'}">
|
||||
<img class="block w-full h-auto lazyload"
|
||||
data-src="{f:uri.image(image: mediaElement, width: '640', height: '360c+50')}"
|
||||
<img class="block w-full h-auto"
|
||||
src="{f:uri.image(image: mediaElement, width: '640', height: '360c+50')}"
|
||||
loading="lazy"
|
||||
alt="{mediaElement.originalResource.alternative}">
|
||||
</f:alias>
|
||||
</f:if>
|
||||
@@ -19,8 +20,9 @@
|
||||
<f:else>
|
||||
<f:if condition="{newsItem.media}">
|
||||
<f:alias map="{mediaElement: '{newsItem.media.0}'}">
|
||||
<img class="block w-full h-auto lazyload"
|
||||
data-src="{f:uri.image(image: mediaElement, width: '640', height: '360c+50')}"
|
||||
<img class="block w-full h-auto"
|
||||
src="{f:uri.image(image: mediaElement, width: '640', height: '360c+50')}"
|
||||
loading="lazy"
|
||||
alt="{mediaElement.originalResource.alternative}">
|
||||
</f:alias>
|
||||
</f:if>
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
</div>
|
||||
<div class="col-span-1">
|
||||
<f:if condition="{officetip.author.image}">
|
||||
<ep:lazyLoadImage image="{officetip.author.image}"
|
||||
loaderimg="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
class="block w-full h-auto"
|
||||
width="120"
|
||||
alt="{officetip.author.name}" />
|
||||
<f:image image="{officetip.author.image}"
|
||||
loading="lazy"
|
||||
class="block w-full h-auto"
|
||||
width="120"
|
||||
alt="{officetip.author.name}" />
|
||||
</f:if>
|
||||
</div>
|
||||
<div class="col-span-2">
|
||||
|
||||
@@ -16,19 +16,19 @@
|
||||
<div class="relative{f:if(condition: landscape, then: ' sm:w-2/5')}">
|
||||
<f:if condition="{productImage}">
|
||||
<f:then>
|
||||
<ep:lazyLoadImage image="{productImage}"
|
||||
loaderimg="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
class="block w-full h-full object-cover"
|
||||
width="400c"
|
||||
height="300c"
|
||||
alt="{product.name}" />
|
||||
<f:image image="{productImage}"
|
||||
loading="lazy"
|
||||
class="block w-full h-full object-cover"
|
||||
width="400c"
|
||||
height="300c"
|
||||
alt="{product.name}" />
|
||||
</f:then>
|
||||
<f:else>
|
||||
<f:image src="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
class="block w-full h-full object-cover"
|
||||
width="400c"
|
||||
height="300c"
|
||||
alt="{product.name}" />
|
||||
class="block w-full h-full object-cover"
|
||||
width="400c"
|
||||
height="300c"
|
||||
alt="{product.name}" />
|
||||
</f:else>
|
||||
</f:if>
|
||||
<div class="absolute top-0 left-0 z-20 inset-x-0 p-2 flex justify-between items-center {f:if(condition: concept, then: 'bg-concept-{concept.code}/70', else: 'bg-ep-primary/80')}">
|
||||
|
||||
@@ -18,12 +18,12 @@
|
||||
</f:if>
|
||||
<f:if condition="{image}">
|
||||
<f:then>
|
||||
<ep:lazyLoadImage image="{image}"
|
||||
loaderimg="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
class="block w-full h-full object-cover"
|
||||
width="400c"
|
||||
height="300c"
|
||||
alt="{region.name}" />
|
||||
<f:image image="{image}"
|
||||
loading="lazy"
|
||||
class="block w-full h-full object-cover"
|
||||
width="400c"
|
||||
height="300c"
|
||||
alt="{region.name}" />
|
||||
</f:then>
|
||||
<f:else>
|
||||
<f:image src="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<html data-namespace-typo3-fluid="true" lang="en"
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers"
|
||||
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
|
||||
|
||||
<f:if condition="{region.webcam.available}">
|
||||
@@ -13,11 +12,11 @@
|
||||
data-action="lightbox#open"
|
||||
data-lightbox-caption="Webcam {region.name}"
|
||||
title="Webcam {region.name}">
|
||||
<ep:lazyLoadImage src="{region.webcam.url}"
|
||||
loaderimg="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
class="block w-full h-auto"
|
||||
width="330"
|
||||
alt="Webcam {region.name}" />
|
||||
<f:image src="{region.webcam.url}"
|
||||
loading="lazy"
|
||||
class="block w-full h-auto"
|
||||
width="330"
|
||||
alt="Webcam {region.name}" />
|
||||
</a>
|
||||
</div>
|
||||
</f:if>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<html data-namespace-typo3-fluid="true" lang="en"
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers"
|
||||
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
|
||||
|
||||
<f:if condition="{region.regionMaps}">
|
||||
@@ -17,11 +16,11 @@
|
||||
data-lightbox-index="{iteration.cycle}"
|
||||
data-lightbox-caption="Pistenplan {region.name}"
|
||||
title="Pistenplan {region.name}">
|
||||
<ep:lazyLoadImage image="{regionMap}"
|
||||
loaderimg="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
class="block w-full h-auto"
|
||||
width="330"
|
||||
alt="{regionMap.alternative}"/>
|
||||
<f:image image="{regionMap}"
|
||||
loading="lazy"
|
||||
class="block w-full h-auto"
|
||||
width="330"
|
||||
alt="{regionMap.alternative}"/>
|
||||
</a>
|
||||
</f:for>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<html data-namespace-typo3-fluid="true" lang="en"
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers"
|
||||
xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers"
|
||||
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
|
||||
|
||||
@@ -11,11 +10,11 @@
|
||||
Teamer vor Ort
|
||||
</p>
|
||||
<f:if condition="{teamerInCharge.image}">
|
||||
<ep:lazyLoadImage image="{teamerInCharge.image}"
|
||||
loaderimg="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
class="block w-full h-auto mb-4"
|
||||
width="330"
|
||||
alt="{teamerInCharge.name}"/>
|
||||
<f:image image="{teamerInCharge.image}"
|
||||
loading="lazy"
|
||||
class="block w-full h-auto mb-4"
|
||||
width="330"
|
||||
alt="{teamerInCharge.name}"/>
|
||||
</f:if>
|
||||
<p>{teamerInCharge.name}</p>
|
||||
</div>
|
||||
|
||||
@@ -9,12 +9,12 @@
|
||||
<f:if condition="{context.country}">
|
||||
{ep:icon(icon: 'flag-{context.country.code -> f:format.case(mode: \'lower\')}', class: 'w-8 h-6 absolute top-0 left-0')}
|
||||
</f:if>
|
||||
<ep:lazyLoadImage image="{teaserImage}"
|
||||
loaderimg="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
class="block w-full h-full object-cover"
|
||||
width="400c"
|
||||
height="300c"
|
||||
alt="{teaserImage.alternative}" />
|
||||
<f:image image="{teaserImage}"
|
||||
loading="lazy"
|
||||
class="block w-full h-full object-cover"
|
||||
width="400c"
|
||||
height="300c"
|
||||
alt="{teaserImage.alternative}" />
|
||||
</div>
|
||||
<div class="flex-1 flex flex-col pt-4 bg-white border border-t-0 border-zinc-200">
|
||||
<a href="{f:uri.typolink(parameter: data.header_link)}" class="px-2 peer headline--3 mb-2 no-underline">
|
||||
|
||||
@@ -1,62 +1,61 @@
|
||||
<html data-namespace-typo3-fluid="true" lang="en"
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers"
|
||||
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
|
||||
|
||||
<f:if condition="{image.uid}">
|
||||
<f:then>
|
||||
<picture>
|
||||
<source media="(min-width: 1201px)" data-srcset="{f:uri.image(
|
||||
<source media="(min-width: 1201px)" srcset="{f:uri.image(
|
||||
image: image, width: '370', height: '220c-100'
|
||||
)} 370w"/>
|
||||
<source media="(max-width: 1200px)" data-srcset="{f:uri.image(
|
||||
<source media="(max-width: 1200px)" srcset="{f:uri.image(
|
||||
image: image, width: '320', height: '160c-100'
|
||||
)} 320w"/>
|
||||
<source media="(max-width: 991px)" data-srcset="{f:uri.image(
|
||||
<source media="(max-width: 991px)" srcset="{f:uri.image(
|
||||
image: image, width: '360', height: '200c-100'
|
||||
)} 360w"/>
|
||||
<source media="(max-width: 768px)" data-srcset="{f:uri.image(
|
||||
<source media="(max-width: 768px)" srcset="{f:uri.image(
|
||||
image: image, width: '500', height: '250c-100'
|
||||
)} 500w"/>
|
||||
<source media="(max-width: 512px)" data-srcset="{f:uri.image(
|
||||
<source media="(max-width: 512px)" srcset="{f:uri.image(
|
||||
image: image, width: '350', height: '175c-100'
|
||||
)} 350w"/>
|
||||
<ep:lazyLoadImage image="{image}"
|
||||
loaderimg="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
class="block w-full h-auto"
|
||||
width="500"
|
||||
height="250c-100"
|
||||
alt="{image.alternative}" />
|
||||
<f:image image="{image}"
|
||||
loading="lazy"
|
||||
class="block w-full h-auto"
|
||||
width="500"
|
||||
height="250c-100"
|
||||
alt="{image.alternative}" />
|
||||
</picture>
|
||||
</f:then>
|
||||
<f:else>
|
||||
<picture>
|
||||
<source media="(min-width: 1201px)" data-srcset="{f:uri.image(
|
||||
<source media="(min-width: 1201px)" srcset="{f:uri.image(
|
||||
src: 'EXT:ep_theme/Resources/Public/images/header-winter.jpg',
|
||||
width: '370', height: '220c-100'
|
||||
)} 370w"/>
|
||||
<source media="(max-width: 1200px)" data-srcset="{f:uri.image(
|
||||
<source media="(max-width: 1200px)" srcset="{f:uri.image(
|
||||
src: 'EXT:ep_theme/Resources/Public/images/header-winter.jpg',
|
||||
width: '320', height: '160c-100'
|
||||
)} 420w"/>
|
||||
<source media="(max-width: 991px)" data-srcset="{f:uri.image(
|
||||
)} 320w"/>
|
||||
<source media="(max-width: 991px)" srcset="{f:uri.image(
|
||||
src: 'EXT:ep_theme/Resources/Public/images/header-winter.jpg',
|
||||
width: '360', height: '200c-100'
|
||||
)} 360w"/>
|
||||
<source media="(max-width: 768px)" data-srcset="{f:uri.image(
|
||||
<source media="(max-width: 768px)" srcset="{f:uri.image(
|
||||
src: 'EXT:ep_theme/Resources/Public/images/header-winter.jpg',
|
||||
width: '500', height: '250c-100'
|
||||
)} 500w"/>
|
||||
<source media="(max-width: 512px)" data-srcset="{f:uri.image(
|
||||
<source media="(max-width: 512px)" srcset="{f:uri.image(
|
||||
src: 'EXT:ep_theme/Resources/Public/images/header-winter.jpg',
|
||||
width: '350', height: '175c-100'
|
||||
)} 320w"/>
|
||||
<ep:lazyLoadImage src="EXT:ep_theme/Resources/Public/images/header-winter.jpg"
|
||||
loaderimg="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
class="block w-full h-auto"
|
||||
width="360"
|
||||
height="270c-100"
|
||||
alt="" />
|
||||
)} 350w"/>
|
||||
<f:image src="EXT:ep_theme/Resources/Public/images/header-winter.jpg"
|
||||
loading="lazy"
|
||||
class="block w-full h-auto"
|
||||
width="360"
|
||||
height="270c-100"
|
||||
alt="" />
|
||||
</picture>
|
||||
</f:else>
|
||||
</f:if>
|
||||
|
||||
@@ -1,25 +1,27 @@
|
||||
<f:if condition="{image}">
|
||||
<f:then>
|
||||
<picture class="product-teaser__image">
|
||||
<source media="(min-width: 1201px)" data-srcset="{f:uri.image(
|
||||
<source media="(min-width: 1201px)" srcset="{f:uri.image(
|
||||
image: image, width: '320', height: '200c-100'
|
||||
)} 320w"/>
|
||||
<source media="(max-width: 1200px)" data-srcset="{f:uri.image(
|
||||
<source media="(max-width: 1200px)" srcset="{f:uri.image(
|
||||
image: image, width: '220', height: '130c-100'
|
||||
)} 220w"/>
|
||||
<source media="(max-width: 991px)" data-srcset="{f:uri.image(
|
||||
<source media="(max-width: 991px)" srcset="{f:uri.image(
|
||||
image: image, width: '260', height: '220c-100'
|
||||
)} 260w"/>
|
||||
<source media="(max-width: 768px)" data-srcset="{f:uri.image(
|
||||
<source media="(max-width: 768px)" srcset="{f:uri.image(
|
||||
image: image, width: '320', height: '140c-100'
|
||||
)} 320w"/>
|
||||
<img class="scale lazyload" alt="{image.alternative}"
|
||||
src="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/lazy.png', width: '260', height: '160')}"
|
||||
data-src="{f:uri.image(image: image, width: '260', height: '160c-100')}"
|
||||
<img class="scale" alt="{image.alternative}"
|
||||
src="{f:uri.image(image: image, width: '260', height: '160c-100')}"
|
||||
loading="lazy"
|
||||
>
|
||||
</picture>
|
||||
</f:then>
|
||||
<f:else>
|
||||
<img class="scale" data-src="https://placehold.it/400x300" alt="">
|
||||
<img class="scale" alt=""
|
||||
src="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/lazy.png', width: '260', height: '160')}"
|
||||
loading="lazy">
|
||||
</f:else>
|
||||
</f:if>
|
||||
|
||||
@@ -7,8 +7,9 @@
|
||||
{data.bodytext -> f:format.html()}
|
||||
<f:if condition="{files}">
|
||||
<f:link.typolink parameter="{files.0.link}" title="{files.0.originalResource.title}">
|
||||
<img class="img-responsive lazyload"
|
||||
data-src="{f:uri.image(image: files.0, maxWidth: '770')}"
|
||||
<img class="img-responsive"
|
||||
src="{f:uri.image(image: files.0, maxWidth: '770')}"
|
||||
loading="lazy"
|
||||
alt="{files.0.originalResource.alternative}">
|
||||
</f:link.typolink>
|
||||
</f:if>
|
||||
|
||||
+6
-7
@@ -1,7 +1,6 @@
|
||||
<html data-namespace-typo3-fluid="true" lang="en"
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers"
|
||||
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers"
|
||||
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
|
||||
|
||||
<f:section name="Content">
|
||||
@@ -25,12 +24,12 @@
|
||||
<f:section name="Image">
|
||||
<div class="{cssClasses}">
|
||||
<f:link.typolink parameter="{image.link}">
|
||||
<ep:lazyLoadImage image="{image}"
|
||||
loaderimg="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
class="block w-full h-auto"
|
||||
width="400c"
|
||||
height="400"
|
||||
alt="{image.alternative}" />
|
||||
<f:image image="{image}"
|
||||
loading="lazy"
|
||||
class="block w-full h-auto"
|
||||
width="400c"
|
||||
height="400"
|
||||
alt="{image.alternative}" />
|
||||
</f:link.typolink>
|
||||
</div>
|
||||
</f:section>
|
||||
|
||||
+5
-6
@@ -10,12 +10,11 @@
|
||||
<f:for each="{items}" as="item" iteration="iteration">
|
||||
<div class="lg:flex odd:flex-row-reverse justify-between items-end mb-16">
|
||||
<div class="mb-4 lg:mb-0 lg:w-1/2">
|
||||
<ep:lazyLoadImage image="{item.image.0}"
|
||||
loaderimg="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
class="block w-full h-auto"
|
||||
width="768"
|
||||
alt="{item.data.name}"
|
||||
title="{item.data.name}" />
|
||||
<f:image image="{item.image.0}"
|
||||
loading="lazy"
|
||||
class="block w-full h-auto"
|
||||
width="768"
|
||||
alt="{item.data.name}"/>
|
||||
</div>
|
||||
<div class="lg:w-1/2">
|
||||
<div class="px-4 {f:if(condition: iteration.isEven, then: 'lg:pl-12', else: 'lg:pr-12')}">
|
||||
|
||||
+6
-7
@@ -1,6 +1,5 @@
|
||||
<html data-namespace-typo3-fluid="true" lang="en"
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers"
|
||||
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
|
||||
|
||||
<f:layout name="Bare"/>
|
||||
@@ -12,12 +11,12 @@
|
||||
<use href="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/icons_sprite.svg')}#icon-flag-{country.code -> f:format.case(mode: 'lower')}"></use>
|
||||
</svg>
|
||||
<f:if condition="{country.teaserImages}">
|
||||
<ep:lazyLoadImage image="{country.teaserImages.0}"
|
||||
loaderimg="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
class="block w-full h-full object-cover"
|
||||
width="400c"
|
||||
height="300c"
|
||||
alt="{country.name}" />
|
||||
<f:image image="{country.teaserImages.0}"
|
||||
loading="lazy"
|
||||
class="block w-full h-full object-cover"
|
||||
width="400c"
|
||||
height="300c"
|
||||
alt="{country.name}" />
|
||||
</f:if>
|
||||
</div>
|
||||
<div class="flex-1 flex flex-col pt-4 bg-white border border-t-0 border-zinc-200">
|
||||
|
||||
@@ -182,12 +182,11 @@
|
||||
title="360°-Rundgang {hotel.name}">
|
||||
<f:if condition="{product.tourThumbnail}">
|
||||
<f:then>
|
||||
<ep:lazyLoadImage image="{product.tourThumbnail}"
|
||||
loaderimg="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
class="block w-full h-auto"
|
||||
width="330"
|
||||
alt="360°-Rundgang {hotel.name}"
|
||||
title="360°-Rundgang {hotel.name}"/>
|
||||
<f:image image="{product.tourThumbnail}"
|
||||
loading="lazy"
|
||||
class="block w-full h-auto"
|
||||
width="330"
|
||||
alt="360°-Rundgang {hotel.name}"/>
|
||||
</f:then>
|
||||
<f:else>
|
||||
<div class="button bg-button w-full">
|
||||
@@ -335,11 +334,11 @@
|
||||
data-lightbox-caption="{image.originalResource.description}"
|
||||
data-action="lightbox#open"
|
||||
class="{f:if(condition: iteration.isFirst, then: 'col-span-4')}">
|
||||
<ep:lazyLoadImage image="{image}"
|
||||
loaderimg="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
class="block w-full h-auto"
|
||||
width="{f:if(condition: iteration.isFirst, then: '400', else: '160')}"
|
||||
height="{f:if(condition: iteration.isFirst, then: '225c+100', else: '160c+100')}"/>
|
||||
<f:image image="{image}"
|
||||
loading="lazy"
|
||||
class="block w-full h-auto"
|
||||
width="{f:if(condition: iteration.isFirst, then: '400', else: '160')}"
|
||||
height="{f:if(condition: iteration.isFirst, then: '225c+100', else: '160c+100')}"/>
|
||||
</a>
|
||||
</f:for>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<html data-namespace-typo3-fluid="true" lang="en"
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers"
|
||||
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers"
|
||||
xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers">
|
||||
|
||||
<f:layout name="Default"/>
|
||||
@@ -28,13 +27,12 @@
|
||||
arguments: '{member: member}'
|
||||
)}">
|
||||
<f:if condition="{member.image}">
|
||||
<ep:lazyLoadImage image="{member.image}"
|
||||
loaderimg="EXT:ep_theme/Resources/Public/images/lazy.png"
|
||||
class="block w-full h-auto rounded-full"
|
||||
width="400"
|
||||
height="400c"
|
||||
alt="{member.name}"
|
||||
title="{member.name}" />
|
||||
<f:image image="{member.image}"
|
||||
loading="lazy"
|
||||
class="block w-full h-auto rounded-full"
|
||||
width="400"
|
||||
height="400c"
|
||||
alt="{member.name}"/>
|
||||
</f:if>
|
||||
<div class="text-center text-zinc-800 pt-2">
|
||||
<span class="block font-bold text-xl">
|
||||
|
||||
@@ -9,7 +9,6 @@ Encore
|
||||
.setOutputPath('./public/typo3conf/ext/ep_theme/Resources/Public/')
|
||||
.setPublicPath('/typo3conf/ext/ep_theme/Resources/Public/')
|
||||
.addEntry('main', './public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/main.js')
|
||||
.addEntry('groups-calculator', './public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/groups-calculator.js')
|
||||
.addStyleEntry('rte', './public/typo3conf/ext/ep_theme/Resources/Private/Assets/scss/rte.scss')
|
||||
.splitEntryChunks()
|
||||
.enableSingleRuntimeChunk()
|
||||
|
||||
Reference in New Issue
Block a user