Compare commits

...
10 Commits
Author SHA1 Message Date
frommeandClaude Opus 5.5 ea2eda5ee1 fix: palettes in record forms use the full width in the backend
TYPO3 13 lays out palette rows with more than four fields in sixth-width
columns and breaks the line after every second field, so the product form's
top palette showed up as a narrow column. Line breaks keep every row at four
fields or fewer (product, hotel, city).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-22 16:53:11 +02:00
frommeandClaude Opus 5.5 20225ad9e3 fix: /reiseinformationen/ without a travel info answers 404 instead of 500
The page holds only the travel info plugin, whose default action required
a travel info: opened without a slug or code it failed with "Required
argument travelInfo is not set" (TYPO3 10 did the same). The argument is
optional now and its absence gives the same 404 as an unknown slug or travel
code (notFound(), shared with travelCodeAction).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-22 15:47:19 +02:00
frommeandClaude Opus 5.5 ebc9925304 fix: office tip labels no longer warn when the author was deleted
21 of 53 office tips still point to team members who have left (deleted
records), so the backend label read 'name' from null: "Trying to access
array offset on null" in production. TYPO3 10 on PHP 7.4 printed an empty
name silently. The label is now the tip's text, with the author in brackets
only when the team member still exists; a tip record that cannot be found
(e.g. a new one) gives an empty title instead of a warning.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-22 15:46:04 +02:00
frommeandClaude Opus 5.5 48e049671e feat: search bar on TYPO3 13, loaded into the static pages, searching by GET
The search bar in the page header is back (SearchbarController, lib.searchBar
and lib.searchBarCollapsed), in the Subpage, SubpageSidebarRight and Detail
layouts as on TYPO3 10; product pages get the collapsed bar and its toggle
button in the main navigation again.

- The bar takes no arguments, so it is the same on every page of a site and
  cacheable. Page types 1706/1707 (/searchbar, /searchbar-collapsed on the
  ep-reisen root, also under /en/) render it alone for the static pages,
  which replace their exported bar with it via htmx. The suffixes have no
  leading slash: on the root page the route path has none, so "/searchbar"
  would never match (as /form and /snowreport do not there either).
- The form sends dateFrom, dateTo, pax, destinationType, destinationUid and
  priceRange by GET to the search page instead of POSTing to processSearch:
  no signed fields and no redirect, and URLs of about 100 characters instead
  of about 870. SearchController reads them (SEARCHBAR_PARAMETERS, excluded
  from the cHash; the results are not cached) and drops anything but a real
  Y-m-d date, which made DateUtility::formatDateRange() throw.
  processSearch is removed.
- The date range label is empty without arguments, so the template no longer
  needs ep:dateRange.

Compared with TYPO3 10: the bar's markup matches apart from the form (open,
collapsed, /en/); seven searches by GET load the same filter settings and
hit counts as the TYPO3 10 POST.

The static pages get the island from the exporter in EP/website, see
.ddev/plans/static-export-searchbar-island.patch (local only).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-22 15:43:24 +02:00
frommeandClaude Opus 5.5 b5637ba86e fix: hotels without a category no longer break product teasers
29 hotels have category 0, which has no label. The product teasers looked
the label up unguarded, an "Undefined array key 0" warning: a 500 in DDEV
(warnings are exceptions there), a logged warning in production. The
teaser and the hotel serializer now use null for an unknown category, as
SearchResultService and HotelDataService already do; TYPO3 10 ended up
with null as well.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-22 15:15:04 +02:00
frommeandClaude Opus 5.5 ca2fdc1e13 feat: snow reports on TYPO3 13, with a page type for the static pages
The snow report list ("Schneehöhen" plugin) is ported from TYPO3 10:
SnowreportController, SnowreportRepository::getSnowreportsForRegions(),
the plugin registration with its flexform (regions) and the template,
which now formats dates with d.m.Y.

Page type 1705 (/<page>/snowreport) renders only the snow report plugins
of a page, like /form for forms. The static pages of the hybrid setup can
load it to replace the snow reports frozen at export time; each list
carries id="snowreport-<content uid>" for hx-select, since TYPO3 10 gives
the plugin no element of its own. ep:import-snowreport already flushes
the page cache after each import. The suffix is in the PageType enhancer
of every site with snow reports.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

feat: the snow report box includes the spacing of its content element

id="snowreport-<content uid>" moves from the list to a wrapper around
ep:container. The static pages of the hybrid setup no longer export the
snow reports at all, only an empty placeholder that loads the whole box,
spacing included, from /<page>/snowreport, so a page never shows
outdated snow depths.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-22 14:19:53 +02:00
frommeandClaude Opus 5.5 62f3bee230 fix: forms on pages TYPO3 13 renders itself can be submitted
The .form-island wrapper existed only in the form page type (/form), so
on pages TYPO3 13 renders completely (e.g. the EP ambassador page) the
form's hx-target="closest .form-island" found nothing and submitting did
nothing. The island with its loading overlay now comes from the form
plugin's template (Render.html), on full pages and in /form alike; the
page type renders just the plugin again.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-22 12:45:32 +02:00
frommeandClaude Opus 5.5 f925c7f2d6 chore: commit the German language packs instead of fetching them on deploy
TYPO3's base distribution keeps var/labels in Git (!/var/labels in
.gitignore): the release build takes them from git archive, so deploys
no longer depend on the translation server. Update them with
"vendor/bin/typo3 language:update de" and commit the result.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-22 12:13:01 +02:00
frommeandClaude Opus 5.5 925e24397b feat: forms on TYPO3 13, loaded into the static pages with htmx
The static export replaced every EXT:form form with a contact notice. The
forms are back, rendered by TYPO3 13 and embedded in the static pages:

- Page type 1704 (/<page>/form) renders only the form plugin of a page,
  inside a .form-island element. Every form posts to that URL
  (renderingOptions.additionalParams), because on www the page URL is a
  static file that never reaches TYPO3. htmx swaps the island in place:
  validation errors, multi-step pages and confirmations. A redirect to an
  htmx request becomes HX-Redirect (HtmxRedirectMiddleware), so Redirect
  finishers send the browser to the thank-you page.
- While a request runs, an overlay with a spinner (as in MyE&P) covers
  the form. Styled inside the island: the static pages load the CSS of
  the TYPO3 10 export.
- The bw_captcha image comes from /<page>/captcha for the same reason.
  Both suffixes are in the PageType enhancer of every site with forms
  (semesterende gets one with default '' to keep its URLs).
- Ported from TYPO3 10: form setup, templates and partials, the MyE&P
  address finisher, the job application finisher with the MyE&P Team
  API client (epTeamApi* in secrets.php), the page URL/referrer finisher
  with ReferrerMiddleware (?ref=), the e-mail layout without the system
  footer, bw_captcha 5 and form_element_linked_checkbox 6. The address
  check forms are dropped.
- German language packs (EXT:form messages): availableLanguages = de,
  fetched on every deploy (typo3:language:update).
- The checkbox partials passed null to VHS' substring, which PHP 8.5
  reports as deprecated.
- DDEV no longer turns deprecations into exceptions, matching
  production: EXT:form's RenderFormValueViewHelper uses null as an array
  offset for empty optional fields (core bug, also in 13.4.37).

The static pages get their placeholders from the exporter in EP/website,
see .ddev/plans/static-export-form-islands.patch (local only).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-22 12:10:43 +02:00
fromme 59e4a2d49b chore: code cleanup 2026-10-22 11:10:37 +02:00
197 changed files with 23753 additions and 69 deletions

No files matched your search

Generated
+272 -1
View File
@@ -128,6 +128,91 @@
},
"time": "2026-04-05T21:06:35+00:00"
},
{
"name": "blueways/bw-captcha",
"version": "5.4.2",
"source": {
"type": "git",
"url": "https://github.com/maikschneider/bw_captcha.git",
"reference": "74c5bbce91285b146c3c8dbbb2916783c0227c38"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/maikschneider/bw_captcha/zipball/74c5bbce91285b146c3c8dbbb2916783c0227c38",
"reference": "74c5bbce91285b146c3c8dbbb2916783c0227c38",
"shasum": ""
},
"require": {
"ext-gd": "*",
"gregwar/captcha": "^2.1",
"maikschneider/steganography": "^1.0",
"php": "^8.2",
"typo3/cms-core": "^12.0 || ^13.0 || ^14.0"
},
"require-dev": {
"armin/editorconfig-cli": "^2.0",
"bk2k/bootstrap-package": "^15.0 || ^16.0",
"derhansen/sf_event_mgt": "^7.6 || ^8.0 || ^9.0",
"eliashaeussler/typo3-vendor-bundler": "^4.0",
"ergebnis/composer-normalize": "^2.44",
"friendsofphp/php-cs-fixer": "^3.12",
"helhum/typo3-console": "^7.0 || ^8.0 || ^9.0",
"helmich/typo3-typoscript-lint": "^3.2",
"move-elevator/composer-translation-validator": "^1.3.1",
"saschaegerer/phpstan-typo3": "^2.1.1 || ^3.0.0",
"ssch/typo3-rector": "^3.9.0",
"typo3/cms-base-distribution": "^12.4 || ^13.4 || ^14.0",
"typo3/cms-lowlevel": "^12.4 || ^13.4 || ^14.0"
},
"type": "typo3-cms-extension",
"extra": {
"typo3/cms": {
"web-dir": "public",
"extension-key": "bw_captcha",
"cms-package-dir": "{$vendor-dir}/typo3/cms",
"vendor-libraries": {
"root-path": "Resources/Private/Libs",
"sbom-file": "Resources/Private/Libs/sbom.json"
}
}
},
"autoload": {
"psr-4": {
"Gregwar\\": [
"Resources/Private/Libs/vendor/gregwar/captcha/src/Gregwar"
],
"Blueways\\BwCaptcha\\": [
"Classes"
],
"MaikSchneider\\Steganography\\": [
"Resources/Private/Libs/vendor/maikschneider/steganography/src"
]
},
"exclude-from-classmap": [
"Resources/Private/Libs/vendor/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-2.0-or-later"
],
"authors": [
{
"name": "Maik Schneider",
"email": "[email protected]",
"role": "Developer"
}
],
"description": "Captcha element with audio support for TYPO3 form components. The captcha generation does not rely on Google or third-party integrations.",
"keywords": [
"typo3"
],
"support": {
"issues": "https://github.com/maikschneider/bw_captcha/issues",
"source": "https://github.com/maikschneider/bw_captcha/tree/5.4.2"
},
"time": "2026-10-20T05:07:13+00:00"
},
{
"name": "christian-riesen/base32",
"version": "2.0.1",
@@ -865,16 +950,19 @@
"dist": {
"type": "path",
"url": "./packages/ep_theme",
"reference": "f3e425fca030011066b3d2e6a25a756941885b0d"
"reference": "3848f9e276e8ece16ce7755556c4ef033c93f357"
},
"require": {
"b13/container": "^4.1",
"blueways/bw-captcha": "^5.4",
"ep/ep-products": "@dev",
"php": "^8.2",
"tritum/form-element-linked-checkbox": "^6.0",
"typo3/cms-core": "^13.4",
"typo3/cms-extbase": "^13.4",
"typo3/cms-fluid": "^13.4",
"typo3/cms-fluid-styled-content": "^13.4",
"typo3/cms-form": "^13.4",
"typo3/cms-frontend": "^13.4"
},
"type": "typo3-cms-extension",
@@ -1046,6 +1134,68 @@
},
"time": "2026-07-23T10:57:34+00:00"
},
{
"name": "gregwar/captcha",
"version": "v2.1.1",
"source": {
"type": "git",
"url": "https://github.com/Gregwar/Captcha.git",
"reference": "c1e67b3d7ac4f873f785daa366051d7c73d19ca0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Gregwar/Captcha/zipball/c1e67b3d7ac4f873f785daa366051d7c73d19ca0",
"reference": "c1e67b3d7ac4f873f785daa366051d7c73d19ca0",
"shasum": ""
},
"require": {
"ext-fileinfo": "*",
"ext-gd": "*",
"ext-mbstring": "*",
"php": "^8.2",
"symfony/finder": "*"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.49",
"phpstan/phpstan": "2.1.17",
"phpstan/phpstan-phpunit": "2.0.6",
"phpunit/phpunit": "^9.6",
"squizlabs/php_codesniffer": "4.0.4"
},
"type": "library",
"autoload": {
"psr-4": {
"Gregwar\\": "src/Gregwar"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Grégoire Passault",
"email": "[email protected]",
"homepage": "http://www.gregwar.com/"
},
{
"name": "Jeremy Livingston",
"email": "[email protected]"
}
],
"description": "Captcha generator",
"homepage": "https://github.com/Gregwar/Captcha",
"keywords": [
"bot",
"captcha",
"spam"
],
"support": {
"issues": "https://github.com/Gregwar/Captcha/issues",
"source": "https://github.com/Gregwar/Captcha/tree/v2.1.1"
},
"time": "2026-08-27T10:37:12+00:00"
},
{
"name": "guzzlehttp/guzzle",
"version": "8.3.0",
@@ -1591,6 +1741,56 @@
},
"time": "2025-10-31T12:28:27+00:00"
},
{
"name": "maikschneider/steganography",
"version": "v1.0.2",
"source": {
"type": "git",
"url": "https://github.com/maikschneider/steganography.git",
"reference": "6a796c6367d38ac06837d309fba78ffaa4738681"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/maikschneider/steganography/zipball/6a796c6367d38ac06837d309fba78ffaa4738681",
"reference": "6a796c6367d38ac06837d309fba78ffaa4738681",
"shasum": ""
},
"require": {
"ext-gd": "*",
"ext-zlib": "*",
"symfony/options-resolver": ">4.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.12",
"php-coveralls/php-coveralls": "^2.0",
"phpunit/phpunit": "^10.3",
"rector/rector": "^0.18.0"
},
"type": "library",
"autoload": {
"psr-4": {
"MaikSchneider\\Steganography\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Maik Schneider",
"email": "[email protected]"
}
],
"description": "Simple implementation of Steganography (Hiding a hidden message within an image)",
"keywords": [
"steganography"
],
"support": {
"source": "https://github.com/maikschneider/steganography/tree/v1.0.2"
},
"time": "2023-10-08T10:39:48+00:00"
},
{
"name": "masterminds/html5",
"version": "2.11.0",
@@ -6217,6 +6417,77 @@
],
"time": "2026-10-12T12:34:30+00:00"
},
{
"name": "tritum/form-element-linked-checkbox",
"version": "v6.0.0",
"source": {
"type": "git",
"url": "https://github.com/tritum/form_element_linked_checkbox.git",
"reference": "cad79670c59d7d52f7cde0d74ab10e9b5e6c78fa"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/tritum/form_element_linked_checkbox/zipball/cad79670c59d7d52f7cde0d74ab10e9b5e6c78fa",
"reference": "cad79670c59d7d52f7cde0d74ab10e9b5e6c78fa",
"shasum": ""
},
"require": {
"php": "^8.2",
"typo3/cms-core": "^13.4 || ^14.1",
"typo3/cms-form": "^13.4 || ^14.1",
"typo3/cms-frontend": "^13.4 || ^14.1"
},
"require-dev": {
"armin/editorconfig-cli": "^2.2",
"ergebnis/composer-normalize": "^2.23",
"helmich/typo3-typoscript-lint": "^3.1",
"phpstan/phpstan": "^1.3",
"saschaegerer/phpstan-typo3": "^1.0",
"typo3/coding-standards": "^0.8.0"
},
"type": "typo3-cms-extension",
"extra": {
"typo3/cms": {
"extension-key": "form_element_linked_checkbox"
}
},
"autoload": {
"psr-4": {
"TRITUM\\FormElementLinkedCheckbox\\": "Classes/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-2.0-or-later"
],
"authors": [
{
"name": "Björn Jacob",
"email": "[email protected]",
"homepage": "https://www.tritum.de",
"role": "Developer"
},
{
"name": "Elias Häußler",
"email": "[email protected]",
"homepage": "https://haeussler.dev",
"role": "Developer"
},
{
"name": "dreistrom.land",
"email": "[email protected]",
"homepage": "https://dreistrom.land",
"role": "Developer"
}
],
"description": "Adds a new form element which allows the editor to create a checkbox with a linked label text. This is an extension for TYPO3 CMS.",
"homepage": "https://github.com/tritum/form_element_linked_checkbox",
"support": {
"issues": "https://github.com/tritum/form_element_linked_checkbox/issues",
"source": "https://github.com/tritum/form_element_linked_checkbox/tree/v6.0.0"
},
"time": "2026-02-24T09:59:51+00:00"
},
{
"name": "typo3/class-alias-loader",
"version": "v1.2.2",
+5
View File
@@ -282,6 +282,11 @@ routeEnhancers:
/: 0
/json: 1701
/html: 1702
/form: 1704
/captcha: 3413
searchbar: 1706
searchbar-collapsed: 1707
/snowreport: 1705
.json: 1803
.ical: 1710
sitemap.xml: 1533906435
+9
View File
@@ -79,6 +79,15 @@ routeEnhancers:
hotel_uid: \d+
date_from: '\d{4}\-\d{2}\-\d{2}'
date_to: '\d{4}\-\d{2}\-\d{2}'
# Only for the form, captcha and snow report page types; default '' keeps the URLs without trailing slash
PageTypeSuffix:
type: PageType
default: ''
index: ''
map:
/form: 1704
/captcha: 3413
/snowreport: 1705
routes:
-
route: robots.txt
+3
View File
@@ -66,6 +66,9 @@ routeEnhancers:
/: 0
/json: 1701
/html: 1702
/form: 1704
/captcha: 3413
/snowreport: 1705
sitemap.xml: 1533906435
yoast-snippetpreview.json: 1480321830
routes:
+2
View File
@@ -50,6 +50,8 @@ routeEnhancers:
/: 0
/json: 1701
/html: 1702
/form: 1704
/captcha: 3413
sitemap.xml: 1533906435
yoast-snippetpreview.json: 1480321830
routes:
+3
View File
@@ -50,6 +50,9 @@ routeEnhancers:
/: 0
/json: 1701
/html: 1702
/form: 1704
/captcha: 3413
/snowreport: 1705
sitemap.xml: 1533906435
yoast-snippetpreview.json: 1480321830
routes:
+3
View File
@@ -50,6 +50,9 @@ routeEnhancers:
/: 0
/json: 1701
/html: 1702
/form: 1704
/captcha: 3413
/snowreport: 1705
sitemap.xml: 1533906435
yoast-snippetpreview.json: 1480321830
routes:
+5 -2
View File
@@ -35,8 +35,11 @@ if (getenv('IS_DDEV_PROJECT') == 'true') {
'trustedHostsPattern' => '.*.*',
'devIPmask' => '*',
'displayErrors' => 1,
// Warnings and deprecations are exceptions locally: they are how PHP 7.4 leftovers show up
'exceptionalErrors' => 12290,
// Warnings are exceptions locally: they are how PHP 7.4 leftovers show up. Deprecations
// are not (production neither): PHP 8.5 deprecations in vendor code, e.g. EXT:form's
// RenderFormValueViewHelper, would break requests that work in production. They are
// still written to the deprecation log.
'exceptionalErrors' => E_WARNING | E_RECOVERABLE_ERROR,
],
'BE' => [
'debug' => true,
+3
View File
@@ -28,6 +28,9 @@ return [
'myEpApiClientSecret' => '',
'myEpApiUrlAuthorize' => '',
'myEpApiUrlToken' => '',
// MyE&P Team: job application forms (ApplicationApiFinisher), POST /api/application-forms
'epTeamApiBaseUrl' => '',
'epTeamApiKey' => '',
// ep:groups-swiss (cron, daily): availability of the group houses on groups.swiss.
// Production only; the keys are in the TYPO3 10 scheduler tasks 16-21.
// 'groupsSwissHouses' => [
+7
View File
@@ -25,6 +25,13 @@ return [
],
],
],
'EXTCONF' => [
'lang' => [
'availableLanguages' => [
'de',
],
],
],
'EXTENSIONS' => [
'backend' => [
'backendFavicon' => '',
+1 -1
View File
@@ -87,7 +87,7 @@ desc('Build the release locally: committed state, production dependencies, theme
task('build', function () {
// Inside DDEV directly, on the host through "ddev exec" (paths relative to the project root)
$inDdev = getenv('IS_DDEV_PROJECT') === 'true';
$exec = fn (string $command) => runLocally($inDdev
$exec = fn(string $command) => runLocally($inDdev
? $command
: 'ddev exec bash -c ' . escapeshellarg($command));
runLocally('rm -rf {{build_dir}} && mkdir -p {{build_dir}}');
@@ -40,6 +40,12 @@ class SearchController extends ActionController
use RequestArgumentTypeConversionTrait;
/**
* The fields of the search bar (Templates/Searchbar/Index.html), sent by GET to the search
* page and excluded from the cHash: the visitor chooses the values
*/
public const SEARCHBAR_PARAMETERS = ['dateFrom', 'dateTo', 'pax', 'destinationType', 'destinationUid', 'priceRange'];
/**
* @var FilterService
*/
@@ -59,32 +65,6 @@ class SearchController extends ActionController
$this->searchResultService = $searchResultService;
}
public function initializeProcessSearchAction()
{
$this->processSearchParamsArgument();
}
/**
* @param array $searchParams
*/
public function processSearchAction(array $searchParams): ResponseInterface
{
$filterSettings = $this->filterService->getFilterSettingsFromSearchParams($searchParams);
$redirectUri = $this->uriBuilder
->reset()
->setCreateAbsoluteUri(true)
->uriFor(
'searchresult',
['filterSettings' => $filterSettings],
null,
null,
'searchresult'
);
return $this->redirectToUri($redirectUri);
}
public function initializeSearchresultAction()
{
// Process encoded filtersettings from static search result.
@@ -98,6 +78,24 @@ class SearchController extends ActionController
$this->request = $this->request->withArgument('filterSettings', $filterSettings);
}
}
// The fields of the search bar, which sends them here by GET
$searchbarParameters = array_filter(
array_intersect_key($this->request->getQueryParams(), array_flip(self::SEARCHBAR_PARAMETERS)),
'is_string'
);
// Anything but a real Y-m-d date is dropped: the URL is easy to edit, and
// DateUtility::formatDateRange() throws on what DateTime cannot read
foreach (['dateFrom', 'dateTo'] as $name) {
$date = \DateTime::createFromFormat('!Y-m-d', $searchbarParameters[$name] ?? '');
if (!$date || $date->format('Y-m-d') !== $searchbarParameters[$name]) {
unset($searchbarParameters[$name]);
}
}
if ($searchbarParameters !== [] && !$this->request->hasArgument('filterSettings')) {
$searchParams = $this->searchResultService->getNormalizedSearchParams($searchbarParameters);
$filterSettings = $this->filterService->getFilterSettingsFromSearchParams($searchParams);
$this->request = $this->request->withArgument('filterSettings', $filterSettings);
}
$forcedConceptUids = GeneralUtility::intExplode(',', $this->settings['forcedConceptUids'] ?? '', true);
$this->processFilterSettingsArgument($forcedConceptUids);
}
@@ -0,0 +1,66 @@
<?php
namespace EP\EpProducts\Controller;
/***************************************************************
*
* Copyright notice
*
* (c) 2016 Björn Fromme <[email protected]>, dreipunktnull
*
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
use EP\EpProducts\Service\FilterService;
use EP\EpProducts\Service\SearchResultService;
use Psr\Http\Message\ResponseInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
/**
* The search bar in the page header. It takes no arguments: the options come from the products
* the site can show, so the output is the same on every page of a site (cacheable), and the
* static pages of the hybrid setup load it from <site root>/searchbar (Page/Searchbar.typoscript).
* The form sends its fields by GET to the search page (SearchController::SEARCHBAR_PARAMETERS).
*/
class SearchbarController extends ActionController
{
public function __construct(
private readonly FilterService $filterService,
private readonly SearchResultService $searchResultService,
) {
}
public function indexAction(): ResponseInterface
{
$searchParams = $this->searchResultService->getNormalizedSearchParams();
$forcedConceptUids = GeneralUtility::intExplode(',', $this->settings['forcedConceptUids'] ?? '', true);
$filterSettings = $this->filterService->getFilterSettingsFromSearchParams($searchParams, $forcedConceptUids);
$excludedConceptUids = GeneralUtility::intExplode(',', $this->settings['excludedConceptUids'] ?? '', true);
$searchResult = $this->searchResultService->getResult($filterSettings, $excludedConceptUids);
$this->view->assignMultiple([
'filterOptions' => $this->filterService->collectFilterOptionsFromSearchResult($searchResult),
'searchParams' => $searchParams,
'collapsed' => (bool)($this->settings['collapsed'] ?? false),
]);
return $this->htmlResponse();
}
}
@@ -0,0 +1,23 @@
<?php
namespace EP\EpProducts\Controller;
use EP\EpProducts\Domain\Repository\SnowreportRepository;
use Psr\Http\Message\ResponseInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
class SnowreportController extends ActionController
{
public function __construct(private readonly SnowreportRepository $snowreportRepository)
{
}
public function listAction(): ResponseInterface
{
$regionUids = GeneralUtility::intExplode(',', (string)($this->settings['regionUids'] ?? ''), true);
$this->view->assign('data', $this->request->getAttribute('currentContentObject')?->data ?? []);
$this->view->assign('list', $this->snowreportRepository->getSnowreportsForRegions($regionUids));
return $this->htmlResponse();
}
}
@@ -45,25 +45,35 @@ class TravelinfoController extends ActionController
// return 404 in case no travel info is available as last resort
if (null === $travelInfo) {
$response = GeneralUtility::makeInstance(ErrorController::class)->pageNotFoundAction(
$this->request,
'Reiseinformationen nicht gefunden'
);
throw new ImmediateResponseException($response, 1731071856);
$this->notFound();
}
$this->handleRequest($travelCode, $travelInfo);
return $this->htmlResponse();
}
public function travelInfoAction(Travelinfo $travelInfo): ResponseInterface
public function travelInfoAction(?Travelinfo $travelInfo = null): ResponseInterface
{
// the page itself (/reiseinformationen/) without a travel info or code
if (null === $travelInfo) {
$this->notFound();
}
$travelCode = $travelInfo->getTravelCode();
$this->handleRequest($travelCode, $travelInfo);
return $this->htmlResponse();
}
private function notFound(): never
{
$response = GeneralUtility::makeInstance(ErrorController::class)->pageNotFoundAction(
$this->request,
'Reiseinformationen nicht gefunden'
);
throw new ImmediateResponseException($response, 1731071856);
}
private function handleRequest(string $travelCode, Travelinfo $travelInfo)
{
@@ -0,0 +1,43 @@
<?php
namespace EP\EpProducts\Domain\Repository;
use TYPO3\CMS\Core\Database\Connection;
class SnowreportRepository extends AbstractRepository
{
/**
* Snow reports of the given regions (all regions with a snow report if empty), one per vendor
* record, with region and country data for the list.
*/
public function getSnowreportsForRegions(array $regionUids = []): array
{
$qb = $this->getDbConnection()->createQueryBuilder();
$qb
->select(
'snowreport.*',
'region.name as regionName', 'region.uid as regionUid', 'region.detail_page as regionDetailPage',
'country.name as countryName', 'country.uid as countryUid', 'country.code as countryCode',
'country.detail_page as countryDetailPage',
'season_start as seasonStart', 'season_end as seasonEnd'
)
->addSelectLiteral('(UNIX_TIMESTAMP() >= snowreport.season_start AND UNIX_TIMESTAMP() <= snowreport.season_end) as inSeason')
->from('tx_epproducts_domain_model_snowreport', 'snowreport')
->innerJoin('snowreport', 'tx_epproducts_domain_model_region', 'region', 'snowreport.uid = region.snowreport')
->innerJoin('region', 'tx_epproducts_domain_model_country', 'country', 'region.country = country.uid')
->where('region.snowreport > 0')
->groupBy('snowreport.vendor_uid')
->orderBy('region.name')
;
if ($regionUids) {
$qb->andWhere($qb->expr()->in(
'region.uid',
$qb->createNamedParameter($regionUids, Connection::PARAM_INT_ARRAY)
));
}
return $qb->executeQuery()->fetchAllAssociative();
}
}
@@ -44,7 +44,7 @@ class Hotel
$hotel['@id'] = $entity->getUid();
$hotel['@code'] = $entity->getCode();
$hotel['name'] = $entity->getName();
$hotel['category'] = \EP\EpProducts\Domain\Model\Hotel::$categoryLabels[$entity->getCategory()];
$hotel['category'] = \EP\EpProducts\Domain\Model\Hotel::$categoryLabels[$entity->getCategory()] ?? null;
$hotel['type'] = \EP\EpProducts\Domain\Model\Hotel::$typeLabels[$entity->getType()];
$hotel['description'] = SerializationUtility::sanitizeText($entity->getDescription());
$hotel['roomtypes'] = SerializationUtility::sanitizeText($entity->getRoomTypes());
@@ -0,0 +1,244 @@
<?php
namespace EP\EpProducts\EpTeam;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
use Symfony\Component\HttpClient\HttpClient;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\HttpClient\ResponseInterface;
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* The MyE&P Team application (Symfony). Separate from EP\EpProducts\MyEP\ApiClient on purpose:
* this is a different application on its own host, authenticated with a shared key in a header
* instead of the OAuth client-credentials flow MyE&P uses, so it shares neither the base URI nor
* the token handling.
*/
class ApiClient implements LoggerAwareInterface
{
use LoggerAwareTrait;
/**
* Applied when extension configuration does not override them. Seconds.
*/
private const DEFAULT_TIMEOUT = 5;
private const DEFAULT_MAX_DURATION = 15;
/**
* Status codes the endpoint answers a stored submission with. A conflict is included for the
* dedupe the team application may add later - it is not returned today - because a
* double-clicked submit button is not something to report.
*/
private const ACCEPTED_STATUS_CODES = [
Response::HTTP_OK,
Response::HTTP_CREATED,
Response::HTTP_ACCEPTED,
Response::HTTP_NO_CONTENT,
Response::HTTP_CONFLICT,
];
/**
* How much of a rejected response is carried into the exception message. A 400 names the
* offending field in its body, which is the only way to tell from a log why a submission
* was refused.
*/
private const ERROR_BODY_EXCERPT_LENGTH = 500;
/**
* Shared, like the MyE&P client: Symfony's CurlHttpClient keeps its connection pool and TLS
* session cache per instance. The API key is a constant, so unlike a bearer token it can be
* a client default header and the instance can live as long as the request.
*/
private static ?HttpClientInterface $httpClient = null;
private ?array $configuration = null;
/**
* Posts a submitted TYPO3 form to POST /api/application-forms.
*
* @throws ApiException
*/
public function submitApplicationForm(array $payload): void
{
$uri = 'api/application-forms';
// 'json' also sets the Content-Type the endpoint requires - without it the body is not
// read as JSON and the answer is a 400.
$response = $this->request('POST', $uri, [
'json' => $payload,
]);
$statusCode = $this->readStatusCode($response, 'POST', $uri);
if (false === in_array($statusCode, self::ACCEPTED_STATUS_CODES, true)) {
$message = sprintf(
'EP Team API returned unexpected status %d for POST %s: %s',
$statusCode,
$uri,
$this->readErrorBody($response)
);
$this->logWarning($message);
throw new ApiException($message, $statusCode);
}
$this->logAcceptedSubmission($response, $payload);
}
/**
* @throws ApiException
*/
private function request(string $method, string $uri, array $options): ResponseInterface
{
try {
return $this->getHttpClient()->request($method, $uri, $options);
} catch (TransportExceptionInterface $e) {
$message = sprintf('EP Team API transport error for %s %s: %s', $method, $uri, $e->getMessage());
$this->logError($message, ['exception' => $e]);
throw new ApiException($message, 0, $e);
}
}
/**
* Reading the status completes the transfer, so this is also what turns the lazy response
* returned by the client into a finished request.
*
* @throws ApiException
*/
private function readStatusCode(ResponseInterface $response, string $method, string $uri): int
{
try {
return $response->getStatusCode();
} catch (TransportExceptionInterface $e) {
$message = sprintf('EP Team API transport error while reading status for %s %s: %s', $method, $uri, $e->getMessage());
$this->logError($message, ['exception' => $e]);
throw new ApiException($message, 0, $e);
}
}
private function readErrorBody(ResponseInterface $response): string
{
try {
$body = trim($response->getContent(false));
} catch (TransportExceptionInterface $e) {
return '<no response body>';
}
if ('' === $body) {
return '<empty response body>';
}
if (mb_strlen($body) > self::ERROR_BODY_EXCERPT_LENGTH) {
$body = mb_substr($body, 0, self::ERROR_BODY_EXCERPT_LENGTH) . '…';
}
return $body;
}
/**
* The submission uuid the endpoint returns is what makes a support question ("did our
* application arrive?") answerable from the TYPO3 log alone. Reading the body also drains
* the response, which returns the connection to the pool instead of cancelling the transfer.
* Deliberately without any of the submitted values: these payloads are personal data.
*/
private function logAcceptedSubmission(ResponseInterface $response, array $payload): void
{
try {
$data = $response->toArray(false);
} catch (\Throwable $e) {
// A body that is absent (204) or not JSON costs nothing here - the submission is
// stored either way, which the asserted status has already established.
return;
}
if (null !== $this->logger) {
$this->logger->info('Application form submission accepted by the EP Team API.', [
'form' => $payload['form'] ?? null,
'pageUid' => $payload['pageUid'] ?? null,
'uuid' => $data['uuid'] ?? null,
]);
}
}
/**
* @throws ApiException
*/
private function getHttpClient(): HttpClientInterface
{
if (null !== static::$httpClient) {
return static::$httpClient;
}
$config = $this->getConfiguration();
$baseUrl = trim((string)($config['epTeamApiBaseUrl'] ?? ''));
$apiKey = trim((string)($config['epTeamApiKey'] ?? ''));
if ('' === $baseUrl) {
throw new ApiException('EP Team API base URL is not configured.');
}
if ('' === $apiKey) {
throw new ApiException('EP Team API key is not configured.');
}
if (0 !== strpos($baseUrl, 'https://')) {
// The application answers an http request with a 301 to the https URL, and this
// client does not follow redirects, so a plain http base URL fails every submission.
$this->logWarning(sprintf('EP Team API base URL is not https (%s); submissions will fail on the redirect.', $baseUrl));
}
$options = [
'headers' => [
'X-Api-Key' => $apiKey,
],
];
// Without these the client falls back to PHP's default_socket_timeout (commonly 60s),
// so a stalled API pins a PHP worker for a minute per request - and this call happens
// inside the visitor's form submission, with the visitor waiting for it. The defaults
// live in code rather than in ext_conf_template.txt: ExtensionConfiguration::get()
// returns the stored configuration verbatim and only syncs the template when an
// extension has no configuration at all, so a newly added template key is absent until
// someone saves extension configuration by hand. Falling back to 0 there would silently
// mean "no timeout" - the opposite of what this guard is for. An explicit 0 still
// disables.
$timeout = (int)($config['epTeamApiTimeout'] ?? self::DEFAULT_TIMEOUT);
if ($timeout > 0) {
$options['timeout'] = $timeout;
}
$maxDuration = (int)($config['epTeamApiMaxDuration'] ?? self::DEFAULT_MAX_DURATION);
if ($maxDuration > 0) {
$options['max_duration'] = $maxDuration;
}
return static::$httpClient = HttpClient::createForBaseUri(rtrim($baseUrl, '/') . '/', $options);
}
private function getConfiguration(): array
{
if (null === $this->configuration) {
$this->configuration = GeneralUtility::makeInstance(ExtensionConfiguration::class)
->get('ep_products');
}
return $this->configuration;
}
private function logError(string $message, array $context = []): void
{
if (null !== $this->logger) {
$this->logger->error($message, $context);
}
}
private function logWarning(string $message, array $context = []): void
{
if (null !== $this->logger) {
$this->logger->warning($message, $context);
}
}
}
@@ -0,0 +1,7 @@
<?php
namespace EP\EpProducts\EpTeam;
class ApiException extends \RuntimeException
{
}
@@ -78,8 +78,12 @@ class LabelService
public function getOfficetipLabel(&$parameters, $parentObject)
{
$officetip = BackendUtility::getRecord('tx_epproducts_domain_model_officetip', $parameters['row']['uid']);
$author = BackendUtility::getRecord('tx_epproducts_domain_model_teammember', $officetip['author']);
$parameters['title'] = sprintf('%s (%s)', substr($officetip['label'], 0, 30), $author['name']);
// Many tips still point to team members who have left (deleted records)
$author = BackendUtility::getRecord('tx_epproducts_domain_model_teammember', (int)($officetip['author'] ?? 0));
$parameters['title'] = substr($officetip['label'] ?? '', 0, 30);
if (!empty($author['name'])) {
$parameters['title'] .= ' (' . $author['name'] . ')';
}
}
/**
@@ -156,7 +156,7 @@ class ProductDataService implements SingletonInterface
}
if (!array_key_exists($row['hotelCategory'], $teaser['hotelCategories'])) {
$teaser['hotelCategories'][$row['hotelCategory']] = Hotel::$categoryLabels[$row['hotelCategory']];
$teaser['hotelCategories'][$row['hotelCategory']] = Hotel::$categoryLabels[$row['hotelCategory']] ?? null;
ksort($teaser['hotelCategories']);
}
}
@@ -3,30 +3,11 @@
namespace EP\EpProducts\Traits;
use EP\EpProducts\Service\FilterService;
use EP\EpProducts\Service\SearchResultService;
use TYPO3\CMS\Core\Utility\GeneralUtility;
trait RequestArgumentTypeConversionTrait
{
public function processSearchParamsArgument(): void
{
/** @var SearchResultService $searchResultService */
$searchResultService = GeneralUtility::makeInstance(SearchResultService::class);
if (!$this->request->hasArgument('searchParams')) {
$searchParams = $searchResultService->getNormalizedSearchParams();
} else {
$requestArgument = $this->request->getArgument('searchParams');
$searchParamsFromRequest = is_array($requestArgument) ?
$requestArgument : json_decode($requestArgument, true, 512, JSON_THROW_ON_ERROR);
$searchParams = $searchResultService->getNormalizedSearchParams($searchParamsFromRequest);
}
$this->request = $this->request->withArgument('searchParams', $searchParams);
}
public function processFilterSettingsArgument(array $forcedConceptUids = []): void
{
@@ -0,0 +1,28 @@
<?xml version="1.0"?>
<T3DataStructure>
<meta>
<langDisable>1</langDisable>
</meta>
<sheets>
<sDEF>
<ROOT>
<sheetTitle>Konfiguration</sheetTitle>
<type>array</type>
<el>
<settings.regionUids>
<label>Gebiete einschränken</label>
<config>
<type>select</type>
<renderType>selectMultipleSideBySide</renderType>
<foreign_table>tx_epproducts_domain_model_region</foreign_table>
<foreign_table_where>AND tx_epproducts_domain_model_region.snowreport > 0 ORDER BY name</foreign_table_where>
<minitems>0</minitems>
<maxitems>99</maxitems>
<size>10</size>
</config>
</settings.regionUids>
</el>
</ROOT>
</sDEF>
</sheets>
</T3DataStructure>
@@ -43,6 +43,12 @@ call_user_func(function () {
'Buchungstabelle'
);
ExtensionUtility::registerPlugin(
'EpProducts',
'snowreport_list',
'Schneehöhen'
);
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist']['epproducts_product_detail'] = 'pi_flexform';
ExtensionManagementUtility::addPiFlexFormValue(
'epproducts_product_detail',
@@ -61,4 +67,10 @@ call_user_func(function () {
'FILE:EXT:ep_products/Configuration/FlexForms/flexform_product_pricetable.xml'
);
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist']['epproducts_snowreport_list'] = 'pi_flexform';
ExtensionManagementUtility::addPiFlexFormValue(
'epproducts_snowreport_list',
'FILE:EXT:ep_products/Configuration/FlexForms/flexform_snowreport.xml'
);
});
@@ -35,7 +35,7 @@ return [
'palettes' => [
'top' => ['showitem' => 'hidden,detail_page,exclude_from_teasergroups'],
'name' => ['showitem' => 'name,headline,--linebreak--,header_title,header_subtitle'],
'destinations' => ['showitem' => 'country,region,city,latitude,longitude,season'],
'destinations' => ['showitem' => 'country,region,city,--linebreak--,latitude,longitude,season'],
],
'columns' => [
@@ -39,7 +39,7 @@ return [
],
],
'palettes' => [
'top' => ['showitem' => 'hidden,earlybird,new,low_contingent,show_as_teaser,
'top' => ['showitem' => 'hidden,earlybird,new,--linebreak--,low_contingent,show_as_teaser,
--linebreak--,code,detail_page,--linebreak--,external_link,path_segment'],
'geolocation' => ['showitem' => 'address, longitude, latitude'],
'destinations' => ['showitem' => 'country,region,city'],
@@ -47,7 +47,8 @@ return [
'categories' => ['showitem' => 'type,category'],
'season' => ['showitem' => 'main_season_from, main_season_to'],
'others' => ['showitem' => 'season,groups_price_tax_label, groups_price_adolescents_age'],
'icons' => ['showitem' => 'beds_count,parking_count,altitude,shower,partyroom,gamesroom,sauna,wifi,distance_bus,distance_lift'],
'icons' => ['showitem' => 'beds_count,parking_count,altitude,shower,
--linebreak--,partyroom,gamesroom,sauna,wifi,--linebreak--,distance_bus,distance_lift'],
],
'columns' => [
@@ -43,13 +43,15 @@ return [
],
'palettes' => [
'destinations' => ['showitem' => 'country,region,city'],
'top' => ['showitem' => 'searchable, bookable, hide_booking_button, daytrip, important, skipass_included,
season, detail_page, external_link, tour_link, path_segment, min_price'],
'top' => ['showitem' => 'searchable, bookable, hide_booking_button, daytrip,
--linebreak--, important, skipass_included, season,
--linebreak--, detail_page, external_link, tour_link,
--linebreak--, path_segment, min_price'],
'name' => ['showitem' => 'name,code'],
'alternative' => ['showitem' => 'alt_product, alt_label'],
'header' => ['showitem' => 'headline, subline, --linebreak--, header_title, header_subtitle'],
'rating' => ['showitem' => 'rating_average, rating_votes_count'],
'records' => ['showitem' => 'journey, concept, calendar_hotel, officetip, badge'],
'records' => ['showitem' => 'journey, concept, calendar_hotel, --linebreak--, officetip, badge'],
'misc' => ['showitem' => 'feature,keywords'],
],
'columns' => [
@@ -60,3 +60,15 @@ contentFeedNewsDetailPages = ep-reisen:1392
# cat=Import; type=int+; label=Storage page of the imported dates and rooms
importStoragePid = 11
# cat=EpTeamAPI; type=string; label=MyE&P Team base URL (https, e.g. https://team.ep-reisen.de) - receives application form submissions
epTeamApiBaseUrl =
# cat=EpTeamAPI; type=string; label=MyE&P Team application form API key (sent as X-Api-Key)
epTeamApiKey =
# cat=EpTeamAPI; type=int; label=MyE&P Team API inactivity timeout in seconds (0 = PHP default_socket_timeout)
epTeamApiTimeout = 5
# cat=EpTeamAPI; type=int; label=MyE&P Team API max total request duration in seconds (0 = unlimited)
epTeamApiMaxDuration = 15
+27 -2
View File
@@ -2,6 +2,8 @@
use TYPO3\CMS\Extbase\Utility\ExtensionUtility;
use EP\EpProducts\Controller\ProductController;
use EP\EpProducts\Controller\SearchController;
use EP\EpProducts\Controller\SearchbarController;
use EP\EpProducts\Controller\SnowreportController;
use EP\EpProducts\Controller\TravelinfoController;
use EP\EpProducts\Controller\WatchlistController;
use EP\EpProducts\Controller\AjaxFilterPanelController;
@@ -58,10 +60,19 @@ $boot = function () {
'EpProducts',
'searchresult',
[
SearchController::class => 'searchresult,processSearch',
SearchController::class => 'searchresult',
],
[
SearchController::class => 'searchresult,processSearch',
SearchController::class => 'searchresult',
]
);
// The search bar in the page header (lib.searchBar), not a content element
ExtensionUtility::configurePlugin(
'EpProducts',
'searchbar',
[
SearchbarController::class => 'index',
]
);
@@ -81,6 +92,14 @@ $boot = function () {
]
);
ExtensionUtility::configurePlugin(
'EpProducts',
'snowreport_list',
[
SnowreportController::class => 'list',
]
);
ExtensionUtility::configurePlugin(
'EpProducts',
'ajax',
@@ -114,6 +133,12 @@ $boot = function () {
// The client-side callers that vary month/year (calendar_controller.js) send them in a
// POST body, which the cHash never inspects, so nothing depends on the exclusion.
$GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParameters'][] = 'f';
// The search bar sends its fields by GET to the search page, whose results are not cached
// (SearchController::SEARCHBAR_PARAMETERS)
array_push(
$GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParameters'],
...SearchController::SEARCHBAR_PARAMETERS
);
$GLOBALS['TYPO3_CONF_VARS']['SYS']['routing']['aspects']['PassthroughMapper'] =
PassthroughMapper::class;
@@ -0,0 +1,156 @@
<?php
namespace EP\EpTheme\Form;
use TYPO3\CMS\Core\Log\LogManager;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Domain\Model\FileReference;
use TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher;
abstract class AbstractMappedFinisher extends AbstractFinisher
{
/**
* Resolves the 'mapping' option into remote name => local form element identifier.
*/
protected function parseMapping(): array
{
$mappings = [];
$mappingOption = (string)$this->parseOption('mapping');
foreach (GeneralUtility::trimExplode(',', $mappingOption, true) as $mapping) {
$parts = GeneralUtility::trimExplode(':', $mapping, true, 2);
if (2 !== count($parts)) {
continue;
}
[$remote, $local] = $parts;
if ('' === $remote || '' === $local) {
continue;
}
$mappings[$remote] = $local;
}
return $mappings;
}
/**
* The mapped values, keyed by the remote name the receiving side expects. Values pass through
* normalizeValue() just like the labeled ones do, so a date element arrives as a Y-m-d string
* instead of a serialized DateTime. A value that does not survive normalization keeps its key:
* the remote names make up the request shape and dropping one would change it.
*/
protected function buildPayload(): array
{
$values = [];
$formValues = $this->finisherContext->getFormValues();
foreach ($this->parseMapping() as $remote => $local) {
if (false === array_key_exists($local, $formValues)) {
continue;
}
$values[$remote] = $this->normalizeValue($formValues[$local], $local);
}
return $values;
}
/**
* Every submitted value that the mapping does not already cover, keyed by the element label
* as the editor sees it in the form editor. Forms built in the backend use generated
* identifiers (text-1, singleselect-2, ...) that carry no meaning and cannot be renamed
* without breaking existing finisher options, so the label is the only stable description
* of what was asked.
*
* The label is taken from the form definition, not through TranslationService: a translated
* label would change the payload keys with the site language, and these keys are stored.
*/
protected function buildLabeledValues(): array
{
$formValues = $this->finisherContext->getFormValues();
$skip = array_merge(
array_values($this->parseMapping()),
GeneralUtility::trimExplode(',', (string)$this->parseOption('exclude'), true)
);
// Keyed by identifier in form order, and contains only real form elements - iterating
// this instead of the form values keeps the collection in the order of the form and
// leaves out anything that is not an element the visitor filled in.
$elements = $this->finisherContext->getFormRuntime()->getFormDefinition()->getElements();
$collected = [];
foreach ($elements as $identifier => $element) {
if (true === in_array($identifier, $skip, true) || false === array_key_exists($identifier, $formValues)) {
continue;
}
$value = $this->normalizeValue($formValues[$identifier], $identifier);
if (null === $value || '' === $value || [] === $value) {
continue;
}
$label = trim($element->getLabel());
if ('' === $label) {
$label = $identifier;
}
if (true === array_key_exists($label, $collected)) {
$label .= ' (' . $identifier . ')';
}
$collected[$label] = $value;
}
return $collected;
}
/**
* @param mixed $value
*
* @return mixed null when the value has no JSON representation
*/
protected function normalizeValue($value, string $identifier)
{
if (true === is_array($value)) {
$normalized = [];
foreach ($value as $item) {
$item = $this->normalizeValue($item, $identifier);
if (null !== $item && '' !== $item) {
$normalized[] = $item;
}
}
return $normalized;
}
if ($value instanceof \DateTimeInterface) {
return $value->format('Y-m-d');
}
if ($value instanceof FileReference) {
$resource = $value->getOriginalResource();
return null !== $resource ? $resource->getName() : null;
}
if (true === is_object($value)) {
$this->logWarning('Form value skipped while collecting labeled values: unsupported type.', [
'element' => $identifier,
'class' => get_class($value),
]);
return null;
}
return $value;
}
protected function logWarning(string $message, array $context = []): void
{
GeneralUtility::makeInstance(LogManager::class)
->getLogger(static::class)
->warning($message, array_merge([
'finisher' => static::class,
], $context));
}
}
@@ -0,0 +1,76 @@
<?php
namespace EP\EpTheme\Form;
use EP\EpTheme\Middleware\ReferrerMiddleware;
use TYPO3\CMS\Core\Routing\PageArguments;
use TYPO3\CMS\Core\Site\Entity\Site;
use TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher;
use TYPO3\CMS\Frontend\Authentication\FrontendUserAuthentication;
/**
* Adds the URL of the form's page and, if known, the page the visitor came from (see
* ReferrerMiddleware) to the submission, so the e-mail finishers include them.
*/
class AddReferrerFinisher extends AbstractFinisher
{
protected function executeInternal()
{
$this->addCurrentUrlField();
$this->addReferrerField();
}
private function addReferrerField(): void
{
$frontendUser = $this->finisherContext->getRequest()->getAttribute('frontend.user');
if (!$frontendUser instanceof FrontendUserAuthentication) {
return;
}
$referrer = $frontendUser->getKey('ses', ReferrerMiddleware::SESSION_KEY);
if (null === $referrer) {
return;
}
$this->addField('referrer', 'Referrer', $referrer);
$frontendUser->setKey('ses', ReferrerMiddleware::SESSION_KEY, null);
$frontendUser->storeSessionData();
}
private function addCurrentUrlField(): void
{
$request = $this->finisherContext->getRequest();
$routing = $request->getAttribute('routing');
$site = $request->getAttribute('site');
if (!$routing instanceof PageArguments || !$site instanceof Site) {
return;
}
// The page itself, not the form page type the submission was posted to
$url = (string)$site->getRouter()->generateUri($routing->getPageId(), [
'_language' => $request->getAttribute('language'),
]);
$this->addField('pageurl', 'URL', $url);
}
private function addField(string $identifier, string $label, string $value): void
{
$field = $this->finisherContext
->getFormRuntime()
->getFormDefinition()
->getPageByIndex(0)
->createElement($identifier, 'Text');
$field->setDefaultValue($value);
$field->setDataType('string');
$field->setLabel($label);
// Finisher variable for potential later use
$this->finisherContext->getFinisherVariableProvider()->add(
$this->shortFinisherIdentifier,
$identifier,
$value
);
}
}
@@ -0,0 +1,74 @@
<?php
namespace EP\EpTheme\Form;
use EP\EpProducts\EpTeam\ApiClient;
use TYPO3\CMS\Core\Routing\PageArguments;
use TYPO3\CMS\Core\Site\Entity\Site;
/**
* Sends job applications to MyE&P Team (POST /api/application-forms).
*/
class ApplicationApiFinisher extends AbstractMappedFinisher
{
public function __construct(private readonly ApiClient $apiClient) {}
protected function executeInternal()
{
try {
$payload = $this->buildPayload();
if ([] === $payload) {
$this->logWarning('Application form API finisher skipped: the mapping produced no values.');
return;
}
$formDefinition = $this->finisherContext->getFormRuntime()->getFormDefinition();
$formLabel = trim($formDefinition->getLabel());
$payload['form'] = $formDefinition->getIdentifier();
// The name the editor gave the form, so the receiving side can label a submission
// without keeping a list of identifiers. Taken from the definition rather than
// through TranslationService: a translated label would differ per site language.
$payload['formLabel'] = '' !== $formLabel ? $formLabel : $formDefinition->getIdentifier();
$payload['submittedAt'] = (new \DateTimeImmutable())->format(\DateTimeInterface::ATOM);
$payload = array_merge($payload, $this->resolvePageContext());
$payload['details'] = $this->buildLabeledValues();
$this->apiClient->submitApplicationForm($payload);
} catch (\Throwable $e) {
$this->logWarning('Application form API finisher request failed.', [
'exception' => $e,
]);
}
}
private function resolvePageContext(): array
{
$request = $this->finisherContext->getRequest();
$routing = $request->getAttribute('routing');
if (!$routing instanceof PageArguments) {
return [];
}
$pageUid = $routing->getPageId();
$context = ['pageUid' => $pageUid];
try {
/** @var Site $site */
$site = $request->getAttribute('site');
// The page itself, not the form page type the submission was posted to
$context['pageUrl'] = (string)$site->getRouter()->generateUri($pageUid, [
'_language' => $request->getAttribute('language'),
]);
} catch (\Throwable $e) {
// An unroutable page must not cost the submission, so the uid is sent without a URL.
$this->logWarning('Application form API finisher could not resolve the page URL.', [
'pageUid' => $pageUid,
'exception' => $e,
]);
}
return $context;
}
}
@@ -0,0 +1,28 @@
<?php
namespace EP\EpTheme\Form;
use EP\EpProducts\MyEP\ApiClient;
/**
* Registers the sender's address in BusPro through MyE&P (POST contactform). A failing API never
* costs the visitor the submission: the e-mail finisher still runs.
*/
class BpnApiFinisher extends AbstractMappedFinisher
{
public function __construct(private readonly ApiClient $apiClient) {}
protected function executeInternal()
{
try {
$values = $this->buildPayload();
if ([] !== $values) {
$this->apiClient->registerAddress($values);
}
} catch (\Throwable $e) {
$this->logWarning('Bpn API finisher request failed.', [
'exception' => $e,
]);
}
}
}
@@ -0,0 +1,35 @@
<?php
namespace EP\EpTheme\Middleware;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
/**
* htmx follows a redirect inside its XHR and would swap the target page into the form. A redirect
* answering an htmx request (e.g. the Redirect finisher of a form) becomes HX-Redirect instead,
* which sends the browser itself to the new location.
*/
class HtmxRedirectMiddleware implements MiddlewareInterface
{
public function __construct(private readonly ResponseFactoryInterface $responseFactory) {}
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$response = $handler->handle($request);
if ($request->getHeaderLine('HX-Request') !== 'true'
|| $response->getStatusCode() < 300
|| $response->getStatusCode() >= 400
|| !$response->hasHeader('Location')
) {
return $response;
}
return $this->responseFactory->createResponse(200)
->withHeader('HX-Redirect', $response->getHeaderLine('Location'));
}
}
@@ -0,0 +1,43 @@
<?php
namespace EP\EpTheme\Middleware;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use TYPO3\CMS\Core\Exception\SiteNotFoundException;
use TYPO3\CMS\Core\Site\SiteFinder;
use TYPO3\CMS\Frontend\Authentication\FrontendUserAuthentication;
/**
* Links to a form page carry the uid of the page they come from (?ref=123, e.g. the enquiry
* button of a product page). Its URL is kept in the session until AddReferrerFinisher puts it
* into the submission. On static pages the parameter reaches TYPO3 with the request that loads
* the form (see the form placeholder of the static export).
*/
class ReferrerMiddleware implements MiddlewareInterface
{
public const SESSION_KEY = 'referrer';
public function __construct(private readonly SiteFinder $siteFinder) {}
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$ref = $request->getQueryParams()['ref'] ?? null;
$frontendUser = $request->getAttribute('frontend.user');
if (!is_numeric($ref) || !$frontendUser instanceof FrontendUserAuthentication) {
return $handler->handle($request);
}
try {
$url = (string)$this->siteFinder->getSiteByPageId((int)$ref)->getRouter()->generateUri((int)$ref);
$frontendUser->setKey('ses', self::SESSION_KEY, $url);
$frontendUser->storeSessionData();
} catch (SiteNotFoundException) {
}
return $handler->handle($request);
}
}
@@ -8,5 +8,25 @@ return [
'typo3/cms-frontend/page-resolver',
],
],
'ep/referrer' => [
'target' => \EP\EpTheme\Middleware\ReferrerMiddleware::class,
'after' => [
'typo3/cms-frontend/authentication',
],
'before' => [
'typo3/cms-frontend/page-resolver',
],
],
// Outermost of the frontend stack after the site is known, so it also sees redirects
// that core middlewares or exceptions (PropagateResponseException) produce
'ep/htmx-redirect' => [
'target' => \EP\EpTheme\Middleware\HtmxRedirectMiddleware::class,
'after' => [
'typo3/cms-frontend/site',
],
'before' => [
'typo3/cms-frontend/authentication',
],
],
],
];
@@ -7,3 +7,9 @@ services:
EP\EpTheme\:
resource: '../Classes/*'
exclude: '../Classes/Domain/Model/*'
# Form finishers are created with GeneralUtility::makeInstance(), once per form submission
EP\EpTheme\Form\:
resource: '../Classes/Form/*'
public: true
shared: false
@@ -0,0 +1,22 @@
@import 'EXT:form/Configuration/TypoScript/setup.typoscript'
@import 'EXT:form_element_linked_checkbox/Configuration/TypoScript/setup.typoscript'
@import 'EXT:bw_captcha/Configuration/TypoScript/setup.typoscript'
plugin.tx_form.view {
templateRootPaths.10 = EXT:ep_theme/Resources/Private/Templates/Form/
# Spinner.html for Render.html
partialRootPaths.10 = EXT:ep_theme/Resources/Private/Partials/Form/
}
plugin.tx_form.settings.yamlConfigurations {
1630994710 = EXT:ep_theme/Configuration/Yaml/FormSetup.yaml
}
plugin.tx_bwcaptcha.settings {
charset = abcdefghjkmnpqrtuvwxy34679
length = 4
width = 220
height = 60
# The partial has its own reload button and no audio
audioButton = 0
}
@@ -0,0 +1,14 @@
# The search bar in the page header, open (sticky once scrolled past) or collapsed behind the
# search icon of the main navigation (product and hotel pages)
lib.searchBar = USER
lib.searchBar {
userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
extensionName = EpProducts
pluginName = searchbar
settings =< plugin.tx_epproducts.settings
persistence =< plugin.tx_epproducts.persistence
view =< plugin.tx_epproducts.view
}
lib.searchBarCollapsed < lib.searchBar
lib.searchBarCollapsed.settings.collapsed = 1
@@ -0,0 +1,29 @@
# The forms of a page without the page around them (/path/form). The static pages of the hybrid
# setup load this into a placeholder with htmx, and the forms post back to it (see
# FormSetup.yaml): the page URL itself is a static file that never reaches TYPO3.
# Every form page has a single form, wherever it sits (a grid or container counts as well).
tx_eptheme_form = PAGE
tx_eptheme_form {
typeNum = 1704
config {
disableAllHeaderCode = 1
disablePrefixComment = 1
additionalHeaders.10.header = Content-Type: text/html; charset=utf-8
additionalHeaders.20.header = X-Robots-Tag: noindex, nofollow
admPanel = 0
debug = 0
}
10 = CONTENT
10 {
table = tt_content
select {
where = {#CType} = 'form_formframework'
orderBy = sorting
}
# Only the plugin (Templates/Form/Render.html, a .form-island): header and frame stay on
# the static page
renderObj =< tt_content.form_formframework.20
}
}
@@ -0,0 +1,25 @@
# The search bar without the page around it, on the site root (/searchbar, /searchbar-collapsed).
# The static pages of the hybrid setup load it with htmx where the export had the bar: it is the
# same on every page of a site, and its options follow the imported products (ep:import-dates
# flushes the page cache). The form sends its fields by GET to the search page.
tx_eptheme_searchbar = PAGE
tx_eptheme_searchbar {
typeNum = 1706
config {
disableAllHeaderCode = 1
disablePrefixComment = 1
additionalHeaders.10.header = Content-Type: text/html; charset=utf-8
additionalHeaders.20.header = X-Robots-Tag: noindex, nofollow
admPanel = 0
debug = 0
}
10 =< lib.searchBar
}
tx_eptheme_searchbar_collapsed < tx_eptheme_searchbar
tx_eptheme_searchbar_collapsed {
typeNum = 1707
10 =< lib.searchBarCollapsed
}
@@ -0,0 +1,29 @@
# The snow reports of a page without the page around them (/path/snowreport). The static pages of
# the hybrid setup load this with htmx and replace the snow reports of the export with it: the
# page URL itself is a static file that never reaches TYPO3, and the snow reports are imported
# daily (ep:import-snowreport, which flushes the page cache). Each list carries
# id="snowreport-<content uid>" (Templates/Snowreport/List.html) for hx-select.
tx_eptheme_snowreport = PAGE
tx_eptheme_snowreport {
typeNum = 1705
config {
disableAllHeaderCode = 1
disablePrefixComment = 1
additionalHeaders.10.header = Content-Type: text/html; charset=utf-8
additionalHeaders.20.header = X-Robots-Tag: noindex, nofollow
admPanel = 0
debug = 0
}
10 = CONTENT
10 {
table = tt_content
select {
where = {#CType} = 'list' AND {#list_type} = 'epproducts_snowreport_list'
orderBy = sorting
}
# Only the plugin: header and frame stay on the static page
renderObj =< tt_content.list.20.epproducts_snowreport_list
}
}
@@ -0,0 +1,56 @@
TYPO3:
CMS:
Form:
persistenceManager:
allowedExtensionPaths:
10: EXT:ep_theme/Resources/Private/Forms/
prototypes:
standard:
formElementsDefinition:
Form:
renderingOptions:
templateRootPaths:
1505042810: 'EXT:ep_theme/Resources/Private/Templates/Form/'
partialRootPaths:
1623227657: 'EXT:ep_theme/Resources/Private/Partials/Form/'
layoutRootPaths:
1505042810: 'EXT:ep_theme/Resources/Private/Layouts/Form/'
# Every form has a captcha
honeypot:
enable: false
# Forms post to the form page type (tx_eptheme_form, /form): on the static
# pages of the hybrid setup the page URL itself never reaches TYPO3
additionalParams:
type: 1704
finishersDefinition:
BpnApiFinisher:
implementationClassName: 'EP\EpTheme\Form\BpnApiFinisher'
formEditor:
label: 'BusPro Finisher'
options:
identifier: 'BpnApiFinisher'
mapping: 'lastName:text-1,firstName:text-2,gender:singleselect-1,email:email-1,phone:telephone-1'
ApplicationApiFinisher:
implementationClassName: 'EP\EpTheme\Form\ApplicationApiFinisher'
formEditor:
label: 'Application Finisher'
options:
identifier: 'ApplicationApiFinisher'
mapping: 'firstName:text-1,lastName:text-2,email:email-1,phone:telephone-1'
exclude: 'captcha,privacypolicyaccepted'
AddReferrerFinisher:
implementationClassName: 'EP\EpTheme\Form\AddReferrerFinisher'
formEditor:
label: 'Referrer Finisher'
options:
identifier: 'AddReferrerFinisher'
contactform:
__inheritances:
10: 'TYPO3.CMS.Form.prototypes.standard'
applicationform:
__inheritances:
10: 'TYPO3.CMS.Form.prototypes.standard'
@@ -0,0 +1,378 @@
renderingOptions:
submitButtonLabel: Absenden
type: Form
identifier: applicationform
label: Bewerbungsformular
prototypeName: applicationform
finishers:
-
options:
subject: 'Bewerbung von {text-1}'
recipientAddress: [email protected]
recipientName: 'E&P Reisen'
senderAddress: [email protected]
senderName: '{text-1}'
replyToAddress: '{text-6}'
carbonCopyAddress: ''
blindCarbonCopyAddress: ''
format: html
attachUploads: false
translation:
language: ''
identifier: EmailToReceiver
-
options:
message: 'Vielen Dank für deine Bewerbung. Wir werden sie so schnell wie möglich bearbeiten.'
identifier: Confirmation
renderables:
-
renderingOptions:
previousButtonLabel: zurück
nextButtonLabel: weiter
type: Page
identifier: page-1
label: ''
renderables:
-
defaultValue: ''
type: Text
identifier: text-1
label: Name
properties:
fluidAdditionalAttributes:
placeholder: 'Vor- & Nachname'
required: required
elementDescription: ''
validators:
-
identifier: NotEmpty
-
defaultValue: ''
type: Text
identifier: text-2
label: Straße
properties:
fluidAdditionalAttributes:
placeholder: 'Straße & Hausnummer'
required: required
elementDescription: ''
validators:
-
identifier: NotEmpty
-
defaultValue: ''
type: Text
identifier: text-3
label: Wohnort
properties:
fluidAdditionalAttributes:
placeholder: 'PLZ & Ort'
required: required
validators:
-
identifier: NotEmpty
-
defaultValue: ''
type: Text
identifier: text-4
label: 'Mobil Nummer'
properties:
fluidAdditionalAttributes:
required: required
validators:
-
identifier: NotEmpty
-
defaultValue: ''
type: Text
identifier: text-5
label: 'Festnetz Nummer'
-
defaultValue: ''
type: Text
identifier: text-6
label: 'E-Mail Adresse'
properties:
fluidAdditionalAttributes:
required: required
validators:
-
identifier: NotEmpty
-
identifier: EmailAddress
-
defaultValue: ''
type: Text
identifier: text-7
label: Geburtsdatum
properties:
fluidAdditionalAttributes:
placeholder: tt.mm.jjjj
required: required
validators:
-
options:
regularExpression: '/\d{2}\.\d{2}\.\d{4}/'
identifier: RegularExpression
-
identifier: NotEmpty
-
defaultValue: ''
type: Text
identifier: text-8
label: Nationalität
-
properties:
options:
nein: nein
ja: ja
'ja, mit Anhänger': 'ja, mit Anhänger'
type: RadioButton
identifier: radiobutton-1
label: Führerschein
-
defaultValue: ''
type: Text
identifier: text-9
label: Ausbildung/Studium
properties:
fluidAdditionalAttributes:
placeholder: 'Schul-, Uni-, Berufsausbildung'
elementDescription: ''
-
defaultValue: ''
type: Text
identifier: text-10
label: 'Aktuelle Tätigkeit'
-
properties:
options:
Haus-/Destinationsleitung: Haus-/Destinationsleitung
Koch/Köchin: Koch/Köchin
Koch-Assistenz/Service: Koch-Assistenz/Service
'Serviceleitung/Assistenz Hausleitung': 'Serviceleitung/Assistenz Hausleitung'
Serviceteamer: Serviceteamer
Reinigungskraft: Reinigungskraft
Materialteamer/Verleih: Materialteamer/Verleih
Allrounder: Allrounder
'Praktikum im Schnee': 'Praktikum im Schnee'
elementDescription: ''
type: MultiCheckbox
identifier: multicheckbox-1
label: 'Bewerbung als'
-
defaultValue: ''
type: Text
identifier: text-11
label: 'Einsatz datum'
properties:
fluidAdditionalAttributes:
placeholder: 'von tt.mm.jjjj bis tt.mm.jjjj'
required: required
validators:
-
identifier: NotEmpty
-
properties:
options:
Ski: Ski
Snowboard: Snowboard
nichts: nichts
type: MultiCheckbox
identifier: multicheckbox-2
label: 'Ich fahre'
validators:
-
identifier: NotEmpty
-
options:
minimum: '1'
maximum: '2'
identifier: Count
-
properties:
options:
'noch nicht gelernt': 'noch nicht gelernt'
Anfänger: Anfänger
Fortgeschritten: Fortgeschritten
Experte: Experte
type: SingleSelect
identifier: singleselect-1
label: 'Wie gut fahre ich Ski'
defaultValue: 'noch nicht gelernt'
-
defaultValue: ''
type: Text
identifier: text-12
label: 'Skifahrer seit'
-
properties:
options:
'noch nicht gelernt': 'noch nicht gelernt'
Anfänger: Anfänger
Fortgeschritten: Fortgeschritten
Experte: Experte
type: SingleSelect
identifier: singleselect-2
label: 'Wie gut fahre ich Snowboard'
-
defaultValue: ''
type: Text
identifier: text-13
label: 'Snowboarder seit'
properties:
elementDescription: ''
-
properties:
options:
nein: nein
'Ski Grundstufe': 'Ski Grundstufe'
'Board Grundstufe': 'Board Grundstufe'
'Ski Instructor': 'Ski Instructor'
'Board Instructor': 'Board Instructor'
'Ski Begleitschein': 'Ski Begleitschein'
'Board Begleitschein': 'Board Begleitschein'
type: MultiSelect
identifier: multiselect-1
label: Ski-/Snowboardlehrerschein
defaultValue:
- nein
-
type: Fieldset
identifier: fieldset-1
label: Fremdsprachen
renderables:
-
properties:
options:
nein: nein
Grundkenntnisse: Grundkenntnisse
gut: gut
'sehr gut': 'sehr gut'
type: SingleSelect
identifier: singleselect-3
label: Englisch
defaultValue: nein
-
properties:
options:
nein: nein
Grundkenntnisse: Grundkenntnisse
gut: gut
'sehr gut': 'sehr gut'
type: SingleSelect
identifier: singleselect-4
label: Französisch
defaultValue: nein
-
properties:
options:
nein: nein
Grundkenntnisse: Grundkenntnisse
gut: gut
'sehr gut': 'sehr gut'
type: SingleSelect
identifier: singleselect-5
label: Spanisch
defaultValue: nein
-
defaultValue: ''
type: Text
identifier: text-14
label: 'Sonstige Fremdsprachen'
-
properties:
options:
ja: ja
nein: nein
type: RadioButton
identifier: radiobutton-2
label: 'Kocherfahrung für Gruppen (min. 30 Personen)'
-
defaultValue: ''
type: Text
identifier: text-15
label: 'Wenn ja, welche?'
properties:
elementDescription: ''
-
properties:
options:
ja: ja
nein: nein
type: RadioButton
identifier: radiobutton-3
label: 'Erfahrungen im Tourismus'
-
defaultValue: ''
type: Text
identifier: text-16
label: 'Wenn ja, welche?'
properties:
elementDescription: ''
-
properties:
options:
'ja, mit Zertifikat zur Bindungseinstellung': 'ja, mit Zertifikat zur Bindungseinstellung'
nein: nein
type: RadioButton
identifier: radiobutton-4
label: 'Erfahrungen im Skiverleih'
-
properties:
options:
Zillertal: Zillertal
Lenzerheide: Lenzerheide
'Davos Klosters': 'Davos Klosters'
Montafon: Montafon
Saalbach: Saalbach
'Les Deux Alpes': 'Les Deux Alpes'
'4 Vallées': '4 Vallées'
'Val Thorens': 'Val Thorens'
'Les Sybelles': 'Les Sybelles'
'Portes du Soleil': 'Portes du Soleil'
type: MultiCheckbox
identifier: multicheckbox-3
label: 'Ortskenntnisse in folgenden Destinationen'
-
properties:
options:
'Damen 36': 'Damen 36'
'Damen 38': 'Damen 38'
'Damen 40': 'Damen 40'
'Damen 42': 'Damen 42'
'Herren S': 'Herren S'
'Herren M': 'Herren M'
'Herren L': 'Herren L'
'Herren XL': 'Herren XL'
type: SingleSelect
identifier: singleselect-6
label: Jackengröße
-
defaultValue: ''
type: Textarea
identifier: textarea-1
label: 'Warum möchte ich für E&P Reisen arbeiten?'
-
properties:
options:
Freunde: Freunde
'Social Media': 'Social Media'
Uni: Uni
Sonstiges: Sonstiges
type: MultiCheckbox
identifier: multicheckbox-4
label: 'Wie bin ich auf E&P Reisen aufmerksam geworden?'
-
type: LinkedCheckbox
identifier: privacypolicyaccepted
label: 'Ich akzeptiere die %s.'
properties:
pageUid: '355'
linkText: 'Datenschutzbestimmungen'
fluidAdditionalAttributes:
required: required
validators:
-
identifier: NotEmpty
@@ -0,0 +1,148 @@
renderingOptions:
submitButtonLabel: Absenden
type: Form
identifier: contactform
label: Kontaktformular
prototypeName: contactform
finishers:
-
identifier: BpnApiFinisher
options:
mapping: 'lastName:lastName,firstName:firstName,gender:gender,email:email,street:street,zipCode:zipCode,city:city,phone:phone'
-
options:
subject: 'Kontaktanfrage von {firstName} {lastName}'
recipientAddress: [email protected]
recipientName: 'E&P Reisen'
senderAddress: [email protected]
senderName: '{firstName} {lastName}'
replyToAddress: '{email}'
carbonCopyAddress: ''
blindCarbonCopyAddress: ''
format: html
attachUploads: false
translation:
language: ''
identifier: EmailToReceiver
-
options:
pageUid: '1387'
additionalParameters: ''
identifier: Redirect
renderables:
-
renderingOptions:
previousButtonLabel: 'Previous step'
nextButtonLabel: 'Neue Seite'
type: Page
identifier: page-1
label: ''
renderables:
-
defaultValue: ''
type: Text
identifier: firstName
label: Vorname
properties:
fluidAdditionalAttributes:
placeholder: 'Vorname'
required: required
elementDescription: ''
validators:
-
identifier: NotEmpty
-
defaultValue: ''
type: Text
identifier: lastName
label: 'Nachname'
properties:
fluidAdditionalAttributes:
placeholder: 'Nachname'
required: required
elementDescription: ''
validators:
-
identifier: NotEmpty
-
properties:
options:
M: M
W: W
D: D
fluidAdditionalAttributes:
required: required
type: SingleSelect
identifier: gender
label: 'Gender'
validators:
-
identifier: NotEmpty
-
defaultValue: ''
type: Text
identifier: email
label: 'E-Mail'
properties:
fluidAdditionalAttributes:
required: required
validators:
-
identifier: NotEmpty
-
identifier: EmailAddress
-
defaultValue: ''
type: Text
identifier: street
label: 'Straße'
properties:
fluidAdditionalAttributes:
placeholder: 'Straße & Nr.'
elementDescription: ''
-
defaultValue: ''
type: Text
identifier: zipCode
label: 'PLZ'
-
defaultValue: ''
type: Text
identifier: city
label: 'Ort'
-
defaultValue: ''
type: Text
identifier: phone
label: 'Telefon'
-
defaultValue: ''
type: Textarea
identifier: message
label: 'Deine Kontaktanfrage'
-
defaultValue: ''
type: Text
identifier: bookingNumber
label: 'Buchungsnummer (falls vorhanden)'
-
type: LinkedCheckbox
identifier: privacypolicyaccepted
label: 'Ich akzeptiere die %s.'
properties:
pageUid: '355'
linkText: 'Datenschutzbestimmungen'
fluidAdditionalAttributes:
required: required
validators:
-
identifier: NotEmpty
-
type: Captcha
identifier: captcha
label: Captcha
properties:
fluidAdditionalAttributes:
required: required
autocomplete: 'off'
@@ -0,0 +1,388 @@
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true" >
<head>
<!--[if gte mso 15]>
<xml>
<o:OfficeDocumentSettings>
<o:AllowPNG/>
<o:PixelsPerInch>96</o:PixelsPerInch>
</o:OfficeDocumentSettings>
</xml>
<![endif]-->
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title></title>
<style type="text/css">
p {
margin:10px 0;
padding:0;
}
table {
border-collapse:collapse;
}
h1,
h2,
h3,
h4,
h5,
h6 {
display:block;
margin:0;
padding:0;
}
img,
a img {
border:0;
height:auto;
outline:none;
text-decoration:none;
}
body,
#bodyTable,
#bodyCell {
height:100%;
margin:0;
padding:0;
width:100%;
}
#outlook a {
padding:0;
}
img {
-ms-interpolation-mode:bicubic;
}
table {
mso-table-lspace:0pt;
mso-table-rspace:0pt;
}
.ReadMsgBody {
width:100%;
}
.ExternalClass {
width:100%;
}
p,
a,
td {
mso-line-height-rule:exactly;
}
a[href^=tel],
a[href^=sms] {
color:inherit;
cursor:default;
text-decoration:none;
}
p,
a,
td,
body,
table,
blockquote {
-ms-text-size-adjust:100%;
-webkit-text-size-adjust:100%;
}
.ExternalClass,
.ExternalClass p,
.ExternalClass td,
.ExternalClass div,
.ExternalClass span,
.ExternalClass font {
line-height:100%;
}
a[x-apple-data-detectors]{
color:inherit !important;
text-decoration:none !important;
font-size:inherit !important;
font-family:inherit !important;
font-weight:inherit !important;
line-height:inherit !important;
}
.templateContainer {
max-width:600px !important;
}
a.button {
display:block;
}
.image,.retinaImage {
vertical-align:bottom;
}
.textContent {
word-break:break-word;
}
.textContent img {
height:auto !important;
}
.dividerBlock {
table-layout:fixed !important;
}
h1 {
color:#222222;
font-family:'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif;
font-size:40px;
font-style:normal;
font-weight:bold;
line-height:150%;
letter-spacing:normal;
text-align:center;
}
h2 {
color:#222222;
font-family:'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif;
font-size:34px;
font-style:normal;
font-weight:bold;
line-height:150%;
letter-spacing:normal;
text-align:left;
}
h3 {
color:#444444;
font-family:'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif;
font-size:22px;
font-style:normal;
font-weight:bold;
line-height:150%;
letter-spacing:normal;
text-align:left;
}
h4 {
color:#999999;
font-family:'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif;
font-size:20px;
font-style:italic;
font-weight:normal;
line-height:125%;
letter-spacing:normal;
text-align:left;
}
#templateHeader {
background-image:none;
background-repeat:no-repeat;
background-position:center;
background-size:cover;
border-top:0;
border-bottom:0;
padding-top:36px;
padding-bottom:0;
}
.headerContainer {
background-color:#ffffff;
background-image:none;
background-repeat:no-repeat;
background-position:center;
background-size:cover;
border-top:1px none ;
border-bottom:0;
padding-top:36px;
padding-bottom:36px;
}
.headerContainer .textContent,
.headerContainer .textContent p {
color:#808080;
font-family:'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif;
font-size:16px;
line-height:150%;
text-align:left;
}
.headerContainer .textContent a,
.headerContainer .textContent p a {
color:#538bb3;
font-weight:normal;
text-decoration:underline;
}
#templateBody {
background-color:#f2f2f2;
background-image:none;
background-repeat:no-repeat;
background-position:center;
background-size:cover;
border-top:0;
border-bottom:0;
padding-top:0;
padding-bottom:0;
}
.bodyContainer {
background-color:#ffffff;
background-image:none;
background-repeat:no-repeat;
background-position:center;
background-size:cover;
border-top:0;
border-bottom:0;
padding-top:0;
padding-bottom:18px;
}
.bodyContainer .textContent,
.bodyContainer .textContent p {
color:#808080;
font-family:'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif;
font-size:16px;
line-height:150%;
text-align:left;
}
.bodyContainer .textContent a,
.bodyContainer .textContent p a {
color:#538bb3;
font-weight:normal;
text-decoration:underline;
}
#templateFooter{
background-color:#f2f2f2;
background-image:none;
background-repeat:no-repeat;
background-position:center;
background-size:cover;
border-top:1px none ;
border-bottom:0;
padding-top:0;
padding-bottom:36px;
}
.footerContainer{
background-color:#313131;
background-image:none;
background-repeat:no-repeat;
background-position:center;
background-size:cover;
border-top:0;
border-bottom:0;
padding-top:45px;
padding-bottom:45px;
}
.footerContainer .textContent,
.footerContainer .textContent p {
color:#FFFFFF;
font-family:'Helvetica Neue', Helvetica, Arial, Verdana, sans-serif;
font-size:12px;
line-height:150%;
text-align:center;
}
.footerContainer .textContent a,
.footerContainer .textContent p a {
color:#FFFFFF;
font-weight:normal;
text-decoration:underline;
}
table.data th,
table.data td {
vertical-align: top;
}
@media only screen and (min-width:768px){
.templateContainer {
width:600px !important;
}
}
@media only screen and (max-width: 480px){
body,
table,
td,
p,
a {
-webkit-text-size-adjust:none !important;
}
body {
width:100% !important;
min-width:100% !important;
}
h1 {
font-size:30px !important;
line-height:125% !important;
}
h2 {
font-size:26px !important;
line-height:125% !important;
}
h3 {
font-size:20px !important;
line-height:150% !important;
}
h4 {
font-size:18px !important;
line-height:150% !important;
}
.headerContainer .textContent,
.headerContainer .textContent p {
font-size:16px !important;
line-height:150% !important;
}
.bodyContainer .textContent,
.bodyContainer .textContent p {
font-size:16px !important;
line-height:150% !important;
}
}
</style>
</head>
<body>
<center>
<table align="center" border="0" cellpadding="0" cellspacing="0" height="100%" width="100%" id="bodyTable"><tr><td align="center" valign="top" id="bodyCell">
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<!-- HEADER START -->
<tr><td align="center" valign="top" id="templateHeader" style="background-color: #ffffff">
<!--[if (gte mso 9)|(IE)]><table align="center" border="0" cellspacing="0" cellpadding="0" width="600" style="width:600px;"><tr><td align="center" valign="top" width="600" style="width:600px;"><![endif]-->
<table align="center" border="0" cellpadding="0" cellspacing="0" width="100%" class="templateContainer"><tr><td valign="top" class="headerContainer">
<table border="0" cellpadding="0" cellspacing="0" width="100%" class="textBlock" style="min-width:100%;"><tbody class="textBlockOuter"><tr><td valign="top" class="textBlockInner" style="padding-top:9px;">
<!--[if mso]><table align="left" border="0" cellspacing="0" cellpadding="0" width="100%" style="width:100%;"><tr><td valign="top" width="600" style="width:600px;"><![endif]-->
<table align="left" border="0" cellpadding="0" cellspacing="0" style="max-width:100%; min-width:100%;" width="100%" class="textContentContainer">
<tbody>
<tr>
<td valign="top" class="image" align="center" style="padding: 0px 36px; padding-bottom: 20px; color: #222222;text-align: center;">
<f:image src="EXT:ep_theme/Resources/Public/images/logo_wide.svg" absolute="1" alt="Logo" height="60" width="197" />
</td>
</tr>
<tr>
<td valign="top" class="textContent" style="padding: 0px 36px;color: #222222;font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, Verdana, sans-serif;font-size: 24px;text-align: center;">
<strong><f:render section="Title" optional="true" /></strong>
</td>
</tr>
</tbody>
</table>
<!--[if mso]></td></tr></table><![endif]-->
</td></tr></tbody></table>
</td></tr></table>
<!--[if (gte mso 9)|(IE)]></td></tr></table><![endif]-->
</td></tr>
<!-- HEADER END -->
<!-- BODY START -->
<tr><td align="center" valign="top" id="templateBody">
<!--[if (gte mso 9)|(IE)]><table align="center" border="0" cellspacing="0" cellpadding="0" width="600" style="width:600px;"><tr><td align="center" valign="top" width="600" style="width:600px;"><![endif]-->
<table align="center" border="0" cellpadding="0" cellspacing="0" width="100%" class="templateContainer"><tr><td valign="top" class="bodyContainer">
<table border="0" cellpadding="0" cellspacing="0" width="100%" class="textBlock" style="min-width:100%;"><tbody class="textBlockOuter"><tr><td valign="top" class="textBlockInner" style="padding: 36px 0px;">
<!--[if mso]><table align="left" border="0" cellspacing="0" cellpadding="0" width="100%" style="width:100%;"><tr><td valign="top" width="600" style="width:600px;"><![endif]-->
<table align="left" border="0" cellpadding="0" cellspacing="0" style="max-width:100%; min-width:100%;" width="100%" class="textContentContainer">
<tbody>
<tr>
<td valign="top" class="textContent" style="padding: 0px 36px;">
<f:render section="Main" />
</td>
</tr>
</tbody>
</table>
<!--[if mso]></td></tr></table><![endif]-->
</td></tr></tbody></table>
</td></tr></table>
<!--[if (gte mso 9)|(IE)]></td></tr></table><![endif]-->
</td></tr>
<!-- BODY END -->
</table>
</td></tr></table>
</center>
</body>
</html>
@@ -0,0 +1,2 @@
<f:spaceless><f:render section="Title" optional="true" />
<f:render section="Main" /></f:spaceless>
@@ -0,0 +1 @@
<f:render section="Main"/>
@@ -2,8 +2,11 @@
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
<f:render partial="Topnav" arguments="{_all}"/>
<f:render partial="Mainnav" section="Main" arguments="{_all}"/>
<f:cObject typoscriptObjectPath="lib.searchBarCollapsed"/>
<f:alias map="{searchbarCollapsed: 1}">
<f:render partial="Topnav" arguments="{_all}"/>
<f:render partial="Mainnav" section="Main" arguments="{_all}"/>
</f:alias>
<main id="main-content">
<f:render section="Content"/>
<f:render section="Teasers"/>
@@ -5,6 +5,11 @@
<f:render partial="Mainnav" section="Main" arguments="{_all}"/>
<header>
<f:render partial="HeaderSliderSmall" arguments="{_all}"/>
<f:if condition="{data.tx_eptheme_hide_searchbar} || {settings.hideSearchbar}">
<f:else>
<f:cObject typoscriptObjectPath="lib.searchBar"/>
</f:else>
</f:if>
</header>
<main id="main-content">
<f:cObject typoscriptObjectPath="lib.breadcrumb"/>
@@ -5,6 +5,11 @@
<f:render partial="Mainnav" section="Main" arguments="{_all}"/>
<header>
<f:render partial="HeaderSliderSmall" arguments="{_all}"/>
<f:if condition="{data.tx_eptheme_hide_searchbar}">
<f:else>
<f:cObject typoscriptObjectPath="lib.searchBar"/>
</f:else>
</f:if>
</header>
<main id="main-content">
<f:cObject typoscriptObjectPath="lib.breadcrumb"/>
@@ -0,0 +1,34 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers"
data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:render partial="Field/Field" arguments="{element: element}" contentAs="elementContent">
<div class="flex items-center space-x-2">
<f:form.textfield property="{element.identifier}"
id="{element.uniqueIdentifier}"
value=""
class="form-field"
errorClass="form-field--has-error"
placeholder="Bitte die Zeichen aus der Grafik eingeben"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"/>
<img src="{f:uri.page(pageType:3413)}" alt="Captcha image" loading="lazy" onload="this.parentElement.classList.remove('captcha--reloading'); return false;"/>
<f:if condition="{element.properties.showRefresh}">
<button type="button"
class="captcha__reload"
aria-label="Captcha neu laden"
data-url="{f:uri.page(pageType:3413)}"
onclick="const div = this.parentElement; div.classList.add('captcha--reloading', 'captcha--spin'); let captchaUrl = this.dataset.url; this.previousElementSibling.setAttribute('src', captchaUrl + (/\?/.test(captchaUrl) ? '&' : '?') + 'now=' + Date.now()); setTimeout(function(){div.classList.remove('captcha--spin')},400); return false;">
<span class="sr-only">Captcha neu laden</span>
<svg width="31" height="28" xmlns="http://www.w3.org/2000/svg">
<g fill="#000" fill-rule="evenodd">
<path d="M10 10.7 6.3 8.5a11 11 0 0 1 20 3l2.5-.8h.4v-.3A14 14 0 0 0 3.6 7L.3 5l1.8 8.3 8-2.6ZM31 23l-1.7-8-8 2.5 3.7 2.1a10.9 10.9 0 0 1-19.8-2.3l-2 .6-1 .3a13.9 13.9 0 0 0 17 9.3 14 14 0 0 0 8.4-6.4l3.4 2Z"/>
</g>
</svg>
</button>
</f:if>
</div>
</f:render>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,30 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers"
xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers"
data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:render partial="Field/Field" arguments="{element: element, doNotShowLabel: 1}" contentAs="elementContent">
<f:if condition="{v:format.substring(start: 0, length: 1, content: '{element.label}')} == '*'">
<f:then>
<f:variable name="labelClass" value="ml-2 font-bold"/>
<f:variable name="labelString" value="{v:format.substring(start: 1, content: '{element.label}')}"/>
</f:then>
<f:else>
<f:variable name="labelClass" value="ml-2"/>
<f:variable name="labelString" value="{element.label}"/>
</f:else>
</f:if>
<label class="inline-flex items-center">
<f:form.checkbox
property="{element.identifier}"
id="{element.uniqueIdentifier}"
value="{element.properties.value}"
class="form-checkbox"
errorClass="form-checkbox--has-error"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
/>
<span class="{labelClass}">{labelString}<f:if condition="{element.required}"><f:render partial="Field/Required" /></f:if></span>
</label>
</f:render>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,21 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:if condition="{element.rootForm.renderingOptions.previewMode}">
<f:then>
<f:if condition="{element.properties.contentElementUid}">
<f:then>
<formvh:be.renderContentElementPreview contentElementUid="{element.properties.contentElementUid}" />
</f:then>
<f:else>
<f:translate key="LLL:EXT:form/Resources/Private/Language/Database.xlf:formEditor.elements.ContentElement.selectContentElement" />
</f:else>
</f:if>
</f:then>
<f:else>
<f:if condition="{element.properties.contentElementUid}">
<f:cObject typoscriptObjectPath="lib.tx_form.contentElementRendering">{element.properties.contentElementUid}</f:cObject>
</f:if>
</f:else>
</f:if>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,14 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:render partial="Field/Field" arguments="{element: element}" contentAs="elementContent">
<f:form.textfield
type="date"
property="{element.identifier}"
id="{element.uniqueIdentifier}"
class="form-field"
errorClass="form-field--has-error"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
/>
</f:render>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,14 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:render partial="Field/Field" arguments="{element: element}" contentAs="elementContent">
<f:form.textfield
type="email"
property="{element.identifier}"
id="{element.uniqueIdentifier}"
class="form-field"
errorClass="form-field--has-error"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
/>
</f:render>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,18 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<f:form.validationResults for="{element.rootForm.identifier}.{element.identifier}">
<label class="block mb-4">
<f:if condition="{doNotShowLabel} != 1">
<span class="{f:if(condition: '{validationResults.errors.0}', then: 'text-red-500', else: 'text-zinc-700')}">{formvh:translateElementProperty(element: element, property: 'label')}<f:if condition="{element.required}"><f:render partial="Field/Required" /></f:if></span>
</f:if>
{elementContent -> f:format.raw()}
<f:if condition="{validationResults.flattenedErrors}">
<div class="text-red-500 mt-2" role="alert">
<f:for each="{validationResults.errors}" as="error">
<f:format.htmlspecialchars>{formvh:translateElementError(element: element, error: error)}</f:format.htmlspecialchars>
<br />
</f:for>
</div>
</f:if>
</label>
</f:form.validationResults>
</html>
@@ -0,0 +1,12 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<fieldset id="{element.uniqueIdentifier}" class="{f:if(condition: element.properties.elementClassAttribute, then: ' {element.properties.elementClassAttribute}')}">
<f:if condition="{element.label}">
<legend class="pb-2 mb-2 border-b border-zinc-400">{formvh:translateElementProperty(element: element, property: 'label')}</legend>
</f:if>
<f:for each="{element.elements}" as="element">
<f:render partial="{element.templateName}" arguments="{element: element}" />
</f:for>
</fieldset>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,28 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<nav class="form-navigation">
<div class="button-group" role="group">
<f:if condition="{form.previousPage}">
<f:form.hidden property="__currentPage" value="{form.previousPage.index}" />
<f:form.button type="button" onclick="this.form.noValidate = true; this.form.requestSubmit();" class="button bg-button" formnovalidate="formnovalidate">{formvh:translateElementProperty(element: form.currentPage, renderingOptionProperty: 'previousButtonLabel')}</f:form.button>
</f:if>
<f:if condition="{form.nextPage}">
<f:then>
<f:form.button property="__currentPage"
value="{form.nextPage.index}"
data="{'form-debounce-target': 'button'}"
class="button bg-button">
{formvh:translateElementProperty(element: form.currentPage, renderingOptionProperty: 'nextButtonLabel')}
</f:form.button>
</f:then>
<f:else>
<f:form.button property="__currentPage"
value="{form.pages -> f:count()}"
data="{'form-debounce-target': 'button'}"
class="button bg-button">
{formvh:translateElementProperty(element: form, renderingOptionProperty: 'submitButtonLabel')}
</f:form.button>
</f:else>
</f:if>
</div>
</nav>
</html>
@@ -0,0 +1,19 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:render partial="Field/Field" arguments="{element: element, doNotShowLabel: 1}" contentAs="elementContent">
<label class="inline-flex items-center">
<f:form.checkbox
property="{element.identifier}"
id="{element.uniqueIdentifier}"
class="form-checkbox"
errorClass="form-checkbox--has-error"
value="{element.properties.value}"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
/>
<span class="ml-2">
{formvh:translateElementProperty(element: element, property: 'label') -> f:format.raw()} <f:link.typolink class="underline" parameter="{element.properties.pageUid}" target="_blank">{formvh:translateElementProperty(element: element, property: 'linkText')}</f:link.typolink><f:if condition="{element.required}"> <f:render partial="Field/Required" /></f:if>
</span>
</label>
</f:render>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,35 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers"
xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers"
data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:render partial="Field/Field" arguments="{element: element, doNotShowLabel: 1}" contentAs="elementContent">
<span class="block text-zinc-700 mb-1">{formvh:translateElementProperty(element: element, property: 'label')}<f:if condition="{element.required}"><f:render partial="Field/Required" /></f:if></span>
<f:for each="{element.properties.options}" as="label" key="value" iteration="idIterator">
<f:if condition="{v:format.substring(start: 0, length: 1, content: '{label}')} == '*'">
<f:then>
<f:variable name="labelClass" value="ml-2 font-bold"/>
<f:variable name="labelString" value="{v:format.substring(start: 1, content: '{label}')}"/>
</f:then>
<f:else>
<f:variable name="labelClass" value="ml-2"/>
<f:variable name="labelString" value="{label}"/>
</f:else>
</f:if>
<div>
<label class="inline-flex items-center">
<f:form.checkbox
property="{element.identifier}"
multiple="1"
id="{element.uniqueIdentifier}-{idIterator.index}"
value="{value}"
class="form-checkbox"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
/>
<span class="{labelClass}">{labelString}<f:if condition="{element.required}"><f:render partial="Field/Required" /></f:if></span>
</label>
</div>
</f:for>
</f:render>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,33 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:render partial="Field/Field" arguments="{element: element}" contentAs="elementContent">
<f:if condition="{element.properties.prependOptionLabel}">
<f:then>
<f:form.select
property="{element.identifier}"
id="{element.uniqueIdentifier}"
class="form-field"
errorClass="form-field--has-error"
options="{formvh:translateElementProperty(element: element, property: 'options')}"
multiple="multiple"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
prependOptionLabel="{formvh:translateElementProperty(element: element, property: 'prependOptionLabel')}"
prependOptionValue="{formvh:translateElementProperty(element: element, property: 'prependOptionValue')}"
/>
</f:then>
<f:else>
<f:form.select
property="{element.identifier}"
id="{element.uniqueIdentifier}"
class="form-field"
errorClass="form-field--has-error"
options="{formvh:translateElementProperty(element: element, property: 'options')}"
multiple="multiple"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
/>
</f:else>
</f:if>
</f:render>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,14 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:render partial="Field/Field" arguments="{element: element}" contentAs="elementContent">
<f:form.textfield
type="number"
property="{element.identifier}"
id="{element.uniqueIdentifier}"
class="form-field"
errorClass="form-field--has-error"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
/>
</f:render>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,22 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:render partial="Field/Field" arguments="{element: element, doNotShowLabel: 1}" contentAs="elementContent">
<span class="block text-zinc-700 mb-1">{formvh:translateElementProperty(element: element, property: 'label')}<f:if condition="{element.required}"><f:render partial="Field/Required" /></f:if></span>
<f:for each="{element.properties.options}" as="label" key="value" iteration="idIterator">
<div>
<label for="{element.uniqueIdentifier}-{idIterator.index}" class="inline-flex items-center">
<f:form.radio
property="{element.identifier}"
id="{element.uniqueIdentifier}-{idIterator.index}"
value="{value}"
class="form-radio"
errorClass="form-radio--has-error"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
/>
<span class="ml-2">{formvh:translateElementProperty(element: element, property: '{0: \'options\', 1: value}')}</span>
</label>
</div>
</f:for>
</f:render>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,30 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:render partial="Field/Field" arguments="{element: element}" contentAs="elementContent">
<f:if condition="{element.properties.prependOptionLabel}">
<f:then>
<f:form.select
property="{element.identifier}"
id="{element.uniqueIdentifier}"
options="{formvh:translateElementProperty(element: element, property: 'options')}"
class="form-field"
errorClass="form-field--has-error"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
prependOptionLabel="{formvh:translateElementProperty(element: element, property: 'prependOptionLabel')}"
prependOptionValue="{formvh:translateElementProperty(element: element, property: 'prependOptionValue')}"
/>
</f:then>
<f:else>
<f:form.select
property="{element.identifier}"
id="{element.uniqueIdentifier}"
options="{formvh:translateElementProperty(element: element, property: 'options')}"
class="form-field"
errorClass="form-field--has-error"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
/>
</f:else>
</f:if>
</f:render>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,15 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<f:comment>Same spinner as MyE&amp;P (_partials/_spinner.html.twig), drawn in currentColor</f:comment>
<svg class="{class}" viewBox="0 0 44 44" xmlns="http://www.w3.org/2000/svg" stroke="currentColor">
<g fill="none" fill-rule="evenodd" stroke-width="2">
<circle cx="22" cy="22" r="1">
<animate attributeName="r" begin="0s" dur="1.8s" values="1; 20" calcMode="spline" keyTimes="0; 1" keySplines="0.165, 0.84, 0.44, 1" repeatCount="indefinite" />
<animate attributeName="stroke-opacity" begin="0s" dur="1.8s" values="1; 0" calcMode="spline" keyTimes="0; 1" keySplines="0.3, 0.61, 0.355, 1" repeatCount="indefinite" />
</circle>
<circle cx="22" cy="22" r="1">
<animate attributeName="r" begin="-0.9s" dur="1.8s" values="1; 20" calcMode="spline" keyTimes="0; 1" keySplines="0.165, 0.84, 0.44, 1" repeatCount="indefinite" />
<animate attributeName="stroke-opacity" begin="-0.9s" dur="1.8s" values="1; 0" calcMode="spline" keyTimes="0; 1" keySplines="0.3, 0.61, 0.355, 1" repeatCount="indefinite" />
</circle>
</g>
</svg>
</html>
@@ -0,0 +1,11 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:if condition="{element.properties.text}">
<p{f:if(condition: element.properties.elementClassAttribute, then: ' class="{element.properties.elementClassAttribute}"')}>
<f:link.typolink parameter="{element.properties.targetPage}">
{formvh:translateElementProperty(element: element, property: 'text') -> f:format.nl2br()}
</f:link.typolink>
</p>
</f:if>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,14 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:render partial="Field/Field" arguments="{element: element}" contentAs="elementContent">
<f:form.textfield
type="tel"
property="{element.identifier}"
id="{element.uniqueIdentifier}"
class="form-field"
errorClass="form-field--has-error"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
/>
</f:render>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,13 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:render partial="Field/Field" arguments="{element: element}" contentAs="elementContent">
<f:form.textfield
property="{element.identifier}"
id="{element.uniqueIdentifier}"
class="form-field"
errorClass="form-field--has-error"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
/>
</f:render>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,15 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{element}">
<f:render partial="Field/Field" arguments="{element: element}" contentAs="elementContent">
<f:form.textarea
property="{element.identifier}"
id="{element.uniqueIdentifier}"
class="form-field"
errorClass="form-field--has-error"
rows="{element.properties.rows}"
cols="{element.properties.cols}"
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
/>
</f:render>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,28 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<formvh:renderRenderable renderable="{form}">
<formvh:form
object="{form}"
action="{form.renderingOptions.controllerAction}"
method="{form.renderingOptions.httpMethod}"
id="{form.identifier}"
section="{form.identifier}"
enctype="{form.renderingOptions.httpEnctype}"
addQueryString="{form.renderingOptions.addQueryString}"
argumentsToBeExcludedFromQueryString="{form.renderingOptions.argumentsToBeExcludedFromQueryString}"
additionalParams="{form.renderingOptions.additionalParams}"
additionalAttributes="{formvh:translateElementProperty(element: form, property: 'fluidAdditionalAttributes')}"
data="{'controller': 'form-debounce', 'action': 'form-debounce#debounce', 'form-debounce-disabled-class': 'cursor-not-allowed'}"
hx-boost="true"
hx-target="closest .form-island"
hx-select=".form-island"
hx-swap="outerHTML"
hx-push-url="false"
hx-indicator="closest .form-island"
>
<f:render partial="{form.currentPage.templateName}" arguments="{page: form.currentPage}" />
<div class="actions">
<f:render partial="Form/Navigation" arguments="{form: form}" />
</div>
</formvh:form>
</formvh:renderRenderable>
</html>
@@ -0,0 +1,31 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true">
<f:comment>
Every form sits in a .form-island, on pages TYPO3 13 renders as well as in the form page type
(/path/form) that the static pages load: the form posts there, and htmx swaps the island as a
whole (see Form.html). While a request runs, htmx sets htmx-request on it and the overlay
covers the form. Styled here and not in the theme build: the static pages around the island
load the CSS of the TYPO3 10 export. The spinner takes the button colour of each theme.
</f:comment>
<div class="form-island">
<f:flashMessages />
<f:if condition="{formConfiguration}">
<div class="py-8">
<formvh:render overrideConfiguration="{formConfiguration}" />
</div>
</f:if>
<div class="form-island__loading" aria-hidden="true">
<f:render partial="Spinner" arguments="{class: 'form-island__spinner'}" />
</div>
<style>
.form-island { position: relative; }
.form-island__loading { position: absolute; inset: 0; z-index: 10; display: flex; align-items: center; justify-content: center; background: rgb(255 255 255 / .7); visibility: hidden; opacity: 0; transition: opacity .15s, visibility .15s; }
.form-island.htmx-request .form-island__loading { visibility: visible; opacity: 1; }
.form-island__spinner { width: 6rem; height: 6rem; color: rgb(24 82 123); }
.sbw .form-island__spinner { color: rgb(233 28 38); }
.snz .form-island__spinner { color: rgb(249 195 61); }
.suz .form-island__spinner { color: rgb(130 195 198); }
.uch .form-island__spinner { color: rgb(25 163 220); }
.ser .form-island__spinner { color: rgb(222 44 27); }
</style>
</div>
</html>
@@ -0,0 +1,280 @@
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
data-namespace-typo3-fluid="true">
<f:layout name="Default"/>
<f:section name="Main">
<div data-controller="searchbar"
<f:if condition="{collapsed}">
data-searchbar-collapsed-value="true"
</f:if>
data-action="datepicker:range-select->searchbar#setDateRange searchbar-toggle:toggle@window->searchbar#toggle">
<f:comment>
GET to the search page, read by SearchController::initializeSearchresultAction()
(SEARCHBAR_PARAMETERS). searchbar_controller.js finds the fields by their target.
</f:comment>
<form action="{f:uri.page(pageUid: settings.defaultSearchPageUid)}" method="get" data-searchbar-target="form">
<input type="hidden" name="dateFrom" value="{searchParams.dateFrom}" data-searchbar-target="dateFrom"/>
<input type="hidden" name="dateTo" value="{searchParams.dateTo}" data-searchbar-target="dateTo"/>
<input type="hidden" name="pax" value="{searchParams.pax}" data-searchbar-target="pax"/>
<input type="hidden" name="destinationUid" value="{searchParams.destinationUid}" data-searchbar-target="destinationUid"/>
<input type="hidden" name="destinationType" value="{searchParams.destinationType}" data-searchbar-target="destinationType"/>
<input type="hidden" name="priceRange" value="{searchParams.priceRange}" data-searchbar-target="priceRange"/>
<div class="searchbar{f:if(condition: collapsed, then: ' reduced hidden')}"
<f:if condition="{collapsed}">
<f:else>
data-controller="sticky"
data-sticky-offset-value="650"
data-sticky-padding-value="7.5rem"
data-sticky-disabled-value="false"
data-sticky-classes-value="sticky reduced"
</f:else>
</f:if>
data-searchbar-target="container">
<div class="bg-brand-gradient">
<div class="reduced:max-w-screen-xl reduced:mx-auto reduced:px-4 flex flex-col reduced:flex-row reduced:items-center">
<div class="flex items-start justify-between reduced:flex-1 pt-8 px-8 reduced:px-0 reduced:py-4">
<div class="flex-1"
data-controller="collapse datepicker"
data-datepicker-inline-value="true"
data-datepicker-date-from-value="{searchParams.dateFrom}"
data-datepicker-date-to-value="{searchParams.dateTo}"
data-datepicker-min-date-value="{f:format.date(date: 'now', format: 'Y-m-d')}"
data-action="collapse:click:outside->collapse#close searchbar:input@window->collapse#close"
data-collapse-collapsed-value="true">
<div class="relative border-b border-r border-white/50 mr-8">
<input type="text"
data-action="click->collapse#toggle"
class="w-full bg-transparent border-0 ring-0 focus:ring-0 text-white uppercase px-2 py-1 cursor-pointer placeholder-white"
placeholder="Zeitraum"
aria-label="Zeitraum"
data-searchbar-target="dateRangeLabel"/>
<svg class="w-6 h-6 text-white absolute right-0 top-0 mr-2 mt-1 cursor-pointer"
data-action="click->collapse#toggle">
<use href="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/icons_sprite.svg')}#icon-calendar"></use>
</svg>
<div class="hidden absolute z-100 top-100 mt-2 left-0 min-w-full bg-white p-4 shadow-md rounded"
data-collapse-target="container">
<div class="flex justify-between divide-x divide-zinc-200">
<div class="pr-2">
<input type="hidden"
aria-label="Zeitraum"
data-datepicker-target="field">
</div>
<div class="flex-1 flex flex-col justify-between pl-2">
<f:if condition="{settings.datePickerPresets}">
<div class="flex flex-col space-y-4">
<f:for each="{settings.datePickerPresets}" as="preset">
<button type="button"
class="button bg-button bg-button--light button--small w-full"
data-preset='{preset -> f:format.json() -> f:format.raw()}'
data-action="datepicker#selectPreset">
<span>
{preset.label}
</span>
</button>
</f:for>
</div>
</f:if>
<div class="flex flex-col space-y-4">
<button type="button"
class="button bg-button bg-button--light button--small w-full"
data-action="collapse#close">
schließen
</button>
<button type="button"
class="button bg-button bg-button--light button--small w-full"
data-action="datepicker#reset">
zurücksetzen
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="w-24"
data-controller="collapse"
data-action="collapse:click:outside->collapse#close searchbar:input@window->collapse#close"
data-collapse-collapsed-value="true">
<div class="relative border-b border-r border-white/50 mr-8">
<input type="text"
data-action="click->collapse#toggle"
data-searchbar-target="paxLabel"
aria-label="Personenzahl"
value="{searchParams.pax}"
class="w-full bg-transparent border-0 ring-0 focus:ring-0 text-white uppercase px-2 py-1 cursor-pointer"/>
<svg class="w-6 h-6 text-white absolute right-0 top-0 mr-2 mt-1 cursor-pointer"
data-action="click->collapse#toggle">
<use href="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/icons_sprite.svg')}#icon-user-group"></use>
</svg>
<div
class="hidden absolute z-20 top-100 mt-2 left-0 bg-white p-2 shadow-md rounded w-full h-48 overflow-y-scroll text-sm leading-6"
data-collapse-target="container">
<ul class="m-0 p-0">
<f:for each="{filterOptions.pax}" as="option">
<li>
<button type="button"
data-action="searchbar#setPax"
data-option="{option}"
class="w-full text-right">
{option}
</button>
</li>
</f:for>
<li>
<a href="{f:uri.typolink(parameter: settings.groupsPageUid)}"
class="block text-right">
&gt; 24
</a>
</li>
</ul>
</div>
</div>
</div>
<div class="flex-1"
data-controller="collapse"
data-action="collapse:click:outside->collapse#close searchbar:input@window->collapse#close"
data-collapse-collapsed-value="true">
<div class="relative border-b border-r border-white/50 mr-8">
<input type="text"
data-action="click->collapse#toggle"
data-searchbar-target="destinationLabel"
aria-label="Reiseziel/Konzept"
class="w-full bg-transparent border-0 ring-0 focus:ring-0 text-white uppercase px-2 py-1 cursor-pointer placeholder-white"
placeholder="Reiseziel/Konzept"/>
<svg
class="w-6 h-6 text-white absolute right-0 top-0 mr-2 mt-1 transform rotate-45 cursor-pointer"
data-action="click->collapse#toggle">
<use href="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/icons_sprite.svg')}#icon-airplane"></use>
</svg>
<div
class="hidden absolute z-20 top-100 mt-2 left-0 bg-white p-2 shadow-md rounded min-w-full h-64 overflow-y-scroll"
data-collapse-target="container">
<div class="grid grid-cols-5 gap-4">
<f:for each="{filterOptions.destinations}" as="destination">
<div class="col-span-2">
<button type="button"
class="flex items-center space-x-2"
data-action="searchbar#setDestination"
data-option-uid="{destination.country.uid}"
data-option-type="country"
data-option-label="{destination.country.label}">
<svg class="block w-8 h-6">
<use href="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/icons_sprite.svg')}#icon-flag-{destination.country.code -> f:format.case(mode: 'lower')}"></use>
</svg>
<span>{destination.country.label}</span>
</button>
</div>
<div class="col-span-3 flex flex-col items-start space-y-1">
<f:for each="{destination.regions}" as="region">
<button type="button"
data-action="searchbar#setDestination"
data-option-uid="{region.uid}"
data-option-type="region"
data-option-label="{region.label}">
{region.label}
</button>
</f:for>
</div>
</f:for>
</div>
<div class="grid grid-cols-5 gap-4 border-t py-2 my-2">
<div class="col-span-2">
<strong>
Konzept
</strong>
</div>
<div class="col-span-3 flex flex-col items-start space-y-1">
<f:for each="{filterOptions.concepts}" as="concept">
<button type="button"
data-action="searchbar#setDestination"
data-option-uid="{concept.uid}"
data-option-type="concept"
data-option-label="{concept.name}">
{concept.name}
</button>
</f:for>
</div>
</div>
<button type="button"
class="button bg-button button--small"
data-action="searchbar#resetDestination">
zurücksetzen
</button>
</div>
</div>
</div>
<div class="w-32"
data-controller="collapse"
data-action="collapse:click:outside->collapse#close searchbar:input@window->collapse#close"
data-collapse-collapsed-value="true">
<div class="relative border-r border-b border-white/50">
<input type="text"
aria-label="Preis"
data-action="click->collapse#toggle"
data-searchbar-target="priceRangeLabel"
class="w-full bg-transparent border-0 ring-0 focus:ring-0 text-white uppercase px-2 py-1 cursor-pointer placeholder-white"
placeholder="Preis"/>
<svg class="w-6 h-6 text-white absolute right-0 top-0 mr-2 mt-1 cursor-pointer"
data-action="click->collapse#toggle">
<use href="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/icons_sprite.svg')}#icon-euro"></use>
</svg>
<div
class="hidden absolute z-20 top-100 left-0 bg-white p-2 shadow-md w-full h-48 overflow-y-scroll text-sm leading-7"
data-collapse-target="container">
<ul class="m-0 p-0">
<li>
<button type="button"
data-action="searchbar#setPriceRange"
data-option-value=""
data-label-value="beliebig"
class="w-full text-right">
beliebig
</button>
</li>
<f:for each="{filterOptions.priceRanges}" as="range" iteration="iteration">
<li>
<button type="button"
data-action="searchbar#setPriceRange"
data-option-value="{range.uid}"
data-label-value="{range.formatted}"
class="w-full text-right">
{range.formatted}
</button>
</li>
</f:for>
</ul>
</div>
</div>
</div>
</div>
<button type="submit"
class="hidden reduced:block reduced:ml-4" title="Suchen">
<svg class="w-8 h-8 text-white bg-badge-gradient">
<use href="{f:uri.image(src: 'EXT:ep_theme/Resources/Public/images/icons_sprite.svg')}#icon-chevron-right"></use>
</svg>
</button>
</div>
<div class="flex justify-end mt-6 reduced:hidden">
<button type="submit"
class="w-1/3 text-white uppercase py-2">
Detailsuche
</button>
<button type="submit"
class="w-1/3 text-white bg-badge-gradient hover:bg-none hover:bg-ep-pink transition-colors uppercase py-2">
Alle Reisen anzeigen
</button>
</div>
</div>
</div>
</form>
</div>
</f:section>
</html>
@@ -0,0 +1,61 @@
<html xmlns="http://www.w3.org/1999/xhtml" lang="en"
xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
xmlns:ep="http://typo3.org/ns/EP/EpTheme/ViewHelpers"
xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers"
data-namespace-typo3-fluid="true">
<f:layout name="Default"/>
<f:section name="Main">
<f:comment>
The id lets the static pages of the hybrid setup pick this list, with the spacing of
ep:container, out of the snow report page type (/path/snowreport), which renders every
snow report plugin of a page.
</f:comment>
<div id="snowreport-{data.uid}">
<ep:container data="{data}">
<div class="flex flex-col space-y-2">
<f:for each="{list}" as="snowreport">
<div class="grid md:grid-cols-3 md:gap-y-0">
<div class="md:col-span-1 bg-ep-primary-dark p-2 flex items-start space-x-2">
{ep:icon(icon: 'flag-{snowreport.countryCode -> f:format.case(mode: \'lower\')}', class: 'w-8 h-6')}
<f:link.typolink parameter="{snowreport.regionDetailPage}"
title="{snowreport.regionName}"
class="text-white uppercase text-lg">
{snowreport.regionName}
</f:link.typolink>
</div>
<div class="md:col-span-2 bg-ep-primary-dark/20 p-2">
<f:if condition="{snowreport.inSeason}">
<f:then>
<ul class="flex flex-col space-y-1">
<li>
<strong>Berg/Tal:</strong> {snowreport.snow_level_mountain -> v:or(alternative: '-')}/{snowreport.snow_level_valley -> v:or(alternative: '-')} cm
</li>
<li>
<strong>Qualität:</strong> {snowreport.snow_quality}
</li>
<li>
<strong>Geöffnete Lifte:</strong> <f:if condition="{snowreport.lifts_opened} > 0"><f:then>{snowreport.lifts_opened}/{snowreport.lifts_total}</f:then><f:else>keine Angabe</f:else></f:if>
</li>
<li>
<strong>Letzter Schneefall:</strong> {f:if(condition: snowreport.last_snowfall, then: '{snowreport.last_snowfall -> f:format.date(format: \'d.m.Y\')}', else: 'keine Angabe')}
</li>
<li>
<strong>Letzte Akt.:</strong> {snowreport.last_update -> f:format.date(format: 'd.m.Y')}
</li>
</ul>
</f:then>
<f:else>
Saison vom {snowreport.seasonStart -> f:format.date(format: 'd.m.Y')} bis {snowreport.seasonEnd -> f:format.date(format: 'd.m.Y')}
</f:else>
</f:if>
</div>
</div>
</f:for>
</div>
</ep:container>
</div>
</f:section>
</html>
+3
View File
@@ -12,11 +12,14 @@
"require": {
"php": "^8.2",
"b13/container": "^4.1",
"blueways/bw-captcha": "^5.4",
"ep/ep-products": "@dev",
"tritum/form-element-linked-checkbox": "^6.0",
"typo3/cms-core": "^13.4",
"typo3/cms-extbase": "^13.4",
"typo3/cms-fluid": "^13.4",
"typo3/cms-fluid-styled-content": "^13.4",
"typo3/cms-form": "^13.4",
"typo3/cms-frontend": "^13.4"
},
"autoload": {
+1
View File
@@ -15,6 +15,7 @@ $boot = function () {
$GLOBALS['TYPO3_CONF_VARS']['RTE']['Presets']['ep-minimal'] = 'EXT:ep_theme/Configuration/RTE/Minimal.yaml';
$GLOBALS['TYPO3_CONF_VARS']['SYS']['fluid']['namespaces']['ep'] = ['EP\\EpTheme\\ViewHelpers'];
$GLOBALS['TYPO3_CONF_VARS']['MAIL']['layoutRootPaths'][700] = 'EXT:ep_theme/Resources/Private/Layouts/Email/';
$GLOBALS['TYPO3_CONF_VARS']['MAIL']['format'] = 'html';
$metaTagManagerRegistry = GeneralUtility::makeInstance(MetaTagManagerRegistry::class);
@@ -0,0 +1,136 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="en" datatype="plaintext" original="EXT:backend/Resources/Private/Language/Modules/about.xlf" date="2011-10-17T20:22:34Z" product-name="typo3-cms-backend" target-language="de">
<header/>
<body>
<trans-unit id="mlang_labels_tablabel" approved="yes">
<source>About TYPO3 CMS</source>
<target state="final">Über TYPO3 CMS</target>
</trans-unit>
<trans-unit id="mlang_labels_tabdescr" approved="yes">
<source>Displays the basic facts about the TYPO3 application, version and licensing terms.</source>
<target state="final">Zeigt die Grunddaten zu TYPO3, Versionsinformationen und Lizenzbedingungen an.</target>
</trans-unit>
<trans-unit id="mlang_tabs_tab" approved="yes">
<source>About TYPO3 CMS</source>
<target state="final">Über TYPO3 CMS</target>
</trans-unit>
<trans-unit id="title" approved="yes">
<source>About TYPO3 CMS</source>
<target state="final">Über TYPO3 CMS</target>
</trans-unit>
<trans-unit id="typo3_logo" approved="yes">
<source>TYPO3 CMS logo</source>
<target state="final">Logo des TYPO3 CMS</target>
</trans-unit>
<trans-unit id="information" approved="yes">
<source>TYPO3 Information</source>
<target state="final">Informationen zu TYPO3</target>
</trans-unit>
<trans-unit id="welcome" approved="yes">
<source>TYPO3 CMS - Professional Web Content Management System</source>
<target state="final">TYPO3 CMS - Professionelles Web Content Management System</target>
</trans-unit>
<trans-unit id="minor" approved="yes">
<source>TYPO3 CMS is an enterprise-class, Open Source Content Management System, used internationally to build and manage websites of all types, from small sites for non-profits to multilingual enterprise solutions for large corporations.&lt;br /&gt;&lt;br /&gt;For further information visit &lt;a href="https://typo3.org/typo3-cms/" target="_blank" rel="noreferrer"&gt;typo3.org&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;TYPO3 CMS is &lt;b&gt;freely available&lt;/b&gt; under the &lt;a href="https://typo3.org/project/licenses/" target="_blank"&gt;TYPO3-license (GNU/GPL)&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;You are using %s %s</source>
<target state="final">Das TYPO3 CMS ist ein quelloffenes Business-Level Content Management System, welches weltweit verwendet wird und jegliche Webseiten aller Arten verwaltet. Von kleinen Websites für Non-Profits bis hin zu mehrsprachigen Business Lösungen für große Konzerne. &lt;br /&gt;&lt;br /&gt;Weitere Informationen auf &lt;a href="https://typo3.org/typo3-cms/" target="_blank" rel="noopener noreferrer"&gt;typo3.org&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;TYPO3 CMS ist &lt;b&gt;frei verfügbar&lt;/b&gt; unter der &lt;a href="https://typo3.org/typo3-cms/overview/licenses/" target="_blank"&gt;TYPO3-Lizenz (GNU/GPL)&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Du benutzt %s %s</target>
</trans-unit>
<trans-unit id="cms_description" approved="yes">
<source>TYPO3 CMS is an enterprise-class, Open Source Content Management System, used internationally to build and manage websites of all types, from small sites for non-profits to multilingual enterprise solutions for large corporations.&lt;br /&gt;&lt;br /&gt;For further information visit &lt;a href="https://typo3.org/typo3-cms/" target="_blank" rel="noreferrer"&gt;typo3.org&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;TYPO3 CMS is &lt;b&gt;freely available&lt;/b&gt; under the &lt;a href="https://typo3.org/project/licenses/" target="_blank"&gt;TYPO3-license (GNU/GPL)&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;You are using version %s - Copyright %s %s</source>
<target state="final">Das TYPO3 CMS ist ein quelloffenes Business-Level Content Management System, welches weltweit verwendet wird und jegliche Webseiten aller Arten verwaltet. Von kleinen Websites für Non-Profits bis hin zu mehrsprachigen Business Lösungen für große Konzerne. &lt;br /&gt;&lt;br /&gt;Weitere Informationen auf &lt;a href="https://typo3.org/typo3-cms/" target="_blank" rel="noopener noreferrer"&gt;typo3.org&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;TYPO3 CMS ist &lt;b&gt;frei verfügbar&lt;/b&gt; unter der &lt;a href="https://typo3.org/typo3-cms/overview/licenses/" target="_blank"&gt;TYPO3-Lizenz (GNU/GPL)&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Du benutzt Version %s - Copyright %s %s</target>
</trans-unit>
<trans-unit id="community_credits" approved="yes">
<source>Community Credits</source>
<target state="final">Die TYPO3-Community</target>
</trans-unit>
<trans-unit id="information_detail" approved="yes">
<source>Visit &lt;a href="https://typo3.org/community/" target="_blank" rel="noreferrer"&gt;typo3.org/community/&lt;/a&gt; if you want to know why TYPO3 rocks.</source>
<target state="final">Besuche &lt;a href="https://typo3.org/community/" target="_blank" rel="noreferrer"&gt;typo3.org/community/&lt;/a&gt; wenn Du mehr darüber wissen möchtest, warum TYPO3 super ist.</target>
</trans-unit>
<trans-unit id="coredevs" approved="yes">
<source>Core Team</source>
<target state="final">Core Team</target>
</trans-unit>
<trans-unit id="coredevs_detail" approved="yes">
<source>Visit &lt;a href="https://typo3.org/teams-committees/core-development/" target="_blank" rel="noreferrer"&gt;typo3.org/teams-committees/core-development/&lt;/a&gt; for the complete member list.&lt;br /&gt;&lt;br /&gt;The Git Repository and the ChangeLog can be found &lt;a href="https://forge.typo3.org/projects/typo3cms-core/" target="_blank"&gt;here&lt;/a&gt;.</source>
<target state="final">Unter &lt;a href="https://typo3.org/teams-committees/core-development/" target="_blank" rel="noreferrer"&gt;typo3.org/teams-committees/core-development/&lt;/a&gt; findet man die vollständige Liste der aktuellen Core-Entwickler. Zum Git-Repository und dem Changelog gelangt man &lt;a href="https://forge.typo3.org/projects/typo3cms-core/" target="_blank"&gt;hier&lt;/a&gt;.</target>
</trans-unit>
<trans-unit id="extension_authors" approved="yes">
<source>Extension Authors</source>
<target state="final">Autoren der Erweiterung</target>
</trans-unit>
<trans-unit id="extension_list_info" approved="yes">
<source>This is a list of the people who contributed to the extensions you're using in your installation.</source>
<target state="final">Dies ist eine Liste der Menschen, die zu den Erweiterungen, die Sie in Ihrer Installation benutzen, beigetragen haben.</target>
</trans-unit>
<trans-unit id="extension" approved="yes">
<source>Extension</source>
<target state="final">Erweiterung</target>
</trans-unit>
<trans-unit id="extension_author" approved="yes">
<source>Author</source>
<target state="final">Entwickler</target>
</trans-unit>
<trans-unit id="donation.sectionHeadline" approved="yes">
<source>TYPO3 Donation and community</source>
<target state="final">TYPO3 Spende und Community</target>
</trans-unit>
<trans-unit id="donation_header" approved="yes">
<source>TYPO3 Donation</source>
<target state="final">TYPO3 Spende</target>
</trans-unit>
<trans-unit id="donation_message" approved="yes">
<source>It would be great if you could donate. TYPO3 CMS is Open Source and relies heavily on donations from its users and supporters.&lt;br/&gt;&lt;br/&gt;&lt;b&gt;Thank you&lt;/b&gt; for making this great Content Management System even better with your support!</source>
<target state="final">TYPO3 CMS ist Open Source und setzt auf Spenden von Benutzern und Unterstützern.&lt;br/&gt;&lt;br/&gt;&lt;b&gt;Vielen Dank&lt;/b&gt; dafür, dass Sie dieses großartige Content Management System mit Ihrer Unterstützung noch besser gemacht haben!</target>
</trans-unit>
<trans-unit id="donation_button" approved="yes">
<source>Donate now</source>
<target state="final">Jetzt spenden</target>
</trans-unit>
<trans-unit id="external_libraries" approved="yes">
<source>External Libraries</source>
<target state="final">Externe Bibliotheken</target>
</trans-unit>
<trans-unit id="external_thanks" approved="yes">
<source>TYPO3 CMS core uses and thanks these external Open Source projects:</source>
<target state="final">TYPO3 CMS-Kern verwendet und dankt diesen externen Open-Source-Projekten:</target>
</trans-unit>
<trans-unit id="external_libraries.table.column.name" approved="yes">
<source>Project name</source>
<target state="final">Projektname</target>
</trans-unit>
<trans-unit id="external_libraries.table.column.website" approved="yes">
<source>Website</source>
<target state="final">Webseite</target>
</trans-unit>
<trans-unit id="introtext" approved="yes">
<source>Web Content Management System</source>
<target state="final">Web Content-Management-System</target>
</trans-unit>
<trans-unit id="modules.headline" approved="yes">
<source>Modules</source>
<target state="final">Module</target>
</trans-unit>
<trans-unit id="modules.introtext" approved="yes">
<source>This is a brief description of the available modules.</source>
<target state="final">Hier finden Sie eine kurze Beschreibung der verfügbaren Module.</target>
</trans-unit>
<trans-unit id="endText" approved="yes">
<source>Features may vary depending on your website and permissions</source>
<target state="final">Die verfügbaren Funktionen hängen von der Website und den Zugriffsrechten ab</target>
</trans-unit>
<trans-unit id="userInfo" approved="yes">
<source>You're logged in as user</source>
<target state="final">Sie sind angemeldet als Benutzer</target>
</trans-unit>
<trans-unit id="link.openModule" approved="yes">
<source>Open module</source>
<target state="final">Modul öffnen</target>
</trans-unit>
<trans-unit id="link.openModuleWithTitle" approved="yes">
<source>Open %1s module</source>
<target state="final">%1s Modul öffnen</target>
</trans-unit>
</body>
</file>
</xliff>
@@ -0,0 +1,152 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="en" datatype="plaintext" original="EXT:backend/Resources/Private/Language/Modules/content-security-policy.xlf" date="2023-01-11T00:00:00Z" product-name="typo3-cms-backend" target-language="de">
<header/>
<body>
<trans-unit id="mlang_labels_tablabel" approved="yes">
<source>Content Security Policy</source>
<target state="final">Content Security Policy</target>
</trans-unit>
<trans-unit id="mlang_labels_tabdescr" approved="yes">
<source>Allows to manage Content Security Policy settings.</source>
<target state="final">Erlaubt die Verwaltung von Content Security Policy-Einstellungen.</target>
</trans-unit>
<trans-unit id="mlang_tabs_tab" approved="yes">
<source>Content Security Policy</source>
<target state="final">Content Security Policy</target>
</trans-unit>
<trans-unit id="module.headline" approved="yes">
<source>Content Security Policy</source>
<target state="final">Content Security Policy</target>
</trans-unit>
<trans-unit id="module.introtext" approved="yes">
<source>A list of the existing Content Security Policy Mutations can be viewed in the %s module.</source>
<target state="final">Eine Liste der vorhandenen Content Security Policy Mutationen kann im Modul %s eingesehen werden.</target>
</trans-unit>
<trans-unit id="module.introtextLowlevelMissing" approved="yes">
<source>If you install the core EXT:lowlevel extension, you can see a list of the existing Content Security Policy Mutations in the %s module.</source>
<target state="final">Wenn du die Systemerweiterung EXT:lowlevel installierst, kannst du eine Liste der vorhandenen Mutationen der Content Security Policy im %s-Modul sehen.</target>
</trans-unit>
<trans-unit id="module.introtext.moduleName" approved="yes">
<source>Configuration</source>
<target state="final">Konfiguration</target>
</trans-unit>
<trans-unit id="module.callout.featureDisabled.title" approved="yes">
<source>Disabled feature flags</source>
<target state="final">Deaktivierte Feature Flags</target>
</trans-unit>
<trans-unit id="module.callout.featureDisabled.message" approved="yes">
<source>The following feature flags are currently disabled and won't be shown in this module:</source>
<target state="final">Die folgenden Feature-Flags sind derzeit deaktiviert und werden nicht in diesem Modul angezeigt:</target>
</trans-unit>
<trans-unit id="module.callout.customReporting.title" approved="yes">
<source>Reporting</source>
<target state="final">Auswertung</target>
</trans-unit>
<trans-unit id="module.callout.customReporting.message" approved="yes">
<source>Reporting is currently configured with these custom endpoints and won't be shown in this module:</source>
<target state="final">Das Reporting ist derzeit mit diesen benutzerdefinierten Endpunkten konfiguriert und wird in diesem Modul nicht angezeigt:</target>
</trans-unit>
<trans-unit id="module.label.noEntriesAvailable" approved="yes">
<source>No entries available.</source>
<target state="final">Keine Einträge vorhanden.</target>
</trans-unit>
<trans-unit id="module.label.reports" approved="yes">
<source>Reports</source>
<target state="final">Berichte</target>
</trans-unit>
<trans-unit id="module.label.created" approved="yes">
<source>Created</source>
<target state="final">Erstellt</target>
</trans-unit>
<trans-unit id="module.label.scope" approved="yes">
<source>Scope</source>
<target state="final">Geltungsbereich</target>
</trans-unit>
<trans-unit id="module.label.removeAll" approved="yes">
<source>Remove all</source>
<target state="final">Alle entfernen</target>
</trans-unit>
<trans-unit id="module.label.violation" approved="yes">
<source>Violation</source>
<target state="final">Verstoß</target>
</trans-unit>
<trans-unit id="module.label.uri" approved="yes">
<source>URI</source>
<target state="final">URI</target>
</trans-unit>
<trans-unit id="module.label.all" approved="yes">
<source>All</source>
<target state="final">Alle</target>
</trans-unit>
<trans-unit id="module.label.details" approved="yes">
<source>Details</source>
<target state="final">Details</target>
</trans-unit>
<trans-unit id="module.label.disposition" approved="yes">
<source>Disposition</source>
<target state="final">Verwendung</target>
</trans-unit>
<trans-unit id="module.label.directive" approved="yes">
<source>Directive</source>
<target state="final">Direktive</target>
</trans-unit>
<trans-unit id="module.label.blocked_uri" approved="yes">
<source>Blocked URI</source>
<target state="final">Blockierte URI</target>
</trans-unit>
<trans-unit id="module.label.document_uri" approved="yes">
<source>Document URI</source>
<target state="final">URI des Dokuments</target>
</trans-unit>
<trans-unit id="module.label.sample" approved="yes">
<source>Sample</source>
<target state="final">Beispiel</target>
</trans-unit>
<trans-unit id="module.label.user_agent" approved="yes">
<source>User Agent</source>
<target state="final">User-Agent</target>
</trans-unit>
<trans-unit id="module.label.uuid" approved="yes">
<source>UUID</source>
<target state="final">UUID</target>
</trans-unit>
<trans-unit id="module.label.source_file" approved="yes">
<source>Source File</source>
<target state="final">Quelldatei</target>
</trans-unit>
<trans-unit id="module.label.summary" approved="yes">
<source>Summary</source>
<target state="final">Übersicht</target>
</trans-unit>
<trans-unit id="module.label.suggestions" approved="yes">
<source>Suggestions</source>
<target state="final">Vorschläge</target>
</trans-unit>
<trans-unit id="module.label.guide.no_record_selected" approved="yes">
<source>Select a row to see more information.</source>
<target state="final">Wählen Sie eine Zeile aus, um weitere Informationen zu sehen.</target>
</trans-unit>
<trans-unit id="module.label.showDetails" approved="yes">
<source>Show details for "%s" violation with URI: %s</source>
<target state="final">zeige Details zu „%s“-Verstoß der URI: %s</target>
</trans-unit>
<trans-unit id="module.button.apply" approved="yes">
<source>Apply</source>
<target state="final">Anwenden</target>
</trans-unit>
<trans-unit id="module.button.close" approved="yes">
<source>Close</source>
<target state="final">Schließen</target>
</trans-unit>
<trans-unit id="module.button.mute" approved="yes">
<source>Mute</source>
<target state="final">Stummschalten</target>
</trans-unit>
<trans-unit id="module.button.delete" approved="yes">
<source>Delete</source>
<target state="final">Löschen</target>
</trans-unit>
</body>
</file>
</xliff>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="en" datatype="plaintext" original="EXT:backend/Resources/Private/Language/Modules/locallang_alt_intro.xlf" date="2011-10-17T20:22:33Z" product-name="lang" target-language="de">
<header/>
<body>
</body>
</file>
</xliff>
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="en" datatype="plaintext" original="EXT:core/Resources/Private/Language/Wizards/move_page.xlf" date="2024-03-08T20:22:34Z" product-name="backend" target-language="de">
<header/>
<body>
<trans-unit id="headline.move" approved="yes">
<source>Move element "%s" [%d]</source>
<target state="final">Element „%s“ verschieben [%d]</target>
</trans-unit>
<trans-unit id="headline.copy" approved="yes">
<source>Copy element "%s" [%d]</source>
<target state="final">Element „%s“ kopieren [%d]</target>
</trans-unit>
<trans-unit id="currentPath" approved="yes">
<source>Current path</source>
<target state="final">Aktueller Pfad</target>
</trans-unit>
<trans-unit id="makeCopy" approved="yes">
<source>Copy element instead of moving</source>
<target state="final">Element kopieren statt verschieben</target>
</trans-unit>
<trans-unit id="moveElement.notification.elementMoved.title" approved="yes">
<source>Element successfully moved</source>
<target state="final">Element erfolgreich verschoben</target>
</trans-unit>
<trans-unit id="moveElement.notification.elementMoved.message" approved="yes">
<source>The element "%s" has been successfully moved.</source>
<target state="final">Das Element „%s“ wurde erfolgreich verschoben.</target>
</trans-unit>
<trans-unit id="moveElement.notification.elementCopied.title" approved="yes">
<source>Element successfully copied</source>
<target state="final">Element erfolgreich kopiert</target>
</trans-unit>
<trans-unit id="moveElement.notification.elementCopied.message" approved="yes">
<source>The element "%s" has been successfully copied.</source>
<target state="final">Das Element „%s“ wurde erfolgreich kopiert.</target>
</trans-unit>
<trans-unit id="moveElement.notification.elementPasted.action.dismiss" approved="yes">
<source>Dismiss</source>
<target state="final">Verwerfen</target>
</trans-unit>
<trans-unit id="moveElement.notification.elementPasted.action.open" approved="yes">
<source>Open "%s"</source>
<target state="final">Öffne „%s“</target>
</trans-unit>
</body>
</file>
</xliff>
@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="en" datatype="plaintext" original="EXT:core/Resources/Private/Language/Wizards/move_page.xlf" date="2024-03-08T20:22:34Z" product-name="backend" target-language="de">
<header/>
<body>
<trans-unit id="headline" approved="yes">
<source>Move page "%1$s" [%2$d]</source>
<target state="final">Seite verschieben "%1$s" [%2$d]</target>
</trans-unit>
<trans-unit id="currentPath" approved="yes">
<source>Current path</source>
<target state="final">Aktueller Pfad</target>
</trans-unit>
<trans-unit id="makeCopy" approved="yes">
<source>Copy page instead of moving page</source>
<target state="final">Seite kopieren statt verschieben</target>
</trans-unit>
<trans-unit id="samePageConflict" approved="yes">
<source>The page "%1$s" [%2$d] cannot get moved into itself.</source>
<target state="final">Die Seite „%1$s“ [%2$d] kann nicht in sich selbst verschoben werden.</target>
</trans-unit>
<trans-unit id="action.pasteAbove" approved="yes">
<source>Paste above</source>
<target state="final">Einfügen darüber</target>
</trans-unit>
<trans-unit id="action.pasteBelow" approved="yes">
<source>Paste below</source>
<target state="final">Einfügen darunter</target>
</trans-unit>
<trans-unit id="action.pasteInto" approved="yes">
<source>Paste into</source>
<target state="final">Einfügen in</target>
</trans-unit>
<trans-unit id="movePage.notification.pageMoved.title" approved="yes">
<source>Page successfully moved</source>
<target state="final">Seite erfolgreich verschoben</target>
</trans-unit>
<trans-unit id="movePage.notification.pageMoved.message" approved="yes">
<source>The page "%s" has been successfully moved.</source>
<target state="final">Die Seite „%s“ wurde erfolgreich verschoben.</target>
</trans-unit>
<trans-unit id="movePage.notification.pageCopied.title" approved="yes">
<source>Page successfully copied</source>
<target state="final">Seite erfolgreich kopiert</target>
</trans-unit>
<trans-unit id="movePage.notification.pageCopied.message" approved="yes">
<source>The page "%s" has been successfully copied.</source>
<target state="final">Die Seite „%s“ wurde erfolgreich kopiert.</target>
</trans-unit>
<trans-unit id="movePage.notification.pagePasted.action.dismiss" approved="yes">
<source>Dismiss</source>
<target state="final">Abweisen</target>
</trans-unit>
<trans-unit id="movePage.notification.pagePasted.action.open" approved="yes">
<source>Open "%s"</source>
<target state="final">Öffne „%s“</target>
</trans-unit>
</body>
</file>
</xliff>
@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="en" datatype="plaintext" original="EXT:backend/Resources/Private/Language/SudoMode.xlf" date="2023-04-08T00:00:00Z" product-name="backend" target-language="de">
<header/>
<body>
<trans-unit id="cancel" approved="yes">
<source>Cancel</source>
<target state="final">Abbrechen</target>
</trans-unit>
<trans-unit id="verify" approved="yes">
<source>Verify</source>
<target state="final">Überprüfen</target>
</trans-unit>
<trans-unit id="password" approved="yes">
<source>Password</source>
<target state="final">Passwort</target>
</trans-unit>
<trans-unit id="verifyWithUserPassword" approved="yes">
<source>Verify with user password</source>
<target state="final">Mit dem Benutzerpasswort bestätigen</target>
</trans-unit>
<trans-unit id="verifyWithInstallToolPassword" approved="yes">
<source>Verify with Install Tool password</source>
<target state="final">Mit dem Install-Tool-Passwort bestätigen</target>
</trans-unit>
<trans-unit id="accessGranted" approved="yes">
<source>Access granted</source>
<target state="final">Zugriff erlaubt</target>
</trans-unit>
<trans-unit id="invalidPassword" approved="yes">
<source>Invalid password</source>
<target state="final">Ungültiges Passwort</target>
</trans-unit>
<trans-unit id="userPasswordMode" approved="yes">
<source>Use user password instead</source>
<target state="final">Stattdessen Benutzer-Passwort verwenden</target>
</trans-unit>
<trans-unit id="installToolPasswordMode" approved="yes">
<source>Use Install Tool password instead</source>
<target state="final">Stattdessen Install-Tool-Passwort verwenden</target>
</trans-unit>
<trans-unit id="sudoModeUserPasswordExplanation" approved="yes">
<source>To perform this action, please enter your user password to confirm you are authorized to proceed.</source>
<target state="final">Gib bitte dein Benutzerpasswort ein, um diese Aktion durchzuführen und zu bestätigen, dass du berechtigt bist, fortzufahren.</target>
</trans-unit>
<trans-unit id="sudoModeInstallToolPasswordExplanation" approved="yes">
<source>To perform this action, please enter the Install Tool password to confirm you are authorized to proceed.</source>
<target state="final">Gib bitte das Passwort für das Install Tool ein, um diese Aktion auszuführen und zu bestätigen, dass du berechtigt bist, fortzufahren.</target>
</trans-unit>
<trans-unit id="verificationFailed" approved="yes">
<source>Verification failed</source>
<target state="final">Überprüfung fehlgeschlagen</target>
</trans-unit>
<trans-unit id="verificationExpired" approved="yes">
<source>Confirmation has expired. Please try again.</source>
<target state="final">Die Bestätigung ist abgelaufen. Bitte versuchen Sie es erneut.</target>
</trans-unit>
</body>
</file>
</xliff>
@@ -0,0 +1,291 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="en" datatype="plaintext" original="EXT:backend/Resources/Private/Language/locallang.xlf" date="2015-01-02T11:16:11Z" product-name="backend" target-language="de">
<header/>
<body>
<trans-unit id="onlineDocumentation" approved="yes">
<source>TYPO3 Online Documentation</source>
<target state="final">TYPO3 Online Dokumentation</target>
</trans-unit>
<trans-unit id="opensInANewWindow" approved="yes">
<source>opens in a new window</source>
<target state="final">öffnet sich in einem neuen Fenster</target>
</trans-unit>
<trans-unit id="no_modules_registered" approved="yes">
<source>No modules have been registered. Please contact your system administrator.</source>
<target state="final">Es wurden keine Module registriert. Bitte kontaktiere deinen Systemadministrator.</target>
</trans-unit>
<trans-unit id="show_references" approved="yes">
<source>Show references</source>
<target state="final">Referenzen anzeigen</target>
</trans-unit>
<trans-unit id="config.loginLogo" approved="yes">
<source>Logo: If set, this logo will be used instead of the TYPO3 logo above the login credential fields (e.g. fileadmin/images/login-logo.png or EXT:my_theme/Resources/Public/Images/login-logo.png or //domain.tld/login-logo.png).</source>
<target state="final">Logo: Wenn gesetzt, wird dieses Logo anstelle des TYPO3-Logos über dem Anmeldefeld gezeigt (bspw. fileadmin/images/login-logo.png oder EXT:my_theme/Resources/Public/Images/login-logo.png oder //domain.tld/login-logo.png).</target>
</trans-unit>
<trans-unit id="config.loginLogoAlt" approved="yes">
<source>Logo Alt-Text: If a custom logo is set, this text will be used as the alt attribute of the img tag.</source>
<target state="final">Logo Alt-Text: Wenn ein eigenes Logo gesetzt ist, wird dieser Text als alt-Attribut des img Tags verwendet.</target>
</trans-unit>
<trans-unit id="config.loginHighlightColor" approved="yes">
<source>Highlight Color: If set, this color will be used as highlight color in the login screen.</source>
<target state="final">Hervorhebungsfarbe: Wenn gesetzt, wird diese Farbe als Hervorhebungsfarbe im Anmeldebildschirm benutzt.</target>
</trans-unit>
<trans-unit id="config.loginBackgroundImage" approved="yes">
<source>Background Image: If set, this image will be used as background image for the login screen (e.g. fileadmin/images/my-background.jpg or EXT:my_theme/Resources/Public/Images/my-background.jpg or //domain.tld/my-background.png).</source>
<target state="final">Hintergrundbild: Wenn gesetzt, wird dieses Bild als Hintergrundbild für den Anmeldebildschirm genutzt (bspw. fileadmin/images/my-background.jpg oder EXT:my_theme/Resources/Public/Images/my-background.jpg oder //domain.tld/my-background.png).</target>
</trans-unit>
<trans-unit id="config.loginFootnote" approved="yes">
<source>Footnote: If set, this text will be displayed on the login screen to provide copyright information for the background image (e.g. background image © 2017 by John Doe) or a descriptive text.</source>
<target state="final">Fußnote: Wenn gesetzt, wird dieser Text auf dem Anmeldebildschirm angezeigt, um Copyright-Informationen oder eine Bildbeschreibung über das Hintergrundbild anzuzeigen (bspw. Hintergrundbild © 2017 von Max Mustermann).</target>
</trans-unit>
<trans-unit id="config.backendLogo" approved="yes">
<source>Logo: If set, this logo will be used instead of the TYPO3 logo in the TYPO3 backend in the left top corner (e.g. fileadmin/images/backend-logo.png or EXT:my_theme/Resources/Public/Images/backend-logo.png).</source>
<target state="final">Logo: Wenn gesetzt, wird dieses Logo anstelle des TYPO3-Logos im TYPO3-Backend in der oberen linken Ecke angezeigt (bspw. fileadmin/images/backend-logo.png oder EXT:my_theme/Resources/Public/Images/backend-logo.png).</target>
</trans-unit>
<trans-unit id="config.backendFavicon" approved="yes">
<source>Favicon: If set, this favicon will be used instead of the TYPO3 logo (e.g. EXT:my_theme/Resources/Public/Images/favicon.ico).</source>
<target state="final">Favicon: Wenn gesetzt, wird dieses Favicon anstelle des TYPO3-Logos genutzt (bspw. EXT:my_theme/Resources/Public/Images/favicon.ico).</target>
</trans-unit>
<trans-unit id="foldertreeview.noFolders.title" approved="yes">
<source>No folders available</source>
<target state="final">Keine Ordner verfügbar</target>
</trans-unit>
<trans-unit id="foldertreeview.noFolders.message" approved="yes">
<source>You do not have access to any folder. Please ask your administrator to fix access permissions for your account.</source>
<target state="final">Du hast keinen Zugriff auf irgendeinen Ordner. Bitte deinen Administrator, die Zugriffsberechtigungen für deinen Benutzer anzupassen.</target>
</trans-unit>
<trans-unit id="login.header" approved="yes">
<source>Login</source>
<target state="final">Anmeldung</target>
</trans-unit>
<trans-unit id="login.region.footnote" approved="yes">
<source>Footnote</source>
<target state="final">Fußnote</target>
</trans-unit>
<trans-unit id="login.link" approved="yes">
<source>Login with username and password</source>
<target state="final">Anmeldung mit Benutzernamen und Passwort</target>
</trans-unit>
<trans-unit id="login.username" approved="yes">
<source>Username</source>
<target state="final">Benutzername</target>
</trans-unit>
<trans-unit id="login.password" approved="yes">
<source>Password</source>
<target state="final">Passwort</target>
</trans-unit>
<trans-unit id="login.togglePassword" approved="yes">
<source>Toggle password visibility</source>
<target state="final">Passwort ein-/ausblenden</target>
</trans-unit>
<trans-unit id="login.password_forget" approved="yes">
<source>Forgot your password?</source>
<target state="final">Passwort vergessen?</target>
</trans-unit>
<trans-unit id="login.error.capslock" approved="yes">
<source>Attention: Caps lock enabled!</source>
<target state="final">Achtung: Feststelltaste aktiviert!</target>
</trans-unit>
<trans-unit id="login.error.capslockStatus" approved="yes">
<source>Caps lock enabled</source>
<target state="final">Feststelltaste aktiv</target>
</trans-unit>
<trans-unit id="login.news.header" approved="yes">
<source>System News</source>
<target state="final">Systemnachrichten</target>
</trans-unit>
<trans-unit id="login.news.date" approved="yes">
<source>Date</source>
<target state="final">Datum</target>
</trans-unit>
<trans-unit id="login.news.previous" approved="yes">
<source>Previous</source>
<target state="final">Vorherige</target>
</trans-unit>
<trans-unit id="login.news.next" approved="yes">
<source>Next</source>
<target state="final">Nächste</target>
</trans-unit>
<trans-unit id="login.navigation.loginProvider" approved="yes">
<source>Login Provider</source>
<target state="final">Anmeldeanbieter</target>
</trans-unit>
<trans-unit id="login.navigation.typo3" approved="yes">
<source>Further information about TYPO3</source>
<target state="final">Weitere Informationen über TYPO3</target>
</trans-unit>
<trans-unit id="login.error.message" approved="yes">
<source>Your login attempt did not succeed</source>
<target state="final">Ihr Anmeldeversuch war nicht erfolgreich</target>
</trans-unit>
<trans-unit id="login.error.description" approved="yes">
<source>Make sure to spell your username and password correctly, including upper/lowercase characters.</source>
<target state="final">Bitte stelle sicher, dass dein Benutzername und Passwort korrekt sind. Groß-/Kleinschreibung wird unterschieden.</target>
</trans-unit>
<trans-unit id="login.error.javascript" approved="yes">
<source>Please activate JavaScript!</source>
<target state="final">Bitte aktivieren Sie JavaScript!</target>
</trans-unit>
<trans-unit id="login.error.cookies" approved="yes">
<source>Please activate Cookies!</source>
<target state="final">Bitte aktivieren Sie Cookies!</target>
</trans-unit>
<trans-unit id="login.error.referrer" approved="yes">
<source>TYPO3 relies on HTTP referrers for security reasons in the backend. It seems your browser refused to send this information.</source>
<target state="final">Das TYPO3 Backend nutzt aus Gründen der Sicherheit den HTTP Referrer. Es scheint als ob der verwendete Browser diese Information nicht mitsendet.</target>
</trans-unit>
<trans-unit id="login.process" approved="yes">
<source>Verifying Login Data ...</source>
<target state="final">Anmeldedaten werden verifiziert...</target>
</trans-unit>
<trans-unit id="login.submit" approved="yes">
<source>Login</source>
<target state="final">Anmeldung</target>
</trans-unit>
<trans-unit id="login.copyrightLink" approved="yes">
<source>More about TYPO3</source>
<target state="final">Mehr über TYPO3</target>
</trans-unit>
<trans-unit id="login.typo3Logo" approved="yes">
<source>TYPO3 logo</source>
<target state="final">TYPO3-Logo</target>
</trans-unit>
<trans-unit id="login.donate" approved="yes">
<source>Donate</source>
<target state="final">Spenden</target>
</trans-unit>
<trans-unit id="formEngine.databaseRecordErrorInlineChildChild" approved="yes">
<source>The record with uid %2$s from table %1$s could not be retrieved from the database. This data inconsistency can occur if
a base record has been deleted but the intermediate record from table %3$s with uid %4$s still points to it. To fix
this situation, either delete the intermediate record, or recover the deleted record using the recycler module.
</source>
<target state="final">Der Datensatz mit Uid %2$s aus Tabelle %1$s konnte nicht aus der Datenbank abgerufen werden. Diese Inkonsistenz kann auftreten, wenn ein Basis-Datensatz gelöscht worden ist, während noch der Datensatz aus Tabelle %3$s mit Uid %4$s auf ihn verweist. Um dieses Problem zu beheben, löschen Sie entweder den verweisenden Datensatz oder stellen Sie den gelöschten Datensatz mit dem Papierkorb wieder her.</target>
</trans-unit>
<trans-unit id="modulemenu.label" approved="yes">
<source>Module Menu</source>
<target state="final">Modulmenü</target>
</trans-unit>
<trans-unit id="module.noAccess.title" approved="yes">
<source>No module access</source>
<target state="final">Kein Zugriff auf das Modul</target>
</trans-unit>
<trans-unit id="module.noAccess.message" approved="yes">
<source>You've been redirected to the "%s" module, because you currently can't access the "%s" module. You either don't have the necessary permissions or access is temporarily not possible, e.g. due to workspace restrictions.</source>
<target state="final">Du wurdest zum Modul "%s" weitergeleitet, da du derzeit nicht auf das Modul "%s" zugreifen kannst. Entweder hast du nicht die erforderlichen Berechtigungen oder der Zugriff ist vorübergehend nicht möglich, z.B. aufgrund von Arbeitsbereichsbeschränkungen.</target>
</trans-unit>
<trans-unit id="clearcache.title" approved="yes">
<source>Page cache</source>
<target state="final">Seitencache</target>
</trans-unit>
<trans-unit id="clearcache.message.success" approved="yes">
<source>Successfully cleared page cache</source>
<target state="final">Seitencache erfolgreich geleert</target>
</trans-unit>
<trans-unit id="clearcache.message.error" approved="yes">
<source>Page cache could not be cleared</source>
<target state="final">Seitencache konnte nicht geleert werden</target>
</trans-unit>
<trans-unit id="error.linkHandlerTitleMissing" approved="yes">
<source>[title missing]</source>
<target state="final">[Titel fehlt]</target>
</trans-unit>
<trans-unit id="create_folder.title" approved="yes">
<source>Create new folder</source>
<target state="final">Neuen Ordner erstellen</target>
</trans-unit>
<trans-unit id="create_folder.placeholder" approved="yes">
<source>Your new folder name</source>
<target state="final">Neuer Ordnername</target>
</trans-unit>
<trans-unit id="create_folder.submit" approved="yes">
<source>Create folder</source>
<target state="final">Ordner erstellen</target>
</trans-unit>
<trans-unit id="row.deletePlaceholder.title" approved="yes">
<source>The live pendant of this record will be deleted when this workspace record is published.</source>
<target state="final">Die Live-Version dieses Datensatzes wird gelöscht, sobald dieser Arbeitsbereichs-Datensatz veröffentlicht wird.</target>
</trans-unit>
<trans-unit id="shortcut.title" approved="yes">
<source>%s%s on page "%s" [%d]</source>
<target state="final">%s%s auf Seite "%s" [%d]</target>
</trans-unit>
<trans-unit id="liveSearch.databaseRecordProvider.filterLabel" approved="yes">
<source>Database records</source>
<target state="final">Datenbankeinträge</target>
</trans-unit>
<trans-unit id="liveSearch.databaseRecordProvider.typeLabel" approved="yes">
<source>Database record</source>
<target state="final">Datenbankeintrag</target>
</trans-unit>
<trans-unit id="liveSearch.pageRecordProvider.filterLabel" approved="yes">
<source>Pages</source>
<target state="final">Seiten</target>
</trans-unit>
<trans-unit id="liveSearch.pageRecordProvider.typeLabel" approved="yes">
<source>Page</source>
<target state="final">Seite</target>
</trans-unit>
<trans-unit id="liveSearch.backendModuleProvider.filterLabel" approved="yes">
<source>Backend modules</source>
<target state="final">Backend-Module</target>
</trans-unit>
<trans-unit id="liveSearch.backendModuleProvider.typeLabel" approved="yes">
<source>Backend module</source>
<target state="final">Backend-Modul</target>
</trans-unit>
<trans-unit id="resultItem.backendModuleProvider.openModule" approved="yes">
<source>Open module</source>
<target state="final">Modul öffnen</target>
</trans-unit>
<trans-unit id="moduleMenu.dropdown.label" approved="yes">
<source>Module action</source>
<target state="final">Modul-Aktion</target>
</trans-unit>
<trans-unit id="pagelayout.moduleMenu.dropdown.label" approved="yes">
<source>Display mode</source>
<target state="final">Anzeigemodus</target>
</trans-unit>
<trans-unit id="editdocument.moduleMenu.dropdown.label" approved="yes">
<source>Record language</source>
<target state="final">Sprache des Datensatzes</target>
</trans-unit>
<trans-unit id="theme" approved="yes">
<source>Theme</source>
<target state="final">Stil</target>
</trans-unit>
<trans-unit id="theme.classic" approved="yes">
<source>Classic</source>
<target state="final">Klassisch</target>
</trans-unit>
<trans-unit id="theme.modern" approved="yes">
<source>Modern</source>
<target state="final">Modern</target>
</trans-unit>
<trans-unit id="colorScheme" approved="yes">
<source>Color scheme</source>
<target state="final">Farbschema</target>
</trans-unit>
<trans-unit id="toggleColorScheme" approved="yes">
<source>Toggle color scheme between light and dark mode</source>
<target state="final">Umschalten des Farbschemas zwischen hellem und dunklem Modus</target>
</trans-unit>
<trans-unit id="colorSchemeToggleDisabled" approved="yes">
<source>Due to your current accessibility settings, the color scheme cannot be changed.</source>
<target state="final">Aufgrund deiner aktuellen Einstellungen für die Barrierefreiheit kann das Farbschema nicht geändert werden.</target>
</trans-unit>
<trans-unit id="colorScheme.auto" approved="yes">
<source>Auto detect</source>
<target state="final">Automatisch erkennen</target>
</trans-unit>
<trans-unit id="colorScheme.light" approved="yes">
<source>Light mode</source>
<target state="final">Heller Modus</target>
</trans-unit>
<trans-unit id="colorScheme.dark" approved="yes">
<source>Dark mode</source>
<target state="final">Dunkler Modus</target>
</trans-unit>
</body>
</file>
</xliff>
@@ -0,0 +1,268 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="en" datatype="plaintext" original="EXT:backend/Resources/Private/Language/locallang_alt_doc.xlf" date="2011-10-17T20:22:33Z" product-name="lang" target-language="de">
<header/>
<body>
<trans-unit id="deleteItem" approved="yes">
<source>Delete</source>
<target state="final">Löschen</target>
</trans-unit>
<trans-unit id="deleteWarning" approved="yes">
<source>Are you sure you want to delete this record?</source>
<target state="final">Diesen Datensatz tatsächlich löschen?</target>
</trans-unit>
<trans-unit id="undoLastChange" approved="yes">
<source>Undo/Redo last change (%s ago)</source>
<target state="final">Letzte Änderung rückgängig/wiederherstellen (%s zurück)</target>
</trans-unit>
<trans-unit id="recordHistory" approved="yes">
<source>View record change history</source>
<target state="final">Änderungsverlauf des Datensatzes anzeigen</target>
</trans-unit>
<trans-unit id="editWholeRecord" approved="yes">
<source>Edit whole record</source>
<target state="final">Kompletten Datensatz bearbeiten</target>
</trans-unit>
<trans-unit id="openDocs" approved="yes">
<source>OPEN DOCUMENTS</source>
<target state="final">GEÖFFNETE DOKUMENTE</target>
</trans-unit>
<trans-unit id="noDocuments" approved="yes">
<source>No open documents</source>
<target state="final">Keine geöffneten Dokumente</target>
</trans-unit>
<trans-unit id="noDocuments_msg" approved="yes">
<source>There are no open documents available to edit.</source>
<target state="final">Es sind keine Dokumente zur Bearbeitung geöffnet.</target>
</trans-unit>
<trans-unit id="noDocuments_msg2" approved="yes">
<source>You can go to %s to find the page or the record you wish to edit.</source>
<target state="final">Rufe %s auf, um die Seite oder den Datensatz zu finden, den du bearbeiten möchtest.</target>
</trans-unit>
<trans-unit id="noDocuments_msg3" approved="yes">
<source>You can select one of your most recently edited records from this list</source>
<target state="final">Aus dieser Liste können die zuletzt bearbeiteten Datensätze ausgewählt werden</target>
</trans-unit>
<trans-unit id="noDocuments_pagemodule" approved="yes">
<source>the Web&gt;Page module</source>
<target state="final">das Modul Web&gt;Seite</target>
</trans-unit>
<trans-unit id="noDocuments_OR" approved="yes">
<source>or</source>
<target state="final">oder</target>
</trans-unit>
<trans-unit id="noDocuments_listmodule" approved="yes">
<source>the Web&gt;List module</source>
<target state="final">das Modul Web&gt;Liste</target>
</trans-unit>
<trans-unit id="noEditForm" approved="yes">
<source>Edit form could not be loaded</source>
<target state="final">Das Bearbeitungsformular konnte nicht geladen werden</target>
</trans-unit>
<trans-unit id="noEditForm.message" approved="yes">
<source>The edit form could not be loaded for the requested records. This might be due to insufficient permissions.</source>
<target state="final">Das Bearbeitungsformular konnte für die angeforderten Datensätze nicht geladen werden. Dies könnte auf unzureichende Berechtigungen zurückzuführen sein.</target>
</trans-unit>
<trans-unit id="noFieldsEditForm" approved="yes">
<source>No fields to edit</source>
<target state="final">Keine Felder zum Bearbeiten</target>
</trans-unit>
<trans-unit id="noFieldsEditForm.message" approved="yes">
<source>There are no editable fields available for the requested record. This might be due to insufficient permissions or a configuration mismatch.</source>
<target state="final">Es sind keine bearbeitbaren Felder für den angeforderten Datensatz verfügbar. Dies kann an unzureichenden Berechtigungen oder einer fehlerhaften Konfiguration liegen.</target>
</trans-unit>
<trans-unit id="buttons.confirm.duplicate_record_changed.cancel" approved="yes">
<source>Cancel</source>
<target state="final">Abbrechen</target>
</trans-unit>
<trans-unit id="button.confirm.duplicate_record_changed.no" approved="yes">
<source>No, just duplicate the original</source>
<target state="final">Nein, nur das Original duplizieren</target>
</trans-unit>
<trans-unit id="buttons.confirm.duplicate_record_changed.yes" approved="yes">
<source>Yes, save and duplicate this record</source>
<target state="final">Ja, speichern und diesen Datensatz duplizieren</target>
</trans-unit>
<trans-unit id="buttons.confirm.close_without_save.yes" approved="yes">
<source>Yes, discard my changes</source>
<target state="final">Ja, meine Änderungen verwerfen</target>
</trans-unit>
<trans-unit id="buttons.confirm.close_without_save.no" approved="yes">
<source>No, I will continue editing</source>
<target state="final">Nein, ich werde mit dem Bearbeiten fortfahren</target>
</trans-unit>
<trans-unit id="buttons.confirm.save_and_close" approved="yes">
<source>Save and close</source>
<target state="final">Speichern und schließen</target>
</trans-unit>
<trans-unit id="label.confirm.duplicate_record_changed.title" approved="yes">
<source>Do you want to save before duplicating this record?</source>
<target state="final">Speichern bevor dieser Datensatz dupliziert wird?</target>
</trans-unit>
<trans-unit id="label.confirm.duplicate_record_changed.content" approved="yes">
<source>You currently have unsaved changes. Do you want to save your changes before duplicating this record?</source>
<target state="final">Es gibt ungespeicherte Änderungen. Möchtest du deine Änderungen speichern bevor der Datensatz dupliziert wird?</target>
</trans-unit>
<trans-unit id="label.confirm.new_record_changed.title" approved="yes">
<source>Do you want to save before adding?</source>
<target state="final">Speichern vor dem Hinzufügen?</target>
</trans-unit>
<trans-unit id="label.confirm.new_record_changed.content" approved="yes">
<source>You need to save your changes before creating a new record. Do you want to save and create now?</source>
<target state="final">Bevor du einen neuen Datensatz erstellst, musst du deine Änderungen speichern. Möchtest du speichern und den neuen Datensatz erstellen?</target>
</trans-unit>
<trans-unit id="buttons.confirm.new_record_changed.cancel" approved="yes">
<source>Cancel</source>
<target state="final">Abbrechen</target>
</trans-unit>
<trans-unit id="buttons.confirm.new_record_changed.no" approved="yes">
<source>No, just add</source>
<target state="final">Nein, nur hinzufügen</target>
</trans-unit>
<trans-unit id="buttons.confirm.new_record_changed.yes" approved="yes">
<source>Yes, save and create now</source>
<target state="final">Ja, jetzt speichern und erstellen</target>
</trans-unit>
<trans-unit id="label.confirm.view_record_changed.title" approved="yes">
<source>Do you want to save before viewing?</source>
<target state="final">Speichern vor dem Anzeigen?</target>
</trans-unit>
<trans-unit id="label.confirm.view_record_changed.content" approved="yes">
<source>You currently have unsaved changes. You can either discard these changes or save and view them.</source>
<target state="final">Es gibt ungespeicherte Änderungen. Du kannst diese Änderungen entweder verwerfen oder speichern und anzeigen lassen.</target>
</trans-unit>
<trans-unit id="label.confirm.view_record_changed.invalid_form" approved="yes">
<source>The form appears to be invalid, therefore "Save changes and view" is not available.</source>
<target state="final">Das Formular scheint ungültig zu sein, daher ist "Änderungen speichern und anzeigen" nicht verfügbar.</target>
</trans-unit>
<trans-unit id="label.confirm.view_record_changed.content.is-new-page" approved="yes">
<source>You need to save your changes before viewing the page. Do you want to save and view them now?</source>
<target state="final">Du musst deine Änderungen speichern, bevor du die Seite anzeigen kannst. Möchtest du speichern und die Seite anzeigen?</target>
</trans-unit>
<trans-unit id="buttons.confirm.view_record_changed.cancel" approved="yes">
<source>Cancel</source>
<target state="final">Abbrechen</target>
</trans-unit>
<trans-unit id="buttons.confirm.view_record_changed.no-save" approved="yes">
<source>View without changes</source>
<target state="final">Ohne Änderungen anzeigen</target>
</trans-unit>
<trans-unit id="buttons.confirm.view_record_changed.save" approved="yes">
<source>Save changes and view</source>
<target state="final">Änderungen speichern und anzeigen</target>
</trans-unit>
<trans-unit id="label.confirm.close_without_save.title" approved="yes">
<source>Do you want to close without saving?</source>
<target state="final">Ohne Speichern schließen?</target>
</trans-unit>
<trans-unit id="label.confirm.close_without_save.content" approved="yes">
<source>You currently have unsaved changes. Are you sure you want to discard these changes?</source>
<target state="final">Es gibt ungespeicherte Änderungen. Diese Änderungen tatsächlich verwerfen?</target>
</trans-unit>
<trans-unit id="buttons.confirm.delete_file.no" approved="yes">
<source>Cancel</source>
<target state="final">Abbrechen</target>
</trans-unit>
<trans-unit id="buttons.confirm.delete_file.yes" approved="yes">
<source>Yes, delete this file</source>
<target state="final">Ja, diese Datei löschen</target>
</trans-unit>
<trans-unit id="buttons.confirm.delete_folder.yes" approved="yes">
<source>Yes, delete this folder</source>
<target state="final">Ja, diesen Ordner löschen</target>
</trans-unit>
<trans-unit id="buttons.confirm.delete_record.no" approved="yes">
<source>Cancel</source>
<target state="final">Abbrechen</target>
</trans-unit>
<trans-unit id="buttons.confirm.delete_record.yes" approved="yes">
<source>Delete record (!)</source>
<target state="final">Datensatz löschen (!)</target>
</trans-unit>
<trans-unit id="label.confirm.delete_record.title" approved="yes">
<source>Delete this record?</source>
<target state="final">Diesen Datensatz tatsächlich löschen?</target>
</trans-unit>
<trans-unit id="label.confirm.delete_record.content" approved="yes">
<source>Are you sure you want to delete the record '%s'?</source>
<target state="final">Bist du sicher, dass du den Datensatz '%s ' löschen möchtest?</target>
</trans-unit>
<trans-unit id="buttons.confirm.delete_elements.no" approved="yes">
<source>Cancel</source>
<target state="final">Abbrechen</target>
</trans-unit>
<trans-unit id="buttons.confirm.delete_elements.yes" approved="yes">
<source>Yes, delete these elements</source>
<target state="final">Ja, diese Elemente löschen</target>
</trans-unit>
<trans-unit id="label.alert.save_with_error.title" approved="yes">
<source>You have errors in your form!</source>
<target state="final">Du hast Fehler in deinem Formular!</target>
</trans-unit>
<trans-unit id="label.alert.save_with_error.content" approved="yes">
<source>Please check the form, there is at least one error in your form.</source>
<target state="final">Bitte überprüfe das Formular, es gibt mindestens einen Fehler in deinem Formular.</target>
</trans-unit>
<trans-unit id="buttons.alert.save_with_error.ok" approved="yes">
<source>OK</source>
<target state="final">OK</target>
</trans-unit>
<trans-unit id="buttons.reviewFailedValidationFields" approved="yes">
<source>Review fields with failed validations</source>
<target state="final">Felder mit fehlgeschlagenen Validierungen überprüfen</target>
</trans-unit>
<trans-unit id="buttons.pageTsConfig" approved="yes">
<source>PageTS Config</source>
<target state="final">PageTS-Konfiguration</target>
</trans-unit>
<trans-unit id="notification.record_saved.title.singular" approved="yes">
<source>Record saved</source>
<target state="final">Datensatz gespeichert</target>
</trans-unit>
<trans-unit id="notification.record_saved.title.plural" approved="yes">
<source>Records saved</source>
<target state="final">Datensätze gespeichert</target>
</trans-unit>
<trans-unit id="notification.record_saved.message" approved="yes">
<source>Record "%s" has been successfully saved.</source>
<target state="final">Datensatz ''%s'' wurde erfolgreich gespeichert.</target>
</trans-unit>
<trans-unit id="notification.mass_saving.message" approved="yes">
<source>%s records have been successfully saved.</source>
<target state="final">%s Datensätze erfolgreich gespeichert.</target>
</trans-unit>
<trans-unit id="search.find_record" approved="yes">
<source>Find records</source>
<target state="final">Finde Datensätze</target>
</trans-unit>
<trans-unit id="search.no_records_found" approved="yes">
<source>No records found</source>
<target state="final">Keine Datensätze gefunden</target>
</trans-unit>
<trans-unit id="flexform.section.delete.title" approved="yes">
<source>Delete this container?</source>
<target state="final">Diesen Container löschen?</target>
</trans-unit>
<trans-unit id="flexform.section.delete.message" approved="yes">
<source>Are you sure you want to delete this container?</source>
<target state="final">Möchtest du diesen Container wirklich löschen?</target>
</trans-unit>
<trans-unit id="tcatree.findItem" approved="yes">
<source>Filter by item</source>
<target state="final">Nach Eintrag filtern</target>
</trans-unit>
<trans-unit id="tcatree.expandAll" approved="yes">
<source>Expand all</source>
<target state="final">Alle anzeigen</target>
</trans-unit>
<trans-unit id="tcatree.collapseAll" approved="yes">
<source>Collapse all</source>
<target state="final">Alle einklappen</target>
</trans-unit>
<trans-unit id="tcatree.toggleHideUnchecked" approved="yes">
<source>Toggle hide unchecked</source>
<target state="final">Nicht selektierte verbergen / anzeigen</target>
</trans-unit>
</body>
</file>
</xliff>
@@ -0,0 +1,224 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="en" datatype="plaintext" original="EXT:backend/Resources/Private/Language/locallang_browse_links.xlf" date="2011-10-17T20:22:33Z" product-name="lang" target-language="de">
<header/>
<body>
<trans-unit id="linkBrowser" approved="yes">
<source>Link Browser</source>
<target state="final">Link Browser</target>
</trans-unit>
<trans-unit id="openLinkWizard" approved="yes">
<source>Open link wizard</source>
<target state="final">Link-Assistent öffnen</target>
</trans-unit>
<trans-unit id="removeLink" approved="yes">
<source>Remove link</source>
<target state="final">Link entfernen</target>
</trans-unit>
<trans-unit id="uploadImage" approved="yes">
<source>Upload Image</source>
<target state="final">Bild hochladen</target>
</trans-unit>
<trans-unit id="update" approved="yes">
<source>Update</source>
<target state="final">Aktualisieren</target>
</trans-unit>
<trans-unit id="path" approved="yes">
<source>Path</source>
<target state="final">Pfad</target>
</trans-unit>
<trans-unit id="page" approved="yes">
<source>Page</source>
<target state="final">Seite</target>
</trans-unit>
<trans-unit id="file" approved="yes">
<source>File</source>
<target state="final">Datei</target>
</trans-unit>
<trans-unit id="folder" approved="yes">
<source>Folder</source>
<target state="final">Ordner</target>
</trans-unit>
<trans-unit id="extUrl" approved="yes">
<source>External URL</source>
<target state="final">Externe URL</target>
</trans-unit>
<trans-unit id="email" approved="yes">
<source>Email</source>
<target state="final">E-Mail</target>
</trans-unit>
<trans-unit id="email.subject" approved="yes">
<source>Subject</source>
<target state="final">Betreff</target>
</trans-unit>
<trans-unit id="email.cc" approved="yes">
<source>CC</source>
<target state="final">CC</target>
</trans-unit>
<trans-unit id="email.bcc" approved="yes">
<source>BCC</source>
<target state="final">BCC</target>
</trans-unit>
<trans-unit id="email.body" approved="yes">
<source>Body</source>
<target state="final">Inhalt</target>
</trans-unit>
<trans-unit id="telephone" approved="yes">
<source>Telephone</source>
<target state="final">Telefon</target>
</trans-unit>
<trans-unit id="special" approved="yes">
<source>Special</source>
<target state="final">Spezial</target>
</trans-unit>
<trans-unit id="folderTree" approved="yes">
<source>Folder Tree</source>
<target state="final">Verzeichnisbaum</target>
</trans-unit>
<trans-unit id="files" approved="yes">
<source>Files</source>
<target state="final">Dateien</target>
</trans-unit>
<trans-unit id="folders" approved="yes">
<source>Folders</source>
<target state="final">Ordner</target>
</trans-unit>
<trans-unit id="target" approved="yes">
<source>Target</source>
<target state="final">Ziel</target>
</trans-unit>
<trans-unit id="linkRelationship" approved="yes">
<source>Relationship</source>
<target state="final">Beziehung</target>
</trans-unit>
<trans-unit id="class" approved="yes">
<source>CSS-Class</source>
<target state="final">CSS-Klasse</target>
</trans-unit>
<trans-unit id="title" approved="yes">
<source>Title</source>
<target state="final">Titel</target>
</trans-unit>
<trans-unit id="params" approved="yes">
<source>Additional link parameters</source>
<target state="final">Zusätzliche Link-Parameter</target>
</trans-unit>
<trans-unit id="newWindow" approved="yes">
<source>New window</source>
<target state="final">Neues Fenster</target>
</trans-unit>
<trans-unit id="top" approved="yes">
<source>Top</source>
<target state="final">Anfang</target>
</trans-unit>
<trans-unit id="none" approved="yes">
<source>None - new link!</source>
<target state="final">Keiner - neuer Link!</target>
</trans-unit>
<trans-unit id="pageTree" approved="yes">
<source>Page tree</source>
<target state="final">Seitenbaum</target>
</trans-unit>
<trans-unit id="contentElements" approved="yes">
<source>Content elements</source>
<target state="final">Inhaltselemente</target>
</trans-unit>
<trans-unit id="selectRecords" approved="yes">
<source>Select Records</source>
<target state="final">Datensätze auswählen</target>
</trans-unit>
<trans-unit id="addToList" approved="yes">
<source>Add to list...</source>
<target state="final">Zur Liste hinzufügen...</target>
</trans-unit>
<trans-unit id="info" approved="yes">
<source>Info</source>
<target state="final">Info</target>
</trans-unit>
<trans-unit id="emailAddress" approved="yes">
<source>Email address</source>
<target state="final">E-Mail-Adresse</target>
</trans-unit>
<trans-unit id="telephoneNumber" approved="yes">
<source>Telephone number</source>
<target state="final">Telefonnummer</target>
</trans-unit>
<trans-unit id="setLink" approved="yes">
<source>Set Link</source>
<target state="final">Link setzen</target>
</trans-unit>
<trans-unit id="linkTo" approved="yes">
<source>Link to %s</source>
<target state="final">Link zu %s</target>
</trans-unit>
<trans-unit id="urlPlaceholder" translate="no" approved="yes">
<source>https://...</source>
<target state="final">https://...</target>
</trans-unit>
<trans-unit id="clickToRedrawFullSize" approved="yes">
<source>Image is larger than shown here! Click to redraw page with full sized images.</source>
<target state="final">Bild ist größer als hier angezeigt! Klicken, um Seite mit Bildern in voller Größe neu zu laden.</target>
</trans-unit>
<trans-unit id="findDragDrop" approved="yes">
<source>Find and click on your image then drag it into the editor in the main window!</source>
<target state="final">Suchen und klicken Sie auf Ihr Bild, dann ziehen Sie es in den Editor im Hauptfenster!</target>
</trans-unit>
<trans-unit id="noWebFolder" approved="yes">
<source>You cannot drag images from this folder (yellow) because it is internal on the server.</source>
<target state="final">Sie können keine Bilder aus diesem Ordner (gelb) ziehen, da diese intern auf dem Server liegen.</target>
</trans-unit>
<trans-unit id="currentLink" approved="yes">
<source>Current Link</source>
<target state="final">Aktueller Link</target>
</trans-unit>
<trans-unit id="invalidChar" approved="yes">
<source>ERROR: Invalid character found in file path (%s). Cannot add the file!</source>
<target state="final">FEHLER: Ungültiges Zeichen im Dateipfad gefunden (%s). Datei kann nicht hinzugefügt werden!</target>
</trans-unit>
<trans-unit id="toggleSelection" approved="yes">
<source>Toggle selection</source>
<target state="final">Auswahl umkehren</target>
</trans-unit>
<trans-unit id="importSelection" approved="yes">
<source>Import selection</source>
<target state="final">Auswahl importieren</target>
</trans-unit>
<trans-unit id="recordSelector" approved="yes">
<source>Record selector</source>
<target state="final">Datensatzauswahl</target>
</trans-unit>
<trans-unit id="fileSelector" approved="yes">
<source>File selector</source>
<target state="final">Dateiauswahl</target>
</trans-unit>
<trans-unit id="folderSelector" approved="yes">
<source>Folder selector</source>
<target state="final">Ordnerauswahl</target>
</trans-unit>
<trans-unit id="createFolder" approved="yes">
<source>Create new folder</source>
<target state="final">Neuen Ordner erstellen</target>
</trans-unit>
<trans-unit id="page_id" approved="yes">
<source>Page ID</source>
<target state="final">Seiten-ID</target>
</trans-unit>
<trans-unit id="displayThumbs" approved="yes">
<source>Display thumbnails</source>
<target state="final">Miniaturansichten anzeigen</target>
</trans-unit>
<trans-unit id="no_files" approved="yes">
<source>No files found in %s</source>
<target state="final">Keine Dateien in %s gefunden</target>
</trans-unit>
<trans-unit id="no_files_search" approved="yes">
<source>No files found in %s for "%s"</source>
<target state="final">Keine Dateien in %s für "%s " gefunden</target>
</trans-unit>
<trans-unit id="recordNotFound" approved="yes">
<source>Record not found</source>
<target state="final">Datensatz nicht gefunden</target>
</trans-unit>
</body>
</file>
</xliff>
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="en" datatype="plaintext" original="EXT:backend/Resources/Private/Language/locallang_codeeditor.xlf" date="2023-11-20T10:56:42Z" product-name="backend" target-language="de">
<header/>
<body>
<trans-unit id="pageIDInteger" approved="yes">
<source>Syntax error: Parameter pageID must be a valid integer.</source>
<target state="final">Syntaxfehler: Der Parameter pageID muss vom Typ Integer sein.</target>
</trans-unit>
<trans-unit id="noPermission" approved="yes">
<source>Access denied: No permission to template records.</source>
<target state="final">Zugriff verweigert: Keine Zugriffsrechte auf Template-Datensätze vorhanden.</target>
</trans-unit>
</body>
</file>
</xliff>
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="en" datatype="plaintext" original="EXT:backend/Resources/Private/Language/locallang_column_selector.xlf" date="2021-08-25T02:11:02Z" product-name="backend" target-language="de">
<header/>
<body>
<trans-unit id="showColumns" approved="yes">
<source>Show columns</source>
<target state="final">Spalten anzeigen</target>
</trans-unit>
<trans-unit id="showColumnsSelection" approved="yes">
<source>Show columns for %s</source>
<target state="final">Spalten für %s anzeigen</target>
</trans-unit>
<trans-unit id="updateColumnView" approved="yes">
<source>Update</source>
<target state="final">Aktualisieren</target>
</trans-unit>
<trans-unit id="updateColumnView.nothingUpdated" approved="yes">
<source>No columns were updated</source>
<target state="final">Keine Spalten wurden aktualisiert</target>
</trans-unit>
<trans-unit id="updateColumnView.error" approved="yes">
<source>Could not update columns</source>
<target state="final">Spalten konnten nicht aktualisiert werden</target>
</trans-unit>
<trans-unit id="columnsFilter" approved="yes">
<source>Filter by:</source>
<target state="final">Filtern nach:</target>
</trans-unit>
</body>
</file>
</xliff>
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="en" datatype="plaintext" original="EXT:backend/Resources/Private/Language/locallang_copytoclipboard.xlf" date="2021-06-01T12:43:12Z" product-name="backend" target-language="de">
<header/>
<body>
<trans-unit id="copyToClipboard.title" approved="yes">
<source>Copy %s to clipboard</source>
<target state="final">%s in die Zwischenablage kopieren</target>
</trans-unit>
<trans-unit id="copyToClipboard.success" approved="yes">
<source>Copied to clipboard</source>
<target state="final">In die Zwischenablage kopiert</target>
</trans-unit>
<trans-unit id="copyToClipboard.error" approved="yes">
<source>Could not be copied to clipboard</source>
<target state="final">Fehler beim Kopieren in die Zwischenablage</target>
</trans-unit>
</body>
</file>
</xliff>
@@ -0,0 +1,250 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="en" datatype="plaintext" original="EXT:backend/Resources/Private/Language/locallang_db_new_content_el.xlf" date="2011-10-17T20:22:32Z" product-name="cms" target-language="de">
<header>
<note>@deprecated will be removed in TYPO3 v14.0</note>
</header>
<body>
<trans-unit id="sel1" approved="yes">
<source>Please select the type of page content you wish to create</source>
<target state="final">Wähle bitte den Seiteninhaltstyp aus, den du erstellen willst:</target>
</trans-unit>
<trans-unit id="sel2" approved="yes">
<source>Now, click the position where you wish to place the element on the page</source>
<target state="final">Wähle als nächstes die Position aus, an der das Element auf der Seite positioniert werden soll:</target>
</trans-unit>
<trans-unit id="common" approved="yes">
<source>Typical page content</source>
<target state="final">Typischer Seiteninhalt</target>
</trans-unit>
<trans-unit id="common_headerOnly_title" approved="yes">
<source>Header Only</source>
<target state="final">Nur Überschrift</target>
</trans-unit>
<trans-unit id="common_headerOnly_description" approved="yes">
<source>Adds a header only.</source>
<target state="final">Eine Überschrift.</target>
</trans-unit>
<trans-unit id="common_regularText_title" approved="yes">
<source>Regular Text Element</source>
<target state="final">Text</target>
</trans-unit>
<trans-unit id="common_regularText_description" approved="yes">
<source>A regular text element with header and bodytext fields.</source>
<target state="final">Ein normales Textelement mit Überschrift und Fließtext.</target>
</trans-unit>
<trans-unit id="common_textImage_title" approved="yes">
<source>Text &amp; Images</source>
<target state="final">Text &amp; Bilder</target>
</trans-unit>
<trans-unit id="common_textImage_description" approved="yes">
<source>Any number of images wrapped right around a regular text element.</source>
<target state="final">Eine beliebige Anzahl von Bildern mit umfließendem Text.</target>
</trans-unit>
<trans-unit id="common_textMedia_title" approved="yes">
<source>Text &amp; Media</source>
<target state="final">Text &amp; Medien</target>
</trans-unit>
<trans-unit id="common_textMedia_description" approved="yes">
<source>Any number of media wrapped right around a regular text element.</source>
<target state="final">Eine beliebige Anzahl von Medien mit umfließendem Text.</target>
</trans-unit>
<trans-unit id="common_imagesOnly_title" approved="yes">
<source>Images Only</source>
<target state="final">Nur Bilder</target>
</trans-unit>
<trans-unit id="common_imagesOnly_description" approved="yes">
<source>Any number of images aligned in columns and rows with a caption.</source>
<target state="final">Eine beliebige Anzahl von in Zeilen und Spalten angeordneten Bildern mit Beschriftung.</target>
</trans-unit>
<trans-unit id="common_bulletList_title" approved="yes">
<source>Bullet List</source>
<target state="final">Aufzählung</target>
</trans-unit>
<trans-unit id="common_bulletList_description" approved="yes">
<source>A single bullet list.</source>
<target state="final">Eine einzelne Aufzählung.</target>
</trans-unit>
<trans-unit id="common_table_title" approved="yes">
<source>Table</source>
<target state="final">Tabelle</target>
</trans-unit>
<trans-unit id="common_table_description" approved="yes">
<source>A simple table.</source>
<target state="final">Eine einfache Tabelle.</target>
</trans-unit>
<trans-unit id="menu" approved="yes">
<source>Menu</source>
<target state="final">Menü</target>
</trans-unit>
<trans-unit id="menu_abstract.title" approved="yes">
<source>Abstracts</source>
<target state="final">Zusammenfassungen</target>
</trans-unit>
<trans-unit id="menu_abstract.description" approved="yes">
<source>Menu of subpages of selected pages including abstracts</source>
<target state="final">Menü der Unterseiten der ausgewählten Seite inklusive Zusammenfassungen</target>
</trans-unit>
<trans-unit id="menu_categorized_content.title" approved="yes">
<source>Categorized content</source>
<target state="final">Kategorisierter Inhalt</target>
</trans-unit>
<trans-unit id="menu_categorized_content.description" approved="yes">
<source>Content elements for selected categories</source>
<target state="final">Inhaltselemente der ausgewählten Kategorien</target>
</trans-unit>
<trans-unit id="menu_categorized_pages.title" approved="yes">
<source>Categorized pages</source>
<target state="final">Kategorisierte Seiten</target>
</trans-unit>
<trans-unit id="menu_pages.title" approved="yes">
<source>Pages</source>
<target state="final">Seiten</target>
</trans-unit>
<trans-unit id="menu_pages.description" approved="yes">
<source>Menu of selected pages</source>
<target state="final">Menü der ausgewählten Seiten</target>
</trans-unit>
<trans-unit id="menu_subpages.title" approved="yes">
<source>Subpages</source>
<target state="final">Unterseiten</target>
</trans-unit>
<trans-unit id="menu_subpages.description" approved="yes">
<source>Menu of subpages of selected pages</source>
<target state="final">Menü der Unterseiten der ausgewählten Seiten</target>
</trans-unit>
<trans-unit id="menu_categorized_pages.description" approved="yes">
<source>Pages for selected categories</source>
<target state="final">Seiten für ausgewählte Kategorien</target>
</trans-unit>
<trans-unit id="menu_recently_updated.title" approved="yes">
<source>Recently updated pages</source>
<target state="final">Neulich aktualisierte Seiten</target>
</trans-unit>
<trans-unit id="menu_recently_updated.description" approved="yes">
<source>Menu of recently updated pages</source>
<target state="final">Menü der neulich-aktualisierten Seiten</target>
</trans-unit>
<trans-unit id="menu_related_pages.title" approved="yes">
<source>Related pages</source>
<target state="final">Verwandte Seiten</target>
</trans-unit>
<trans-unit id="menu_related_pages.description" approved="yes">
<source>Menu of related pages based on keywords</source>
<target state="final">Menü der verwandten Seiten basierend auf Stichworten</target>
</trans-unit>
<trans-unit id="menu_section.title" approved="yes">
<source>Section index</source>
<target state="final">Sektionsindex</target>
</trans-unit>
<trans-unit id="menu_section.description" approved="yes">
<source>Page content marked for section menus</source>
<target state="final">Seiteninhalt, der für Abschnittsmenüs markiert ist</target>
</trans-unit>
<trans-unit id="menu_section_pages.title" approved="yes">
<source>Section index of subpages from selected pages</source>
<target state="final">Menü der Unterseiten von ausgewählten Seiten</target>
</trans-unit>
<trans-unit id="menu_section_pages.description" approved="yes">
<source>Menu of subpages of selected pages including sections</source>
<target state="final">Menü der Unterseiten der ausgewählten Seiten inklusive Seiteninhalt</target>
</trans-unit>
<trans-unit id="menu_sitemap.title" approved="yes">
<source>Sitemap</source>
<target state="final">Sitemap</target>
</trans-unit>
<trans-unit id="menu_sitemap.description" approved="yes">
<source>Expanded menu of all subpages of the current site</source>
<target state="final">Erweitertes Menü aller Unterseiten der aktuellen Seite</target>
</trans-unit>
<trans-unit id="menu_sitemap_pages.title" approved="yes">
<source>Sitemaps of selected pages</source>
<target state="final">Sitemaps der ausgewählten Seiten</target>
</trans-unit>
<trans-unit id="menu_sitemap_pages.description" approved="yes">
<source>Expanded menu of all subpages for selected pages</source>
<target state="final">Menü aller Seiten und Unterseiten der ausgewählten Seiten ausklappen</target>
</trans-unit>
<trans-unit id="special" approved="yes">
<source>Special elements</source>
<target state="final">Besondere Elemente</target>
</trans-unit>
<trans-unit id="special_filelinks_title" approved="yes">
<source>File Links</source>
<target state="final">Dateilinks</target>
</trans-unit>
<trans-unit id="special_filelinks_description" approved="yes">
<source>Makes a list of files for download.</source>
<target state="final">Erzeugt eine Liste mit Dateien zum Herunterladen.</target>
</trans-unit>
<trans-unit id="special_sitemap_title" approved="yes">
<source>Sitemap</source>
<target state="final">Sitemap</target>
</trans-unit>
<trans-unit id="special_menus_title" approved="yes">
<source>Special Menus</source>
<target state="final">Spezial-Menüs</target>
</trans-unit>
<trans-unit id="special_menus_description" approved="yes">
<source>Creates a menu of pages, sitemap or other special menus.</source>
<target state="final">Erstellt ein Seitenmenü, eine Sitemap oder andere Spezial-Menüs.</target>
</trans-unit>
<trans-unit id="special_plainHTML_title" approved="yes">
<source>Plain HTML</source>
<target state="final">Reines HTML</target>
</trans-unit>
<trans-unit id="special_plainHTML_description" approved="yes">
<source>With this element you can insert raw HTML code on the page.</source>
<target state="final">Mit diesem Element kann reiner HTML-Quelltext auf der Seite eingefügt werden.</target>
</trans-unit>
<trans-unit id="special_divider_title" approved="yes">
<source>Divider</source>
<target state="final">Trenner</target>
</trans-unit>
<trans-unit id="special_divider_description" approved="yes">
<source>This element inserts a visual divider, which is by default a horizontal line.</source>
<target state="final">Mit diesem Element wird ein sichtbarer Trenner eingefügt, standardmäßig eine horizontale Linie.</target>
</trans-unit>
<trans-unit id="special_shortcut_title" approved="yes">
<source>Insert records</source>
<target state="final">Datensätze einfügen</target>
</trans-unit>
<trans-unit id="special_shortcut_description" approved="yes">
<source>With this element you can embed other content elements.</source>
<target state="final">Mit diesem Element werden andere Inhaltselemente eingebunden.</target>
</trans-unit>
<trans-unit id="forms" approved="yes">
<source>Form elements</source>
<target state="final">Formulare</target>
</trans-unit>
<trans-unit id="forms_mail_title" approved="yes">
<source>Mail Form</source>
<target state="final">Mail-Formular</target>
</trans-unit>
<trans-unit id="forms_mail_description" approved="yes">
<source>A mail form allowing website users to submit responses.</source>
<target state="final">Ein E-Mail-Formular, mit dem Besucher mit Ihnen Kontakt aufnehmen können.</target>
</trans-unit>
<trans-unit id="forms_login_title" approved="yes">
<source>Login Form</source>
<target state="final">Anmeldeformular</target>
</trans-unit>
<trans-unit id="forms_login_description" approved="yes">
<source>Login/logout form used to password protect pages allowing only authorised website users and groups access.</source>
<target state="final">Ein An-/Abmeldeformular, um passwortgeschützte Seiten nur für authorisierte Benutzer und Gruppen zugänglich zu machen.</target>
</trans-unit>
<trans-unit id="plugins" approved="yes">
<source>Plugins</source>
<target state="final">Plug-Ins</target>
</trans-unit>
<trans-unit id="plugins_general_title" approved="yes">
<source>General Plugin</source>
<target state="final">Allgemeines Plug-In</target>
</trans-unit>
<trans-unit id="plugins_general_description" approved="yes">
<source>Select this element type to insert a plugin which cannot be found amongst the options below.</source>
<target state="final">Wähle diesen Elementtyp aus, um ein Plug-In einzufügen, das nicht in den unten aufgeführten Optionen enthalten ist.</target>
</trans-unit>
</body>
</file>
</xliff>
@@ -0,0 +1,148 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="en" datatype="plaintext" original="EXT:backend/Resources/Private/Language/locallang_download.xlf" date="2012-06-17T10:22:33Z" product-name="recordlist" target-language="de">
<header/>
<body>
<trans-unit id="downloadRecord" approved="yes">
<source>Download %d record</source>
<target state="final">Datensatz %d herunterladen</target>
</trans-unit>
<trans-unit id="downloadRecords" approved="yes">
<source>Download %d records</source>
<target state="final">Datensätze %d herunterladen</target>
</trans-unit>
<trans-unit id="download" approved="yes">
<source>Download</source>
<target state="final">Herunterladen</target>
</trans-unit>
<trans-unit id="downloadRecordSettings" approved="yes">
<source>Download %s: %d Record</source>
<target state="final">Download %s: %d Datensatz</target>
</trans-unit>
<trans-unit id="downloadRecordsSettings" approved="yes">
<source>Download %s: %d Records</source>
<target state="final">Download %s: %d Datensätze</target>
</trans-unit>
<trans-unit id="downloadSettings.generalSettings" approved="yes">
<source>General settings</source>
<target state="final">Allgemeine Einstellungen</target>
</trans-unit>
<trans-unit id="downloadSettings.columnsToDownload" approved="yes">
<source>Columns to download</source>
<target state="final">Herunterzuladende Spalten</target>
</trans-unit>
<trans-unit id="downloadSettings.selectedColumns" approved="yes">
<source>Selected columns</source>
<target state="final">Ausgewählte Spalten</target>
</trans-unit>
<trans-unit id="downloadSettings.allColumns" approved="yes">
<source>All columns</source>
<target state="final">Alle Spalten</target>
</trans-unit>
<trans-unit id="downloadSettings.valueFormat" approved="yes">
<source>Format of values</source>
<target state="final">Format der Werte</target>
</trans-unit>
<trans-unit id="downloadSettings.rawValues" approved="yes">
<source>Raw values</source>
<target state="final">Rohdaten</target>
</trans-unit>
<trans-unit id="downloadSettings.processedValues" approved="yes">
<source>Processed values</source>
<target state="final">Verarbeitete Werte</target>
</trans-unit>
<trans-unit id="downloadSettings.default" approved="yes">
<source>Default: %s</source>
<target state="final">Standard: %s</target>
</trans-unit>
<trans-unit id="downloadSettings.filename" approved="yes">
<source>Filename</source>
<target state="final">Dateiname</target>
</trans-unit>
<trans-unit id="downloadSettings.filename.placeholder" approved="yes">
<source>e.g. %s_ddmmyy-hhmm</source>
<target state="final">z. B. %s_ddmmyy-hhmm</target>
</trans-unit>
<trans-unit id="downloadSettings.format" approved="yes">
<source>Format</source>
<target state="final">Format</target>
</trans-unit>
<trans-unit id="downloadSettings.format.csv" approved="yes">
<source>CSV</source>
<target state="final">CSV</target>
</trans-unit>
<trans-unit id="downloadSettings.format.json" approved="yes">
<source>JSON</source>
<target state="final">JSON</target>
</trans-unit>
<trans-unit id="downloadSettings.formatOptions.csv" approved="yes">
<source>CSV options</source>
<target state="final">CSV-Optionen</target>
</trans-unit>
<trans-unit id="downloadSettings.formatOptions.csv.delimiter" approved="yes">
<source>Delimiter</source>
<target state="final">Feldtrennzeichen</target>
</trans-unit>
<trans-unit id="downloadSettings.formatOptions.csv.delimiter.comma" approved="yes">
<source>comma</source>
<target state="final">Komma</target>
</trans-unit>
<trans-unit id="downloadSettings.formatOptions.csv.delimiter.semicolon" approved="yes">
<source>semicolon</source>
<target state="final">Semikolon</target>
</trans-unit>
<trans-unit id="downloadSettings.formatOptions.csv.delimiter.pipe" approved="yes">
<source>pipe</source>
<target state="final">Senkrechter Strich</target>
</trans-unit>
<trans-unit id="downloadSettings.formatOptions.csv.delimiter.custom" approved="yes">
<source>user defined</source>
<target state="final">benutzerdefiniert</target>
</trans-unit>
<trans-unit id="downloadSettings.formatOptions.csv.quote" approved="yes">
<source>Quote character</source>
<target state="final">Feldbegrenzerzeichen</target>
</trans-unit>
<trans-unit id="downloadSettings.formatOptions.csv.quote.doublequote" approved="yes">
<source>double quote</source>
<target state="final">Doppeltes Anführungszeichen</target>
</trans-unit>
<trans-unit id="downloadSettings.formatOptions.csv.quote.singlequote" approved="yes">
<source>single quote</source>
<target state="final">Einfaches Anführungszeichen</target>
</trans-unit>
<trans-unit id="downloadSettings.formatOptions.csv.quote.space" approved="yes">
<source>space</source>
<target state="final">Leerzeichen</target>
</trans-unit>
<trans-unit id="downloadSettings.formatOptions.csv.quote.custom" approved="yes">
<source>user defined</source>
<target state="final">benutzerdefiniert</target>
</trans-unit>
<trans-unit id="downloadSettings.formatOptions.json" approved="yes">
<source>JSON options</source>
<target state="final">JSON-Optionen</target>
</trans-unit>
<trans-unit id="downloadSettings.formatOptions.json.meta" approved="yes">
<source>Meta information</source>
<target state="final">Metainformationen</target>
</trans-unit>
<trans-unit id="downloadSettings.formatOptions.json.meta.full" approved="yes">
<source>Add all relevant information to the download</source>
<target state="final">Alle relevanten Informationen zum Download hinzufügen</target>
</trans-unit>
<trans-unit id="downloadSettings.formatOptions.json.meta.prefix" approved="yes">
<source>Prefix the download with table name and page id</source>
<target state="final">Dem Download den Tabellennamen und die Seiten-ID voranstellen</target>
</trans-unit>
<trans-unit id="downloadSettings.formatOptions.json.meta.none" approved="yes">
<source>No information, only download records</source>
<target state="final">Keine Informationen, nur Datensätze herunterladen</target>
</trans-unit>
<trans-unit id="downloadSettings.preset" approved="yes">
<source>Preset</source>
<target state="final">Voreinstellung</target>
</trans-unit>
</body>
</file>
</xliff>
@@ -0,0 +1,566 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="en" datatype="plaintext" original="EXT:backend/Resources/Private/Language/locallang_layout.xlf" date="2011-10-17T20:22:32Z" product-name="cms" target-language="de">
<header/>
<body>
<trans-unit id="title" approved="yes">
<source>Page content</source>
<target state="final">Seiteninhalt</target>
</trans-unit>
<trans-unit id="noEditItems" approved="yes">
<source>Sorry, you do not have permissions to edit items on this page!</source>
<target state="final">Du hast leider nicht die notwendigen Rechte, um Elemente dieser Seite zu bearbeiten!</target>
</trans-unit>
<trans-unit id="noEditPage" approved="yes">
<source>Sorry, you do not have permissions to edit this page!</source>
<target state="final">Du hast leider nicht die notwendigen Rechte, um diese Seite zu bearbeiten!</target>
</trans-unit>
<trans-unit id="moveUp" approved="yes">
<source>Move record up</source>
<target state="final">Datensatz nach oben verschieben</target>
</trans-unit>
<trans-unit id="moveDown" approved="yes">
<source>Move record down</source>
<target state="final">Datensatz nach unten verschieben</target>
</trans-unit>
<trans-unit id="unHide" approved="yes">
<source>Un-hide</source>
<target state="final">Sichtbar machen</target>
</trans-unit>
<trans-unit id="hide" approved="yes">
<source>Hide</source>
<target state="final">Verbergen</target>
</trans-unit>
<trans-unit id="edit" approved="yes">
<source>Edit</source>
<target state="final">Bearbeiten</target>
</trans-unit>
<trans-unit id="newAfter" approved="yes">
<source>New record after this one</source>
<target state="final">Neuen Datensatz nach diesem anfügen</target>
</trans-unit>
<trans-unit id="move_record" approved="yes">
<source>Re-position current content element</source>
<target state="final">Aktuelles Inhaltselement neupositionieren</target>
</trans-unit>
<trans-unit id="move_page" approved="yes">
<source>Move page</source>
<target state="final">Seite verschieben</target>
</trans-unit>
<trans-unit id="transfer_multiple" approved="yes">
<source>Transfer multiple items</source>
<target state="final">Mehrere Elemente verschieben</target>
</trans-unit>
<trans-unit id="mess.transfer_multiple" approved="yes">
<source>Transfer %d items into "%s"?</source>
<target state="final">%d Elemente in Ordner "%s" verschieben?</target>
</trans-unit>
<trans-unit id="drop.conflict" approved="yes">
<source>Conflict with dropped node</source>
<target state="final">Konflikt mit abgelegtem Element</target>
</trans-unit>
<trans-unit id="mess.drop.conflict" approved="yes">
<source>The node %s is a parent of %s and therefore cannot be moved. Operation canceled.</source>
<target state="final">Das Element %s ist ein Eltern-Element von %s und kann daher nicht verschoben werden. Die Aktion wird abgebrochen.</target>
</trans-unit>
<trans-unit id="deleteItem" approved="yes">
<source>Delete</source>
<target state="final">Löschen</target>
</trans-unit>
<trans-unit id="deleteWarning" approved="yes">
<source>Are you sure you want to delete the record '%s'?</source>
<target state="final">Bist du sicher, dass du den Datensatz '%s ' löschen möchtest?</target>
</trans-unit>
<trans-unit id="pasteIntoColumn" approved="yes">
<source>Paste into this column</source>
<target state="final">In diese Spalte einfügen</target>
</trans-unit>
<trans-unit id="pasteAfterRecord" approved="yes">
<source>Paste after this record</source>
<target state="final">Nach diesem Datensatz einfügen</target>
</trans-unit>
<trans-unit id="paste.modal.title.paste" approved="yes">
<source>Paste record</source>
<target state="final">Datensatz einfügen</target>
</trans-unit>
<trans-unit id="paste.modal.paste" approved="yes">
<source>Do you want to paste the record to this position?</source>
<target state="final">Soll der Datensatz an dieser Position eingefügt werden?</target>
</trans-unit>
<trans-unit id="paste.modal.button.cancel" approved="yes">
<source>Cancel</source>
<target state="final">Abbrechen</target>
</trans-unit>
<trans-unit id="paste.modal.button.paste" approved="yes">
<source>Paste</source>
<target state="final">Einfügen</target>
</trans-unit>
<trans-unit id="editColumn" approved="yes">
<source>Edit this column</source>
<target state="final">Diese Spalte bearbeiten</target>
</trans-unit>
<trans-unit id="editPageProperties_curLang" approved="yes">
<source>Edit translation properties</source>
<target state="final">Übersetzungseigenschaften bearbeiten</target>
</trans-unit>
<trans-unit id="editInRTE" approved="yes">
<source>Edit in Rich Text Editor</source>
<target state="final">In Rich-Text-Editor bearbeiten</target>
</trans-unit>
<trans-unit id="newPageContent" approved="yes">
<source>Create page content</source>
<target state="final">Seiteninhalt erstellen</target>
</trans-unit>
<trans-unit id="newPageContent_translate" approved="yes">
<source>Translate</source>
<target state="final">Übersetzen</target>
</trans-unit>
<trans-unit id="newPageContent2" approved="yes">
<source>New content</source>
<target state="final">Neuer Inhalt</target>
</trans-unit>
<trans-unit id="content" approved="yes">
<source>Content</source>
<target state="final">Inhalt</target>
</trans-unit>
<trans-unit id="createNewContent" approved="yes">
<source>Create new content</source>
<target state="final">Neuen Inhalt erstellen</target>
</trans-unit>
<trans-unit id="newInColumn" approved="yes">
<source>Create new record in top of this column</source>
<target state="final">Einen neuen Datensatz am Anfang dieser Spalte erstellen</target>
</trans-unit>
<trans-unit id="records" approved="yes">
<source>records</source>
<target state="final">Datensätze</target>
</trans-unit>
<trans-unit id="pageInformation" approved="yes">
<source>Page information</source>
<target state="final">Seiteninformationen</target>
</trans-unit>
<trans-unit id="goToTable" approved="yes">
<source>Go to table</source>
<target state="final">Gehe zu Tabelle</target>
</trans-unit>
<trans-unit id="internalNotes" approved="yes">
<source>Internal notes</source>
<target state="final">Interne Notizen</target>
</trans-unit>
<trans-unit id="clearCache" approved="yes">
<source>Click here to clear cache for this page.</source>
<target state="final">Hier klicken, um den Cache dieser Seite zu leeren.</target>
</trans-unit>
<trans-unit id="hiddenCE" approved="yes">
<source>Show hidden content elements</source>
<target state="final">Verborgene Inhalte anzeigen</target>
</trans-unit>
<trans-unit id="new_language" approved="yes">
<source>Create a new translation of this page</source>
<target state="final">Neue Übersetzung dieser Seite erstellen</target>
</trans-unit>
<trans-unit id="newLabel" approved="yes">
<source>NEW</source>
<target state="final">NEU</target>
</trans-unit>
<trans-unit id="defaultLanguage" approved="yes">
<source>Default</source>
<target state="final">Standard</target>
</trans-unit>
<trans-unit id="editLanguageHeader" approved="yes">
<source>Edit language header</source>
<target state="final">Sprach-Header bearbeiten</target>
</trans-unit>
<trans-unit id="editPageProperties" approved="yes">
<source>Edit page properties</source>
<target state="final">Seiteneigenschaften bearbeiten</target>
</trans-unit>
<trans-unit id="editPageTitle" approved="yes">
<source>Edit the page title</source>
<target state="final">Seitentitel bearbeiten</target>
</trans-unit>
<trans-unit id="editPageTitle.input.field.label" approved="yes">
<source>Enter a page title</source>
<target state="final">Seitentitel eingeben</target>
</trans-unit>
<trans-unit id="editPageLanguageOverlayProperties" approved="yes">
<source>Edit page language overlay properties</source>
<target state="final">Übersetzungseigenschaften bearbeiten</target>
</trans-unit>
<trans-unit id="editThisColumn" approved="yes">
<source>Edit the '%s' field of the listed pages</source>
<target state="final">Bearbeite das '%s' Feld der gelisteten Seiten</target>
</trans-unit>
<trans-unit id="editDefaultLanguagePage" approved="yes">
<source>Edit default language page properties</source>
<target state="final">Seiteneigenschaften der Standardsprache bearbeiten</target>
</trans-unit>
<trans-unit id="newRecordGeneral" approved="yes">
<source>Create new record</source>
<target state="final">Neuen Datensatz erstellen</target>
</trans-unit>
<trans-unit id="newContentElement" approved="yes">
<source>New Page Content</source>
<target state="final">Neuer Seiteninhalt</target>
</trans-unit>
<trans-unit id="CEonThisPage" approved="yes">
<source>Content elements on this page</source>
<target state="final">Inhaltselemente auf dieser Seite:</target>
</trans-unit>
<trans-unit id="newPage" approved="yes">
<source>Create new page</source>
<target state="final">Neue Seite erstellen</target>
</trans-unit>
<trans-unit id="newPage2" approved="yes">
<source>New page</source>
<target state="final">Neue Seite</target>
</trans-unit>
<trans-unit id="noAccess" approved="yes">
<source>No edit access</source>
<target state="final">Kein Bearbeitungszugriff</target>
</trans-unit>
<trans-unit id="noAccess_msg" approved="yes">
<source>You do not have access to edit the requested record.</source>
<target state="final">Du hast keinen Bearbeitungszugriff für den angeforderten Datensatz.</target>
</trans-unit>
<trans-unit id="notAssigned" approved="yes">
<source>Not assigned</source>
<target state="final">Nicht zugewiesen</target>
</trans-unit>
<trans-unit id="emptyColPos" approved="yes">
<source>Empty section</source>
<target state="final">Leerer Abschnitt</target>
</trans-unit>
<trans-unit id="emptyColPos.message" approved="yes">
<source>This section is only for display purposes, no "colPos" configuration is set.</source>
<target state="final">Dieser Abschnitt dient nur der Anzeige, es wird keine "colPos"-Konfiguration vorgenommen.</target>
</trans-unit>
<trans-unit id="unusedColPos" approved="yes">
<source>Unused</source>
<target state="final">Unbenutzt</target>
</trans-unit>
<trans-unit id="undoLastChange" approved="yes">
<source>Undo/Redo last change (%s ago)</source>
<target state="final">Letzte Änderung rückgängig/wiederherstellen (%s zurück)</target>
</trans-unit>
<trans-unit id="recordHistory" approved="yes">
<source>View record change history</source>
<target state="final">Änderungsverlauf des Datensatzes anzeigen</target>
</trans-unit>
<trans-unit id="viewContent" approved="yes">
<source>Viewing content of</source>
<target state="final">Inhalt anzeigen von</target>
</trans-unit>
<trans-unit id="tt_board_subject" approved="yes">
<source>Subject</source>
<target state="final">Betreff</target>
</trans-unit>
<trans-unit id="tt_board_author" approved="yes">
<source>Author</source>
<target state="final">Autor</target>
</trans-unit>
<trans-unit id="tt_board_date" approved="yes">
<source>Date</source>
<target state="final">Datum</target>
</trans-unit>
<trans-unit id="tt_board_age" approved="yes">
<source>Age</source>
<target state="final">Alter</target>
</trans-unit>
<trans-unit id="tt_board_RE" approved="yes">
<source>RE</source>
<target state="final">AW</target>
</trans-unit>
<trans-unit id="gridView" approved="yes">
<source>Grid-View</source>
<target state="final">Rasteransicht</target>
</trans-unit>
<trans-unit id="m_tt_board_0" approved="yes">
<source>List topics only</source>
<target state="final">Nur Themenliste</target>
</trans-unit>
<trans-unit id="m_tt_board_expand" approved="yes">
<source>Expand Threads</source>
<target state="final">Threads ausklappen</target>
</trans-unit>
<trans-unit id="m_tt_address_0" approved="yes">
<source>Short List</source>
<target state="final">Kurze Liste</target>
</trans-unit>
<trans-unit id="m_tt_address_1" approved="yes">
<source>Address list</source>
<target state="final">Adressliste</target>
</trans-unit>
<trans-unit id="m_tt_address_2" approved="yes">
<source>Personal info</source>
<target state="final">Persönliche Informationen</target>
</trans-unit>
<trans-unit id="m_tt_links_1" approved="yes">
<source>Whole URL</source>
<target state="final">Gesamte URL</target>
</trans-unit>
<trans-unit id="m_tt_links_2" approved="yes">
<source>Alternative note</source>
<target state="final">Alternative Anmerkung</target>
</trans-unit>
<trans-unit id="m_tt_calender_date" approved="yes">
<source>Date</source>
<target state="final">Datum</target>
</trans-unit>
<trans-unit id="m_tt_calender_date_ext" approved="yes">
<source>Date - extended</source>
<target state="final">Datum - erweitert</target>
</trans-unit>
<trans-unit id="m_tt_calender_todo" approved="yes">
<source>Todo</source>
<target state="final">To-do</target>
</trans-unit>
<trans-unit id="m_tt_calender_todo_ext" approved="yes">
<source>Todo - extended</source>
<target state="final">To-do - erweitert</target>
</trans-unit>
<trans-unit id="m_tt_calender_ext" approved="yes">
<source>Extended</source>
<target state="final">Erweitert</target>
</trans-unit>
<trans-unit id="m_tt_products_ext" approved="yes">
<source>Extended</source>
<target state="final">Erweitert</target>
</trans-unit>
<trans-unit id="m_default" approved="yes">
<source>Default</source>
<target state="final">Standard</target>
</trans-unit>
<trans-unit id="clickAPage_content" approved="yes">
<source>Please select a page in the page tree to edit page content.</source>
<target state="final">Bitte wähle eine Seite im Seitenbaum aus, um Seiteninhalte zu bearbeiten.</target>
</trans-unit>
<trans-unit id="pI_crUser" approved="yes">
<source>Created by</source>
<target state="final">Erstellt von</target>
</trans-unit>
<trans-unit id="pI_crDate" approved="yes">
<source>Created date</source>
<target state="final">Erstellt am</target>
</trans-unit>
<trans-unit id="pI_lastChange" approved="yes">
<source>Last change</source>
<target state="final">Letzte Änderung</target>
</trans-unit>
<trans-unit id="pI_lastChangeContent" approved="yes">
<source>Last change, content</source>
<target state="final">Letzte Änderung, Inhalt</target>
</trans-unit>
<trans-unit id="pI_hitsTotal" approved="yes">
<source>Total Hits</source>
<target state="final">Gesamtzugriffe</target>
</trans-unit>
<trans-unit id="pI_hitsPeriod" approved="yes">
<source>Hits Period</source>
<target state="final">Zugriffszeitraum</target>
</trans-unit>
<trans-unit id="pI_hits24hours" approved="yes">
<source>Last 24 hours</source>
<target state="final">Letzte 24 Stunden</target>
</trans-unit>
<trans-unit id="pI_hits10days" approved="yes">
<source>Last 10 days</source>
<target state="final">Letzte 10 Tage</target>
</trans-unit>
<trans-unit id="content_from_pid_title" approved="yes">
<source>Page uses content from this page: %s</source>
<target state="final">Die Seite benutzt Inhalt von dieser Seite: %s</target>
</trans-unit>
<trans-unit id="content_from_pid_invalid_title" approved="yes">
<source>Page is defined to use content from PID %s, but this page does not exist or is inaccessible</source>
<target state="final">Die Seite ist so konfiguriert, dass sie Inhalte von PID %s verwendet, aber diese Seite existiert nicht oder ist nicht zugänglich</target>
</trans-unit>
<trans-unit id="content_on_pid_title" approved="yes">
<source>This content is also shown on: %s</source>
<target state="final">Dieser Inhalt wird auch angezeigt auf: %s</target>
</trans-unit>
<trans-unit id="pageIsExternalLinkMessage" approved="yes">
<source>Page is a link to the following external URL: %s</source>
<target state="final">Die Seite ist ein Link zu der folgenden externen URL: %s</target>
</trans-unit>
<trans-unit id="pageIsInternalLinkMessage" approved="yes">
<source>Page is a link to the following page: %s</source>
<target state="final">Die Seite ist ein Link zu der folgenden Seite: %s</target>
</trans-unit>
<trans-unit id="pageIsRandomInternalLinkMessage" approved="yes">
<source>Page is a link to a random subpage.</source>
<target state="final">Seite ist ein Link zu einer zufälligen Unterseite.</target>
</trans-unit>
<trans-unit id="pageIsMisconfiguredInternalLinkMessage" approved="yes">
<source>Page is configured to be a link but there is actually no valid target defined.</source>
<target state="final">Die Seite ist als Link konfiguriert, aber es ist kein gültiges Ziel definiert.</target>
</trans-unit>
<trans-unit id="pageIsMisconfiguredOrNotAccessibleInternalLinkMessage" approved="yes">
<source>Page is configured to be a link but there is actually no target defined which is accessible in the frontend.</source>
<target state="final">Die Seite ist als Link konfiguriert, aber es ist kein im Frontend erreichbares Ziel definiert.</target>
</trans-unit>
<trans-unit id="pageIsMisconfiguredOrNotAccessibleRandomInternalLinkMessage" approved="yes">
<source>Page is configured to be a link to a random subpage but there is actually no subpage which is accessible in the frontend.</source>
<target state="final">Die Seite ist als Link zu einer zufälligen Unterseite konfiguriert, aber es gibt keine im Frontend erreichbare Unterseite.</target>
</trans-unit>
<trans-unit id="pageIsMisconfiguredFirstSubpageMessage" approved="yes">
<source>Page is configured to be a link to the first subpage but there is actually no such page accessible in the frontend.</source>
<target state="final">Die Seite ist als Link auf die erste Unterseite konfiguriert, aber es gibt keine im Frontend erreichbare Unterseite.</target>
</trans-unit>
<trans-unit id="pageIsMisconfiguredParentPageMessage" approved="yes">
<source>Page is configured to be a link to the parent page but there is actually no such page accessible in the frontend.</source>
<target state="final">Die Seite ist als Link zur Überseite konfiguriert, aber es gibt im Frontend keine solche erreichbare Seite.</target>
</trans-unit>
<trans-unit id="pageIsMisconfiguredExternalLinkMessage" approved="yes">
<source>Page is configured to be an external link but there is actually no URL defined.</source>
<target state="final">Die Seite ist als externer Link konfiguriert, aber es ist keine URL definiert.</target>
</trans-unit>
<trans-unit id="goToListModule" approved="yes">
<source>Go to list module</source>
<target state="final">Zum Modul Datensätze wechseln</target>
</trans-unit>
<trans-unit id="goToListModuleMessage" approved="yes">
<source>The current page is a folder. Folders usually don't contain content elements but are used for collecting other types of records.</source>
<target state="final">Die aktuelle Seite ist ein Ordner. Ordner enthalten gewöhnlich keine Inhaltselemente, sondern werden zum Sammeln anderer Arten von Datensätzen verwendet.</target>
</trans-unit>
<trans-unit id="noPluginSelected" approved="yes">
<source>No plugin selected</source>
<target state="final">Kein Plug-In ausgewählt</target>
</trans-unit>
<trans-unit id="staleTranslationWarning" approved="yes">
<source>Make sure that this behavior is intended and does not pose a problem for you. We highlighted the problematic records for you.</source>
<target state="final">Stelle sicher, dass dieses Verhalten gewünscht ist und kein Problem für dich darstellt. Die problematischen Datensätze wurden hervorgehoben.</target>
</trans-unit>
<trans-unit id="staleTranslationWarningTitle" approved="yes">
<source>Inconsistent content detected in language "%s"</source>
<target state="final">Inkonsistenter Inhalt in Sprache "%s" gefunden</target>
</trans-unit>
<trans-unit id="languageModeFree" approved="yes">
<source>Free Mode</source>
<target state="final">Freier Modus</target>
</trans-unit>
<trans-unit id="languageModeConnected" approved="yes">
<source>Connected Mode</source>
<target state="final">Verbundener Modus</target>
</trans-unit>
<trans-unit id="languageModeMixed" approved="yes">
<source>Mixed Mode</source>
<target state="final">Gemischter Modus</target>
</trans-unit>
<trans-unit id="languageContainsWorkspaceDeletePlaceholderRecords" approved="yes">
<source>Deleted workspace elements are not shown</source>
<target state="final">Gelöschte Workspace-Elemente werden nicht angezeigt</target>
</trans-unit>
<trans-unit id="staleUnusedElementsWarning" approved="yes">
<source>These elements don't belong to any of the available columns of this page. You should either delete them or move them to existing columns. We highlighted the problematic records for you.</source>
<target state="final">Diese Elemente gehören zu keiner der verfügbaren Spalten dieser Seite. Du solltest sie entweder löschen oder in bestehende Spalten verschieben. Die problematischen Datensätze wurden hervorgehoben.</target>
</trans-unit>
<trans-unit id="staleUnusedElementsWarningTitle" approved="yes">
<source>Unused elements detected on this page</source>
<target state="final">Unbenutzte Elemente auf dieser Seite</target>
</trans-unit>
<trans-unit id="localize.chooseLanguage" approved="yes">
<source>Choose your language</source>
<target state="final">Wähle deine Sprache aus</target>
</trans-unit>
<trans-unit id="localize.wizard.header" approved="yes">
<source>Localize record &quot;{0}&quot; into {1}</source>
<target state="final">Datensatz "{0}" nach {1} lokalisieren</target>
</trans-unit>
<trans-unit id="localize.wizard.header_page" approved="yes">
<source>Localize page &quot;{0}&quot; into {1}</source>
<target state="final">Seite "{0}" nach {1} lokalisieren</target>
</trans-unit>
<trans-unit id="localize.wizard.button.translate" approved="yes">
<source>Translate</source>
<target state="final">Übersetzen</target>
</trans-unit>
<trans-unit id="localize.wizard.button.copy" approved="yes">
<source>Copy</source>
<target state="final">Kopieren</target>
</trans-unit>
<trans-unit id="localize.wizard.button.cancel" approved="yes">
<source>Cancel</source>
<target state="final">Abbrechen</target>
</trans-unit>
<trans-unit id="localize.wizard.button.next" approved="yes">
<source>Next</source>
<target state="final">Nächster</target>
</trans-unit>
<trans-unit id="localize.wizard.button.process" approved="yes">
<source>Start processing</source>
<target state="final">Verarbeitung beginnen</target>
</trans-unit>
<trans-unit id="localize.wizard.step.selectMode" approved="yes">
<source>Localization mode</source>
<target state="final">Übersetzungsmodus</target>
</trans-unit>
<trans-unit id="localize.wizard.step.chooseLanguage" approved="yes">
<source>Source Language</source>
<target state="final">Ausgangssprache</target>
</trans-unit>
<trans-unit id="localize.wizard.step.chooseLanguage" approved="yes">
<source>Source Language</source>
<target state="final">Ausgangssprache</target>
</trans-unit>
<trans-unit id="localize.wizard.step.selectRecords" approved="yes">
<source>Records</source>
<target state="final">Datensätze</target>
</trans-unit>
<trans-unit id="localize.view.chooseLanguage" approved="yes">
<source>Choose the language from which you want to localize the content</source>
<target state="final">Wähle die Sprache aus, von der du Inhalte lokalisieren möchtest</target>
</trans-unit>
<trans-unit id="localize.view.summary" approved="yes">
<source>Record summary</source>
<target state="final">Datensatzzusammenfassung</target>
</trans-unit>
<trans-unit id="localize.view.processing" approved="yes">
<source>Processing...</source>
<target state="final">Verarbeitung...</target>
</trans-unit>
<trans-unit id="localize.progress.step" approved="yes">
<source>Step {0} of {1}</source>
<target state="final">Schritt {0} von {1}</target>
</trans-unit>
<trans-unit id="localize.educate.translate" approved="yes">
<source>Translating content will create a direct connection between the original language and the language you translate to.&lt;br&gt;
This means that moving an element or setting meta information like start- or endtime will be taken from the original content and you will not be able to set these values on a translated content element.&lt;br&gt;
&lt;strong&gt;Use this when your workflow demands a strict translation workflow.&lt;/strong&gt;
</source>
<target state="final">Das Übersetzen von Inhalten schafft eine direkte Verbindung zwischen der Originalsprache und der Sprache, in die Sie übersetzen.&lt;br&gt; Das bedeutet, dass das Verschieben eines Elements oder das Setzen von Metainformationen wie Start- oder Endzeit vom ursprünglichen originalen Inhalt genommen wird und Sie diese Werte in einem übersetzten Inhaltselement nicht konfigurieren können.&lt;br&gt; &lt;strong&gt;Verwenden Sie dies, wenn Ihr Workflow einen strikten Übersetzungsprozess erfordert.&lt;/strong&gt;</target>
</trans-unit>
<trans-unit id="localize.educate.copy" approved="yes">
<source>Copying content will take the content elements from the source language and create copies in a different language.&lt;br&gt;
This means that you will be able to move content elements around freely, but you will not have the benefit of being able to compare changes made in the source language later on.&lt;br&gt;
&lt;strong&gt;Use this when you want to have freedom in designing your translated website.&lt;/strong&gt;
</source>
<target state="final">Beim Kopieren von Inhalten werden Kopien der Inhaltselemente der Originalsprache in einer anderen Sprache erstellt.&lt;br&gt;
Sie werden Inhaltselemente frei bewegen können, aber Sie werden nicht die Möglichkeit haben, das Element mit Änderungen zu vergleichen, die in der Originalsprache gemacht wurden.&lt;br&gt;
&lt;strong&gt;Benutzen Sie diese Möglichkeit, wenn Sie Freiheit beim Entwurf Ihrer übersetzten Website wünschen.&lt;/strong&gt;</target>
</trans-unit>
<trans-unit id="window.localization.mixed_mode.title" approved="yes">
<source>Localization not possible</source>
<target state="final">Übersetzung nicht möglich</target>
</trans-unit>
<trans-unit id="window.localization.mixed_mode.message" approved="yes">
<source>Using the translation wizard is not possible, because either translation is disabled or the translated page is in "mixed mode". Being in "mixed mode" means that both translated records that have a source language and "free mode" records without a parent, are present.
We highlighted the problematic records for you in this case.</source>
<target state="final">Die Verwendung des Übersetzungsassistenten ist nicht möglich, da entweder die Übersetzung deaktiviert ist oder die übersetzte Seite sich im "gemischten Modus" befindet. Gemischter Modus" bedeutet, dass sowohl übersetzte Datensätze, die eine Ausgangssprache haben, als auch Datensätze im "freien Modus" ohne Eltern-Datensatz vorhanden sind.
In diesem Fall haben wir die problematischen Datensätze für dich hervorgehoben.</target>
</trans-unit>
<trans-unit id="error.invalidBackendLayout" approved="yes">
<source>The selected page layout is mis-configured, no columns are specified to be editable. Please update your backend layout to have at least one parameter "colPos" set.</source>
<target state="final">Das ausgewählte Seitenlayout ist falsch konfiguriert: Es sind keine Spalten als bearbeitbar festgelegt. Bitte aktualisiere dein Backendlayout so, dass zumindest einmal der Parameter "colPos" gesetzt ist.</target>
</trans-unit>
<trans-unit id="dragdrop.copy.message" approved="yes">
<source>Press CTRL to copy</source>
<target state="final">Drücke &lt;kbd&gt;Strg&lt;/kbd&gt; oder &lt;kbd&gt;Cmd&lt;/kbd&gt; zum Kopieren</target>
</trans-unit>
<trans-unit id="progressTracker.steps" approved="yes">
<source>Step %d of %d</source>
<target state="final">Schritt %d von %d</target>
</trans-unit>
</body>
</file>
</xliff>
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="en" datatype="plaintext" original="EXT:backend/Resources/Private/Language/locallang_login.xlf" date="2011-10-17T20:22:34Z" product-name="lang" target-language="de">
<header/>
<body>
<trans-unit id="labels.submitLogout" approved="yes">
<source>Log Out</source>
<target state="final">Abmelden</target>
</trans-unit>
<trans-unit id="labels.whatIsOpenId" approved="yes">
<source>What is OpenId?</source>
<target state="final">Was ist OpenID?</target>
</trans-unit>
<trans-unit id="availableInterfaces" approved="yes">
<source>Backend,Front End,Traditional Backend</source>
<target state="final">Backend,Frontend,Traditionelles Backend</target>
</trans-unit>
<trans-unit id="headline" approved="yes">
<source>Login to the TYPO3 CMS Backend on ###SITENAME###</source>
<target state="final">Anmeldung am Backend von ###SITENAME###</target>
</trans-unit>
<trans-unit id="info.about" approved="yes">
<source>This is the backend login of TYPO3. You need username and password to access this administration interface. If you are a visitor of ###SITENAME###, please visit the public website: ###SITELINK###</source>
<target state="final">Dies ist die Anmeldung am TYPO3-Backend. Um auf die Verwaltungsoberfläche zugreifen zu können, benötigst du einen Benutzernamen und ein Passwort. Falls du ein Besucher von ###SITENAME### bist, besuche bitte den öffentlichen Bereich: ###SITELINK###</target>
</trans-unit>
<trans-unit id="info.reset" approved="yes">
<source>Reset this form</source>
<target state="final">Formular zurücksetzen</target>
</trans-unit>
<trans-unit id="info.cookies_and_js" approved="yes">
<source>(Note: Cookies and JavaScript must be enabled!)</source>
<target state="final">(Hinweis: Cookies und JavaScript müssen aktiviert sein!)</target>
</trans-unit>
<trans-unit id="clear" approved="yes">
<source>Clear this field!</source>
<target state="final">Dieses Feld leeren!</target>
</trans-unit>
<trans-unit id="warning.incompatibleBrowserHeadline" approved="yes">
<source>Unsupported Browser</source>
<target state="final">Nicht unterstützter Browser</target>
</trans-unit>
<trans-unit id="warning.incompatibleBrowser" approved="yes">
<source>You are using an unsupported browser version.</source>
<target state="final">Du verwendest eine nicht unterstützte Browser-Version.</target>
</trans-unit>
<trans-unit id="warning.incompatibleBrowserInternetExplorer" approved="yes">
<source>Please install &lt;a href="http://www.microsoft.com/internetexplorer/" target="_blank" rel="noreferrer" /&gt;a more modern browser version&lt;/a&gt;.</source>
<target state="final">Bitte installiere &lt;a href="http://www.microsoft.com/internetexplorer/" target="_blank" rel="noreferrer" /&gt;eine aktuellere Browser-Version&lt;/a&gt;.</target>
</trans-unit>
<trans-unit id="newsheadline" approved="yes">
<source>Important Messages</source>
<target state="final">Wichtige Meldungen</target>
</trans-unit>
<trans-unit id="error.login" approved="yes">
<source>Your login attempt did not succeed. Make sure to spell your username and password correctly, including upper/lowercase characters.</source>
<target state="final">Der Anmeldeversuch ist fehlgeschlagen. Achte darauf, Benutzernamen und Passwort korrekt einzugeben, einschließlich Groß-/Kleinschreibung.</target>
</trans-unit>
<trans-unit id="error.cookies_ignore" approved="yes">
<source>Ignore!</source>
<target state="final">Ignorieren!</target>
</trans-unit>
<trans-unit id="error.furtherInformation" approved="yes">
<source>For more information or further help click here</source>
<target state="final">Weitere Informationen und Hilfe erhältst du hier</target>
</trans-unit>
<trans-unit id="warranty.by" x-unused-since="12.4" approved="yes">
<source>Warranty is supplied by %s; %sdetails about licenses.%s</source>
<target state="final">Die Garantie wird von %s gewährt; %sDetails zu Lizenzen.%s</target>
</trans-unit>
<trans-unit id="no.warranty" x-unused-since="12.4" approved="yes">
<source>TYPO3 CMS comes with ABSOLUTELY NO WARRANTY; %sdetails about licenses.%s</source>
<target state="final">TYPO3 CMS kommt mit ABSOLUT KEINER GARANTIE; %sDetails zu Lizenzen.%s</target>
</trans-unit>
<trans-unit id="typo3.cms" approved="yes">
<source>TYPO3 CMS</source>
<target state="final">TYPO3 CMS</target>
</trans-unit>
<trans-unit id="typo3.altText" approved="yes">
<source>TYPO3 CMS logo</source>
<target state="final">TYPO3-CMS-Logo</target>
</trans-unit>
<trans-unit id="version.short" approved="yes">
<source>ver.</source>
<target state="final">Ver.</target>
</trans-unit>
<trans-unit id="copyright" approved="yes">
<source>Copyright</source>
<target state="final">Copyright</target>
</trans-unit>
<trans-unit id="extension.copyright" approved="yes">
<source>Extensions are copyright of their respective owners.</source>
<target state="final">Erweiterungen sind Eigentum ihrer jeweiligen Autoren.</target>
</trans-unit>
<trans-unit id="extension.trademark" approved="yes">
<source>TYPO3 is a registered %strademark%s.</source>
<target state="final">TYPO3 ist eine registrierte %sMarke%s.</target>
</trans-unit>
<trans-unit id="details.link" x-unused-since="12.4" approved="yes">
<source>Go to %s for details.</source>
<target state="final">Weitere Informationen erhalten Sie unter %s.</target>
</trans-unit>
<trans-unit id="free.software" approved="yes">
<source>This is free software, and you are welcome to redistribute it under certain conditions; %sdetails about licenses.%s</source>
<target state="final">Dies ist freie Software, die du unter bestimmten Bedingungen weitergeben darfst; %sDetails zu Lizenzen.%s</target>
</trans-unit>
<trans-unit id="free_software_and_warranty" approved="yes">
<source>TYPO3 CMS comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions, see %sdetails about licenses.%s</source>
<target state="final">TYPO3 CMS wird OHNE JEGLICHE GEWÄHRLEISTUNG bereitgestellt. Es handelt sich um freie Software, die du unter bestimmten Bedingungen weiterverbreiten darfst. Weitere Informationen findest du unter %sdetails about licenses.%s</target>
</trans-unit>
<trans-unit id="free_software_and_custom_warranty" approved="yes">
<source>Warranty is supplied by %s. This is free software, and you are welcome to redistribute it under certain conditions, see %sdetails about licenses.%s</source>
<target state="final">Die Garantie wird von %s gewährt. Dies ist freie Software, die du unter bestimmten Bedingungen weitergeben darfst. Weitere Informationen zu den Lizenzen findst unter %sdetails about licenses.%s</target>
</trans-unit>
<trans-unit id="keep.notice" approved="yes">
<source>Obstructing the appearance of this notice is prohibited by law.</source>
<target state="final">Das Erscheinen dieses Hinweises zu verhindern, ist gesetzlich verboten.</target>
</trans-unit>
</body>
</file>
</xliff>
@@ -0,0 +1,290 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="en" datatype="plaintext" original="EXT:backend/Resources/Private/Language/locallang_mfa.xlf" date="2021-01-26T11:58:45Z" product-name="cms" target-language="de">
<header/>
<body>
<trans-unit id="overview.title" approved="yes">
<source>Multi-factor Authentication Overview</source>
<target state="final">Multi-Faktor-Authentifizierung Übersicht</target>
</trans-unit>
<trans-unit id="overview.badge.active" approved="yes">
<source>Active</source>
<target state="final">Aktiv</target>
</trans-unit>
<trans-unit id="overview.badge.locked" approved="yes">
<source>Locked</source>
<target state="final">Gesperrt</target>
</trans-unit>
<trans-unit id="overview.defaultProvider" approved="yes">
<source>Default provider</source>
<target state="final">Standard-Provider</target>
</trans-unit>
<trans-unit id="overview.unlockLinkTitle" approved="yes">
<source>Unlock %s</source>
<target state="final">Entsperre %s</target>
</trans-unit>
<trans-unit id="overview.unlockLinkLabel" approved="yes">
<source>Unlock</source>
<target state="final">Entsperren</target>
</trans-unit>
<trans-unit id="overview.editLinkTitle" approved="yes">
<source>Edit %s</source>
<target state="final">%s bearbeiten</target>
</trans-unit>
<trans-unit id="overview.editLinkLabel" approved="yes">
<source>Edit / Change</source>
<target state="final">Bearbeiten / Ändern</target>
</trans-unit>
<trans-unit id="overview.deactivateLinkTitle" approved="yes">
<source>Deactivate %s</source>
<target state="final">%s deaktivieren</target>
</trans-unit>
<trans-unit id="overview.deactivateLinkLabel" approved="yes">
<source>Deactivate</source>
<target state="final">Deaktivieren</target>
</trans-unit>
<trans-unit id="overview.setupLinkTitle" approved="yes">
<source>Setup %s</source>
<target state="final">%s einrichten</target>
</trans-unit>
<trans-unit id="overview.setupLinkLabel" approved="yes">
<source>Setup</source>
<target state="final">Einrichten</target>
</trans-unit>
<trans-unit id="overview.setupRequired.title" approved="yes">
<source>Multi-factor authentication required</source>
<target state="final">Multi-Faktor-Authentifizierung erforderlich</target>
</trans-unit>
<trans-unit id="overview.setupRequired.message" approved="yes">
<source>
Your installation requires MFA. Therefore please setup one of the following providers to be
able to continue to use the backend.
</source>
<target state="final">
Ihre Installation benötigt Multi-Faktor-Authentifizierung. Richten Sie daher bitte einen der folgenden Provider ein, um mit der Verwendung des Backends fortfahren zu können.</target>
</trans-unit>
<trans-unit id="overview.noProviders.title" approved="yes">
<source>No multi-factor authentication providers</source>
<target state="final">Keine Multi-Faktor-Authentifizierungs-Provider</target>
</trans-unit>
<trans-unit id="overview.noProviders.message" approved="yes">
<source>There are currently no multi-factor authentication providers available.</source>
<target state="final">Momentan sind keine Multi-Faktor-Authentifizierungs-Provider verfügbar.</target>
</trans-unit>
<trans-unit id="overview.noProviders.errorMessage" approved="yes">
<source>
You are required to setup MFA but there are no providers to activate available. You should contact
your administrator to solve this.
</source>
<target state="final">
Sie müssen die Multi-Faktor-Authentifizierung einrichten, es sind jedoch keine aktivierungsfähigen Provider verfügbar. Bitte kontaktieren Sie Ihren Administrator für eine Lösung dieses Problems.</target>
</trans-unit>
<trans-unit id="providerNotFound" approved="yes">
<source>Selected MFA provider was not found!</source>
<target state="final">Der ausgewählte Multi-Faktor-Authentifizierungs-Provider wurde nicht gefunden!</target>
</trans-unit>
<trans-unit id="providerNotActive" approved="yes">
<source>Selected MFA provider has to be active to perform this action!</source>
<target state="final">Der ausgewählte Multi-Faktor-Authentifizierungs-Provider muss aktiv sein, um diese Aktion durchführen zu können!</target>
</trans-unit>
<trans-unit id="providerActive" approved="yes">
<source>Selected MFA provider has to be inactive to perform this action!</source>
<target state="final">Der ausgewählte Multi-Faktor-Authentifizierungs-Provider muss inaktiv sein, um diese Aktion ausführen zu können!</target>
</trans-unit>
<trans-unit id="providerIsLocked" approved="yes">
<source>Selected MFA provider has to be unlocked to perform this action!</source>
<target state="final">Der ausgewählte Multi-Faktor-Authentifizierungs-Provider muss entsperrt sein, um diese Aktion ausführen zu können!</target>
</trans-unit>
<trans-unit id="setup.instructions" approved="yes">
<source>Setup instructions</source>
<target state="final">Einrichtungsanleitung</target>
</trans-unit>
<trans-unit id="setup.instructions.close" approved="yes">
<source>Close setup instructions</source>
<target state="final">Einrichtungs-Anweisungen schließen</target>
</trans-unit>
<trans-unit id="setup.title" approved="yes">
<source>Set up %s</source>
<target state="final">%s einrichten</target>
</trans-unit>
<trans-unit id="edit.title" approved="yes">
<source>Edit %s</source>
<target state="final">%s bearbeiten</target>
</trans-unit>
<trans-unit id="edit.defaultProvider" approved="yes">
<source>Default provider</source>
<target state="final">Standard-Provider</target>
</trans-unit>
<trans-unit id="edit.defaultProvider.description" approved="yes">
<source>Select this as your default provider for login into the TYPO3 backend.</source>
<target state="final">Wählen Sie diesen Provider als Ihren Standard-Provider für den Login in das TYPO3 Backend aus.</target>
</trans-unit>
<trans-unit id="edit.defaultProvider.inputLabel" approved="yes">
<source>Use as default provider</source>
<target state="final">Als Standard-Provider verwenden</target>
</trans-unit>
<trans-unit id="edit.deactivateProvider" approved="yes">
<source>Deactivate provider</source>
<target state="final">Provider deaktivieren</target>
</trans-unit>
<trans-unit id="edit.deactivateProvider.description" approved="yes">
<source>If you don't want to use this provider anymore, you can deactivate it here.</source>
<target state="final">Falls Sie diesen Provider nicht länger verwenden möchten, können Sie ihn hier deaktivieren.</target>
</trans-unit>
<trans-unit id="edit.deactivateProvider.linkTitle" approved="yes">
<source>Deactivate %s</source>
<target state="final">%s deaktivieren</target>
</trans-unit>
<trans-unit id="edit.deactivateProvider.linkText" approved="yes">
<source>Deactivate this provider</source>
<target state="final">Diesen Provider deaktivieren</target>
</trans-unit>
<trans-unit id="activate.failure" approved="yes">
<source>Could not activate MFA provider %s. Please try again.</source>
<target state="final">Multi-Faktor-Authentifizierungs-Provider %s konnte nicht aktiviert werden. Bitte versuchen Sie es erneut.</target>
</trans-unit>
<trans-unit id="activate.success" approved="yes">
<source>Successfully activated MFA provider %s.</source>
<target state="final">Multi-Faktor-Authentifizierungs-Provider %s erfolgreich aktiviert.</target>
</trans-unit>
<trans-unit id="deactivate.failure" approved="yes">
<source>Could not deactivate MFA provider %s. Please try again.</source>
<target state="final">Multi-Faktor-Authentifizierungs-Provider %s konnte nicht deaktiviert werden. Bitte versuchen Sie es erneut.</target>
</trans-unit>
<trans-unit id="deactivate.success" approved="yes">
<source>Successfully deactivated MFA provider %s.</source>
<target state="final">Multi-Faktor-Authentifizierungs-Provider %s erfolgreich deaktiviert.</target>
</trans-unit>
<trans-unit id="unlock.failure" approved="yes">
<source>Could not unlock MFA provider %s. Please try again.</source>
<target state="final">Multi-Faktor-Authentifizierungs-Provider %s konnte nicht entsperrt werden. Bitte versuchen Sie es erneut.</target>
</trans-unit>
<trans-unit id="unlock.success" approved="yes">
<source>Successfully unlocked MFA provider %s.</source>
<target state="final">Multi-Faktor-Authentifizierungs-Provider %s wurde erfolgreich entsperrt.</target>
</trans-unit>
<trans-unit id="save.failure" approved="yes">
<source>Could not update MFA provider %s. Please try again.</source>
<target state="final">Multi-Faktor-Authentifizierungs-Provider %s konnte nicht aktualisiert werden. Bitte versuchen Sie es erneut.</target>
</trans-unit>
<trans-unit id="save.success" approved="yes">
<source>Successfully updated MFA provider %s.</source>
<target state="final">Multi-Faktor-Authentifizierungs-Provider %s erfolgreich aktualisiert.</target>
</trans-unit>
<trans-unit id="auth.authError" approved="yes">
<source>Authentication was not successful.</source>
<target state="final">Authentifizierung war nicht erfolgreich.</target>
</trans-unit>
<trans-unit id="auth.submit" approved="yes">
<source>Verify</source>
<target state="final">Verifizieren</target>
</trans-unit>
<trans-unit id="auth.cancel" approved="yes">
<source>Go back</source>
<target state="final">Zurück</target>
</trans-unit>
<trans-unit id="auth.locked" approved="yes">
<source>This provider is locked. Unlocking may require administrative intervention. Recovery codes can be used to circumvent the lock.</source>
<target state="final">Dieser Provider ist gesperrt. Zum Entsperren kann ein Eingreifen durch die Administration erforderlich sein. Wiederherstellungscodes können verwendet werden, um die Sperre aufzuheben.</target>
</trans-unit>
<trans-unit id="auth.alternativeProviders" approved="yes">
<source>Alternative providers</source>
<target state="final">Alternative Provider</target>
</trans-unit>
<trans-unit id="auth.alternativeProviders.use" approved="yes">
<source>Use %s</source>
<target state="final">Verwende %s</target>
</trans-unit>
<trans-unit id="standalone.setupProvider" approved="yes">
<source>Set up %s</source>
<target state="final">%s einrichten</target>
</trans-unit>
<trans-unit id="standalone.selection.title" approved="yes">
<source>Set up MFA</source>
<target state="final">MFA einrichten</target>
</trans-unit>
<trans-unit id="standalone.selection.message" approved="yes">
<source>
%s requires you setting up MFA to secure your account. Please select one of the
available providers below.
</source>
<target state="final">
%s erfordert, dass Sie MFA einrichten, um Ihr Konto zu sichern. Bitte wählen Sie einen der
verfügbaren Anbieter unten.
</target>
</trans-unit>
<trans-unit id="standalone.selection.noAvailableProviders" approved="yes">
<source>
You are required to set up MFA. However, there are no MFA providers available for you to use.
This might be a misconfiguration. Please get in touch with your administrator to find a solution.
</source>
<target state="final">
Sie müssen MFA einrichten, aber es stehen Ihnen keine MFA-Anbieter zur Verfügung.
Dies könnte eine Fehlkonfiguration sein. Bitte kontaktieren Sie Ihren Administrator, um eine Lösung zu finden.
</target>
</trans-unit>
<trans-unit id="standalone.selection.goBack" approved="yes">
<source>Go back</source>
<target state="final">Zurück</target>
</trans-unit>
<trans-unit id="standalone.setup" approved="yes">
<source>Setup</source>
<target state="final">Einrichten</target>
</trans-unit>
<trans-unit id="standalone.setup.cancel" approved="yes">
<source>Cancel</source>
<target state="final">Abbrechen</target>
</trans-unit>
<trans-unit id="standalone.setup.success.title" approved="yes">
<source>MFA setup successful</source>
<target state="final">MFA-Einrichtung erfolgreich</target>
</trans-unit>
<trans-unit id="standalone.setup.success.message" approved="yes">
<source>
You have successfully activated MFA provider %s. This provider was also automatically set as your
default provider. You can change this at any time in your user settings.
</source>
<target state="final">
Sie haben erfolgreich den MFA-Anbieter %s aktiviert. Dieser Provider wurde auch automatisch als Ihr
Standardprovider festgelegt. Sie können dies jederzeit in Ihren Benutzereinstellungen ändern.
</target>
</trans-unit>
<trans-unit id="ajax.success" approved="yes">
<source>Success</source>
<target state="final">Erfolgreich</target>
</trans-unit>
<trans-unit id="ajax.error" approved="yes">
<source>An error occurred</source>
<target state="final">Es ist ein Fehler aufgetreten</target>
</trans-unit>
<trans-unit id="ajax.invalidRequest" approved="yes">
<source>Invalid request could not be processed</source>
<target state="final">Ungültige Anfrage konnte nicht verarbeitet werden</target>
</trans-unit>
<trans-unit id="ajax.insufficientPermissions" approved="yes">
<source>Your are not allowed to perform this action</source>
<target state="final">Sie sind nicht berechtigt, diese Aktion durchzuführen</target>
</trans-unit>
<trans-unit id="ajax.deactivate.providersNotDeactivated" approved="yes">
<source>No provider has been deactivated</source>
<target state="final">Kein Provider wurde deaktiviert</target>
</trans-unit>
<trans-unit id="ajax.deactivate.providersDeactivated" approved="yes">
<source>Successfully deactivated all active providers for user %s</source>
<target state="final">Alle aktiven Provider für Benutzer %s erfolgreich deaktiviert</target>
</trans-unit>
<trans-unit id="ajax.deactivate.providerNotFound" approved="yes">
<source>Provider %s could not be found</source>
<target state="final">Provider %s konnte nicht gefunden werden</target>
</trans-unit>
<trans-unit id="ajax.deactivate.providerNotDeactivated" approved="yes">
<source>Could not deactivate provider %s</source>
<target state="final">Provider %s konnte nicht deaktiviert werden</target>
</trans-unit>
<trans-unit id="ajax.deactivate.providerDeactivated" approved="yes">
<source>Successfully deactivated provider %s for user %s</source>
<target state="final">Provider %s für Benutzer %s erfolgreich deaktiviert</target>
</trans-unit>
</body>
</file>
</xliff>
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="en" datatype="plaintext" original="EXT:backend/Resources/Private/Language/locallang_mod.xlf" date="2011-10-17T20:22:32Z" product-name="cms" target-language="de">
<header/>
<body>
<trans-unit id="mlang_labels_tablabel" approved="yes">
<source>Page content</source>
<target state="final">Seiteninhalt</target>
</trans-unit>
<trans-unit id="mlang_labels_tabdescr" approved="yes">
<source>This module allows you to create and edit webpages, view page hit statistics, manage different languages and columns of content per page and access special page contents like guestbooks and shopping items.</source>
<target state="final">Mit diesem Modul können neue Web-Seiten angelegt und bearbeitet werden. Es bietet einen Quickeditor für schnellen Zugriff auf den Hauptseiteninhalt. Zusätzlich können Sie verschiedene Sprachen und Inhaltsspalten Ihrer Seite verwalten. Darüber hinaus lassen sich spezielle Seiteninhalte wie Gästebücher-, Forums- und Shop-Einträge verwalten. Das Modul zeigt auch Seitenzugriffstatistiken für die einzelnen Seiten an.</target>
</trans-unit>
<trans-unit id="mlang_tabs_tab" approved="yes">
<source>Page</source>
<target state="final">Seite</target>
</trans-unit>
</body>
</file>
</xliff>
@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="en" datatype="plaintext" original="EXT:backend/Resources/Private/Language/locallang_pages_new.xlf" date="2011-10-17T20:22:37Z" product-name="backend" target-language="de">
<header/>
<body>
<trans-unit id="title" approved="yes">
<source>Create multiple pages</source>
<target state="final">Mehrere Seiten erzeugen</target>
</trans-unit>
<trans-unit id="canNotCreateNew.title" approved="yes">
<source>Insufficient permissions</source>
<target state="final">Berechtigungen reichen nicht aus</target>
</trans-unit>
<trans-unit id="canNotCreateNew.message" approved="yes">
<source>Sorry, you are not allowed to create new subpages to this page due to access restrictions.</source>
<target state="final">Entschuldigung, aufgrund von Zugriffsbeschränkungen dürfen Sie keine neuen Unterseiten unterhalb dieser Seite erstellen.</target>
</trans-unit>
<trans-unit id="newPage" approved="yes">
<source>Page</source>
<target state="final">Seite</target>
</trans-unit>
<trans-unit id="addMoreLines" approved="yes">
<source>Add more lines</source>
<target state="final">Zeilen hinzufügen</target>
</trans-unit>
<trans-unit id="listEnd" approved="yes">
<source>Place new pages after the existing subpages</source>
<target state="final">Neue Seiten nach existierenden Unterseiten anlegen</target>
</trans-unit>
<trans-unit id="hidePages" approved="yes">
<source>Hide new pages</source>
<target state="final">Neue Seiten verbergen</target>
</trans-unit>
<trans-unit id="hidePagesInMenus" approved="yes">
<source>Hide new pages in menus</source>
<target state="final">Neue Seiten in Menüs verbergen</target>
</trans-unit>
<trans-unit id="create" approved="yes">
<source>Create pages</source>
<target state="final">Seiten anlegen</target>
</trans-unit>
<trans-unit id="reset" approved="yes">
<source>Clear fields</source>
<target state="final">Felder zurücksetzen</target>
</trans-unit>
<trans-unit id="newSubPages" approved="yes">
<source>New page structure</source>
<target state="final">Neue Seitenstruktur</target>
</trans-unit>
<trans-unit id="newSubPages.pageTitle" approved="yes">
<source>Page title</source>
<target state="final">Seitentitel</target>
</trans-unit>
<trans-unit id="noPagesCreated.title" approved="yes">
<source>No pages added</source>
<target state="final">Keine Seiten hinzugefügt</target>
</trans-unit>
<trans-unit id="noPagesCreated.message" approved="yes">
<source>No pages were created.</source>
<target state="final">Es wurden keine Seiten erstellt!</target>
</trans-unit>
<trans-unit id="pagesCreated.title" approved="yes">
<source>Pages added</source>
<target state="final">Seiten erstellt</target>
</trans-unit>
<trans-unit id="pagesCreated.message" approved="yes">
<source>The pages were created successfully.</source>
<target state="final">Die Seiten wurden erfolgreich erstellt.</target>
</trans-unit>
</body>
</file>
</xliff>
@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="en" datatype="plaintext" original="EXT:backend/Resources/Private/Language/locallang_pages_sort.xlf" date="2011-10-17T20:22:37Z" product-name="backend" target-language="de">
<header/>
<body>
<trans-unit id="title" approved="yes">
<source>Sort sub pages</source>
<target state="final">Unterseiten sortieren</target>
</trans-unit>
<trans-unit id="currentPageOrder" approved="yes">
<source>Current page order</source>
<target state="final">Aktuelle Seitenreihenfolge</target>
</trans-unit>
<trans-unit id="changeOrder" approved="yes">
<source>Sort these pages by</source>
<target state="final">Diese Seiten sortieren nach</target>
</trans-unit>
<trans-unit id="changeOrderConfirm" approved="yes">
<source>You're about to change the order of the above pages. Are you sure you want to continue?</source>
<target state="final">Die Reihenfolge der obigen Seiten wird geändert. Den Vorgang fortsetzen?</target>
</trans-unit>
<trans-unit id="fieldTitle" approved="yes">
<source>Page title</source>
<target state="final">Seitentitel</target>
</trans-unit>
<trans-unit id="fieldSubtitle" approved="yes">
<source>Subtitle</source>
<target state="final">Untertitel</target>
</trans-unit>
<trans-unit id="fieldNavitle" approved="yes">
<source>Navigation title</source>
<target state="final">Navigationstitel</target>
</trans-unit>
<trans-unit id="fieldCrdate" approved="yes">
<source>Create-time</source>
<target state="final">Erzeugungszeitpunkt</target>
</trans-unit>
<trans-unit id="fieldTstamp" approved="yes">
<source>Change-time</source>
<target state="final">Änderungszeitpunkt</target>
</trans-unit>
<trans-unit id="changeOrderByTitle" approved="yes">
<source>Page title</source>
<target state="final">Seitentitel</target>
</trans-unit>
<trans-unit id="changeOrderBySubtitle" approved="yes">
<source>Subtitle</source>
<target state="final">Untertitel</target>
</trans-unit>
<trans-unit id="changeOrderByNavtitle" approved="yes">
<source>Navigation title</source>
<target state="final">Navigationstitel</target>
</trans-unit>
<trans-unit id="changeOrderByTstamp" approved="yes">
<source>Change-time</source>
<target state="final">Änderungszeitpunkt</target>
</trans-unit>
<trans-unit id="changeOrderByCreate" approved="yes">
<source>Create-time</source>
<target state="final">Erzeugungszeitpunkt</target>
</trans-unit>
<trans-unit id="changeOrderReverse" approved="yes">
<source>Reverse current order</source>
<target state="final">Reihenfolge umkehren</target>
</trans-unit>
<trans-unit id="hasInvisiblePage.title" approved="yes">
<source>Invisible subpages</source>
<target state="final">Unsichtbare Unterseiten</target>
</trans-unit>
<trans-unit id="hasInvisiblePage.message" approved="yes">
<source>The page has invisible subpages which are not shown due to access restrictions. Those will not be sorted among others.</source>
<target state="final">Die Seite hat unsichtbare Unterseiten, die wegen Zugriffsbeschränkungen nicht angezeigt werden. Diese Unterseiten werden nicht mit den anderen sortiert werden.</target>
</trans-unit>
<trans-unit id="noSubpages.title" approved="yes">
<source>No subpages</source>
<target state="final">Keine Unterseiten</target>
</trans-unit>
<trans-unit id="noSubpages.message" approved="yes">
<source>Please select a page with subpages.</source>
<target state="final">Bitte wähle eine Seite mit Unterseiten.</target>
</trans-unit>
<trans-unit id="notAvailableInWorkspace.title" approved="yes">
<source>Not implemented</source>
<target state="final">Nicht implementiert</target>
</trans-unit>
<trans-unit id="notAvailableInWorkspace.message" approved="yes">
<source>Sorry, this function is not available in the current draft workspace!</source>
<target state="final">Entschuldigung, diese Funktion ist in der aktuellen Entwurfarbeitsumgebung nicht verfügbar!</target>
</trans-unit>
<trans-unit id="noEditPermissions" approved="yes">
<source>No edit permissions on this sub page. This page can not be re-sorted among others.</source>
<target state="final">Keine Bearbeitungsberechtigung auf dieser Unterseite. Diese Seite kann nicht mit den anderen neu sortiert werden.</target>
</trans-unit>
</body>
</file>
</xliff>
@@ -0,0 +1,212 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="en" datatype="plaintext" original="EXT:backend/Resources/Private/Language/locallang_pagetsconfig.xlf" date="2023-01-19T14:41:00Z" product-name="cms" target-language="de">
<header/>
<body>
<trans-unit id="module.pagetsconfig.title" approved="yes">
<source>Page TSconfig</source>
<target state="final">Page TSconfig</target>
</trans-unit>
<trans-unit id="module.pagetsconfig.description" approved="yes">
<source>The page TSconfig module lets you manage configuration overrides for editors and option display throughout the Backend.</source>
<target state="final">Mit dem Page TSconfig Modul können Sie Konfigurationsüberschreibungen für Redakteure und die Anzeige von Optionen im gesamten Backend verwalten.</target>
</trans-unit>
<trans-unit id="module.pagetsconfig.shortDescription" approved="yes">
<source>Page TSconfig tools</source>
<target state="final">Page TSconfig Tools</target>
</trans-unit>
<trans-unit id="module.pagetsconfig.noAccess" approved="yes">
<source>Access to this module denied.</source>
<target state="final">Zugriff auf dieses Modul verweigert.</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_pages" approved="yes">
<source>Pages containing page TSconfig</source>
<target state="final">Seiten, die Page TSconfig enthalten</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_pages.headline" approved="yes">
<source>Pages containing page TSconfig</source>
<target state="final">Seiten, die Page TSconfig enthalten</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_pages.description" approved="yes">
<source>Global overview of all pages in the database containing page TSconfig.</source>
<target state="final">Globale Übersicht aller Seiten in der Datenbank, die benutzerdefiniertes Page TSconfig enthalten.</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_pages.noRecords" approved="yes">
<source>There are no pages containing page TSconfig settings in the page configuration.</source>
<target state="final">Es gibt keine Seiten mit Page TSconfig-Einstellungen in der Seitenkonfiguration.</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_pages.pagetitle" approved="yes">
<source>Page title</source>
<target state="final">Seitentitel</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_pages.written_tsconfig_lines" approved="yes">
<source>Number of lines of code in field "TSconfig"</source>
<target state="final">Anzahl der Codezeilen im Feld "TSconfig"</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_active" approved="yes">
<source>Active page TSconfig</source>
<target state="final">Aktive Page TSconfig</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_active.headline" approved="yes">
<source>Active page TSconfig of page "%s"</source>
<target state="final">Aktive Page TSconfig auf Seite "%s"</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_active.description" approved="yes">
<source>Overview of the current page TSconfig of the system. A targeted search for values and names is possible. The list of results can also be filtered according to conditions.</source>
<target state="final">Übersicht des aktuell geladenen Page TSconfig dieses Systems. Eine gezielte Suche nach Werten und Namen ist möglich. Die Ergebnisliste kann auch nach Bedingungen gefiltert werden.</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_active.displayConstantSubstitutions" approved="yes">
<source>Substitute constants in page TSconfig</source>
<target state="final">Konstanten in Page TSconfig ersetzen</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_active.displayComments" approved="yes">
<source>Display comments</source>
<target state="final">Kommentare anzeigen</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_active.sortAlphabetically" approved="yes">
<source>Sort keys alphabetically</source>
<target state="final">Schlüssel alphabetisch sortieren</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_active.panel.header.conditions" approved="yes">
<source>Conditions</source>
<target state="final">Bedingungen</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_active.panel.header.numberOfSearchMatches" approved="yes">
<source>%s search match(es)</source>
<target state="final">%s Suchergebnis(se)</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_active.panel.info.conditionActiveCount.multiple" approved="yes">
<source>%s active conditions</source>
<target state="final">%s aktive Bedingungen</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_active.panel.info.conditionActiveCount.single" approved="yes">
<source>%s active condition</source>
<target state="final">%s aktive Bedingung</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_active.panel.info.conditionWithConstant" approved="yes">
<source>Site settings usage: [%s]</source>
<target state="final">Site-Einstellungen Nutzung: [%s]</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_active.panel.header.configuration" approved="yes">
<source>Configuration</source>
<target state="final">Konfiguration</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_active.siteSettings" approved="yes">
<source>Constants from site settings</source>
<target state="final">Konstanten aus der Site-Konfiguration</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_active.activePageTsConfig" approved="yes">
<source>Page TSconfig</source>
<target state="final">Page TSconfig</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_active.noPageTSconfigAvailable" approved="yes">
<source>No suitable page TSconfig available.</source>
<target state="final">Keine passende Page TSconfig verfügbar.</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_active.tree.valueWithConstant" approved="yes">
<source>Constant usage: [%s]</source>
<target state="final">Konstanten-Nutzung: [%s]</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_includes" approved="yes">
<source>Included page TSconfig</source>
<target state="final">Eingebundene Page TSconfig</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_includes.headline" approved="yes">
<source>Included page TSconfig of page "%s"</source>
<target state="final">Eingebundene Page TSconfig auf der Seite "%s"</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_includes.description" approved="yes">
<source>Overview of the included TypoScript and include order for the current page.</source>
<target state="final">Übersicht eingebundener TypoScript Datensätze sowie deren Ladereihenfolge für die aktuell ausgewählte Seite.</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_includes.siteSettings" approved="yes">
<source>Constants from site settings</source>
<target state="final">Konstanten aus Site-Konfiguration</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_includes.pagetsconfig" approved="yes">
<source>Page TSconfig</source>
<target state="final">Page TSconfig</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_includes.panel.header.configuration" approved="yes">
<source>Configuration</source>
<target state="final">Konfiguration</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_includes.panel.header.syntaxErrors" approved="yes">
<source>Syntax scanner warnings</source>
<target state="final">Warnungen des Syntax-Scanner</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_includes.panel.info.syntaxErrorCount.single" approved="yes">
<source>%s syntax warning</source>
<target state="final">%s Syntax-Warnung</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_includes.panel.info.syntaxErrorCount.multiple" approved="yes">
<source>%s syntax warnings</source>
<target state="final">%s Syntax-Warnungen</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_includes.syntaxError.sourceCode" approved="yes">
<source>Show affected code snippet</source>
<target state="final">Zeige betroffenes Code-Snippet</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_includes.syntaxError.type.line.invalid" approved="yes">
<source>Invalid line in "%1$s", line number "%2$s"</source>
<target state="final">Ungültige Zeile in "%1$s", Zeilennummer "%2$s"</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_includes.syntaxError.type.brace.excess" approved="yes">
<source>Brace in excess in "%1$s", line number "%2$s"</source>
<target state="final">Klammer zu viel in "%1$s", Zeilennummer "%2$s"</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_includes.syntaxError.type.brace.missing" approved="yes">
<source>Brace missing in "%1$s", line number "%2$s"</source>
<target state="final">Klammer fehlt in "%1$s", Zeilennummer "%2$s"</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_includes.syntaxError.type.import.empty" approved="yes">
<source>Import does not find a file in "%1$s", line number "%2$s"</source>
<target state="final">Der Import findet keine Datei in "%1$s", Zeile "%2$s"</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_includes.tree.child.type.Segment" approved="yes">
<source>Code segment</source>
<target state="final">Code-Segment</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_includes.tree.child.type.AtImport" approved="yes">
<source>Included via "@import"</source>
<target state="final">Eingebunden via "@import"</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_includes.tree.child.type.Condition" approved="yes">
<source>Condition (then)</source>
<target state="final">Bedingung (then)</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_includes.tree.child.type.ConditionElse" approved="yes">
<source>Condition (else)</source>
<target state="final">Bedingung (else)</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_includes.tree.child.type.ConditionStop" approved="yes">
<source>Condition (end)</source>
<target state="final">Bedingung (Ende)</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_includes.tree.child.type.ConditionIncludeTyposcript" approved="yes">
<source>Included via "INCLUDE_TYPOSCRIPT" (deprecated, with condition)</source>
<target state="final">Eingebunden via "INCLUDE_TYPOSPOSCRIPT" (veraltet, mit Bedingung)</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_includes.tree.child.type.IncludeTyposcript" approved="yes">
<source>Included via "INCLUDE_TYPOSCRIPT" (deprecated)</source>
<target state="final">Eingebunden via "INCLUDE_TYPOSPOSCRIPT" (veraltet)</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_includes.tree.child.type.TsConfig" approved="yes">
<source>TSconfig</source>
<target state="final">TsConfig</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_includes.tree.child.type.Site" approved="yes">
<source>Site</source>
<target state="final">Site</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_includes.tree.child.btn.sourceCode" approved="yes">
<source>Show code</source>
<target state="final">Code anzeigen</target>
</trans-unit>
<trans-unit id="module.pagetsconfig_includes.tree.child.btn.sourceCodeWithResolvedIncludes" approved="yes">
<source>Show code including possible includes/imports</source>
<target state="final">Code inklusive möglicher Einbindungen/Importe anzeigen</target>
</trans-unit>
</body>
</file>
</xliff>
@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="en" datatype="plaintext" original="EXT:backend/Resources/Private/Language/locallang_reset_password.xlf" date="2020-03-06T11:16:11Z" product-name="backend" target-language="de">
<header/>
<body>
<trans-unit id="headline" approved="yes">
<source>Reset Your Password</source>
<target state="final">Setze dein Passwort zurück</target>
</trans-unit>
<trans-unit id="instructions.email" approved="yes">
<source>To reset your password, enter the email address stored in the backend user account.</source>
<target state="final">Um Ihr Passwort zurückzusetzen, geben Sie die im Backend Benutzerkonto gespeicherte E-Mail-Adresse ein.</target>
</trans-unit>
<trans-unit id="instructions.password" approved="yes">
<source>Enter a new password to reset your current password.</source>
<target state="final">Gib ein neues Passwort ein, um dein aktuelles Passwort zurückzusetzen.</target>
</trans-unit>
<trans-unit id="instructions.password_requirement" approved="yes">
<source>To reset your password, ensure that your new password matches the following requirements:</source>
<target state="final">Um Ihr Passwort zurückzusetzen, stellen Sie sicher, dass Ihr neues Passwort den folgenden Anforderungen entspricht:</target>
</trans-unit>
<trans-unit id="note.other_providers" approved="yes">
<source>Note: If you're using a centralized user management system such as LDAP, OAuth or Active Directory, you might not receive an email.</source>
<target state="final">Hinweis: Wenn du ein zentralisiertes Benutzerverwaltungssystem wie LDAP, OAuth oder Active Directory verwendest, erhältst du möglicherweise keine E-Mail.</target>
</trans-unit>
<trans-unit id="email_sent.headline" approved="yes">
<source>Check your inbox!</source>
<target state="final">Überprüfe deinen Posteingang!</target>
</trans-unit>
<trans-unit id="email_sent.message" approved="yes">
<source><![CDATA[If a backend user with the email address "%s" exists, an email has been sent to this address. Please check your inbox and spam folder.]]></source>
<target state="final"><![CDATA[Wenn ein Backend-Benutzer mit der E-Mail-Adresse "%s" existiert, wurde eine E-Mail an diese Adresse gesendet. Bitte überprüfen Sie Ihren Posteingang und den Spam-Ordner.]]></target>
</trans-unit>
<trans-unit id="reset_success.headline" approved="yes">
<source>You've successfully reset your password!</source>
<target state="final">Sie haben Ihr Passwort erfolgreich zurückgesetzt!</target>
</trans-unit>
<trans-unit id="reset_success.message" approved="yes">
<source><![CDATA[With your new credentials you can now log in to the <a href="%s">TYPO3 backend</a>.]]></source>
<target state="final"><![CDATA[Mit Ihren neuen Zugangsdaten können Sie sich jetzt im <a href="%s">TYPO3 Backend</a> einloggen.]]></target>
</trans-unit>
<trans-unit id="input.email" approved="yes">
<source>Enter your email address</source>
<target state="final">E-Mail-Adresse eingeben</target>
</trans-unit>
<trans-unit id="input.password" approved="yes">
<source>Enter your new password</source>
<target state="final">Geben Sie Ihr neues Passwort ein</target>
</trans-unit>
<trans-unit id="input.passwordrepeat" approved="yes">
<source>Enter your new password again</source>
<target state="final">Wiederholen Sie das neue Passwort</target>
</trans-unit>
<trans-unit id="button.initiate" approved="yes">
<source>Get Reset Link</source>
<target state="final">Link zum Zurücksetzen zusenden</target>
</trans-unit>
<trans-unit id="button.reset" approved="yes">
<source>Reset Your Password Now</source>
<target state="final">Setzen Sie Ihr Passwort jetzt zurück</target>
</trans-unit>
<trans-unit id="button.restart" approved="yes">
<source>Start over</source>
<target state="final">Neu starten</target>
</trans-unit>
<trans-unit id="button.back_to_login" approved="yes">
<source>Go back to login page</source>
<target state="final">Zurück zur Anmeldeseite</target>
</trans-unit>
<trans-unit id="error.invalid_email" approved="yes">
<source>The entered email address is invalid. Please try again.</source>
<target state="final">Die eingegebene E-Mail-Adresse ist ungültig. Bitte versuchen Sie es erneut.</target>
</trans-unit>
<trans-unit id="error.token_expired" approved="yes">
<source>The password reset link is invalid or has expired.</source>
<target state="final">Der Link zum Zurücksetzen Ihres Passworts ist entweder ungültig oder abgelaufen.</target>
</trans-unit>
<trans-unit id="error.password" approved="yes">
<source>The password you entered is invalid or the passwords do not match. Please try again.</source>
<target state="final">Das eingegebene Passwort ist ungültig oder die Passwörter stimmen nicht überein. Bitte versuchen Sie es erneut.</target>
</trans-unit>
</body>
</file>
</xliff>
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="en" datatype="plaintext" original="EXT:backend/Resources/Private/Language/locallang_resource.xlf" date="2023-02-21T00:00:00Z" product-name="cms" target-language="de">
<header/>
<body>
<trans-unit id="ajax.success" approved="yes">
<source>Success</source>
<target state="final">Erfolgreich</target>
</trans-unit>
<trans-unit id="ajax.success.message.renamed" approved="yes">
<source>The resource "%s" has been renamed to "%s".</source>
<target state="final">Die Ressource "%s" wurde in "%s" umbenannt.</target>
</trans-unit>
<trans-unit id="ajax.error" approved="yes">
<source>An error occurred</source>
<target state="final">Es ist ein Fehler aufgetreten</target>
</trans-unit>
<trans-unit id="ajax.error.message.resourceNotFileOrFolder" approved="yes">
<source>The resource must be a file or a folder.</source>
<target state="final">Die Ressource muss eine Datei oder ein Ordner sein.</target>
</trans-unit>
<trans-unit id="ajax.error.message.resourceOutsideOfStorages" approved="yes">
<source>Access to files outside your configured storages is not permitted.</source>
<target state="final">Der Zugriff auf Dateien außerhalb Ihres konfigurierten Speichers ist nicht gestattet.</target>
</trans-unit>
<trans-unit id="ajax.error.message.resourceNoPermissionRead" approved="yes">
<source>Reading this resource is not permitted.</source>
<target state="final">Das Lesen dieser Ressource ist nicht erlaubt.</target>
</trans-unit>
<trans-unit id="ajax.error.message.resourceNoPermissionRename" approved="yes">
<source>Renaming this resource is not permitted.</source>
<target state="final">Umbenennen dieser Ressource ist nicht zulässig.</target>
</trans-unit>
<trans-unit id="ajax.error.message.resourceNameCannotBeEmpty" approved="yes">
<source>The resource name cannot be empty.</source>
<target state="final">Der Name einer Ressource darf nicht leer sein.</target>
</trans-unit>
<trans-unit id="ajax.error.message.resourceNameNotDifferent" approved="yes">
<source>The resource %s already has this name. No changes were made.</source>
<target state="final">Die Ressource %s hat diesen Namen. Es wurden keine Änderungen vorgenommen.</target>
</trans-unit>
<trans-unit id="ajax.error.message.resourceNotRenamed" approved="yes">
<source>The resource %s could not be renamed.</source>
<target state="final">Die Ressource %s konnte nicht umbenannt werden.</target>
</trans-unit>
</body>
</file>
</xliff>
@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="en" datatype="plaintext" original="EXT:backend/Resources/Private/Language/locallang_settingseditor.xlf" date="2024-09-10T12:13:00Z" product-name="backend" target-language="de">
<header/>
<body>
<trans-unit id="settingseditor.mode.minimal" approved="yes">
<source>Minimal</source>
<target state="final">Minimal</target>
</trans-unit>
<trans-unit id="settingseditor.mode.basic" approved="yes">
<source>Basic</source>
<target state="final">Basis</target>
</trans-unit>
<trans-unit id="settingseditor.mode.advanced" approved="yes">
<source>Advanced</source>
<target state="final">Erweitert</target>
</trans-unit>
<trans-unit id="settingseditor.edit.resetSetting" approved="yes">
<source>Reset setting</source>
<target state="final">Einstellung zurücksetzen</target>
</trans-unit>
<trans-unit id="settingseditor.edit.copySettingsIdentifier" approved="yes">
<source>Copy identifier</source>
<target state="final">Bezeichner kopieren</target>
</trans-unit>
<trans-unit id="settingseditor.edit.copyAsYaml" approved="yes">
<source>Copy as YAML</source>
<target state="final">Als YAML kopieren</target>
</trans-unit>
<trans-unit id="settingseditor.search.searchTermVisuallyHiddenLabel" approved="yes">
<source>Search settings</source>
<target state="final">Sucheinstellungen</target>
</trans-unit>
<trans-unit id="settingseditor.search.searchTermPlaceholder" approved="yes">
<source>Search settings</source>
<target state="final">Einstellungen durchsuchen</target>
</trans-unit>
<trans-unit id="settingseditor.search.noResultsTitle" approved="yes">
<source>No settings were found.</source>
<target state="final">Es wurden keine Einstellungen gefunden.</target>
</trans-unit>
<trans-unit id="settingseditor.search.noResultsMessage" approved="yes">
<source>The search filters by setting value, label, description or identifier.</source>
<target state="final">Die Suche filtert nach Einstellungswert, Bezeichnung, Beschreibung oder Bezeichner.</target>
</trans-unit>
<trans-unit id="settingseditor.search.noResultsResetButtonLabel" approved="yes">
<source>Reset filter</source>
<target state="final">Filter zurücksetzen</target>
</trans-unit>
<trans-unit id="settingseditor.type.page.button" approved="yes">
<source>Select page</source>
<target state="final">Seite auswählen</target>
</trans-unit>
</body>
</file>
</xliff>
Loaded 100 of 197 files, more files were not shown because too many files have changed in this diff. Show more