diff --git a/assets/images/operator-search/cd-website.webp b/assets/images/operator-search/cd-website.webp new file mode 100644 index 00000000..3f5a7e86 Binary files /dev/null and b/assets/images/operator-search/cd-website.webp differ diff --git a/assets/images/operator-search/db-website.de.webp b/assets/images/operator-search/db-website.de.webp new file mode 100644 index 00000000..46f87c83 Binary files /dev/null and b/assets/images/operator-search/db-website.de.webp differ diff --git a/assets/images/operator-search/db-website.en.webp b/assets/images/operator-search/db-website.en.webp new file mode 100644 index 00000000..ba53d509 Binary files /dev/null and b/assets/images/operator-search/db-website.en.webp differ diff --git a/assets/images/operator-search/db-website.fr.webp b/assets/images/operator-search/db-website.fr.webp new file mode 100644 index 00000000..7974a6fc Binary files /dev/null and b/assets/images/operator-search/db-website.fr.webp differ diff --git a/assets/sass/main.scss b/assets/sass/main.scss index 639c39d7..b8d47354 100644 --- a/assets/sass/main.scss +++ b/assets/sass/main.scss @@ -13,6 +13,7 @@ @import "expander.scss"; @import "anchorlink.scss"; @import "booking.scss"; +@import "operatorSearch.scss"; @import "button.scss"; @import "startpage.scss"; @import "interactiveMap.scss"; diff --git a/assets/sass/operatorSearch.scss b/assets/sass/operatorSearch.scss new file mode 100644 index 00000000..94daabe1 --- /dev/null +++ b/assets/sass/operatorSearch.scss @@ -0,0 +1,71 @@ +.o-operator-search__item { + margin-bottom: 2rem; + + &:last-child { + margin-bottom: 0; + } +} + +.o-operator-search__item-title { + margin-top: 0; + margin-bottom: 1.5rem; + font-size: 2rem; +} + +.o-operator-search__item-content { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 3rem; + align-items: start; + + @media (max-width: #{$breakpoint-md}) { + grid-template-columns: 1fr; + gap: 2rem; + } +} + +.o-operator-search__text { + display: flex; + flex-direction: column; + gap: 2rem; +} + +.o-operator-search__image-wrapper { + order: 2; + + @media (max-width: #{$breakpoint-md}) { + order: 1; + } + + img { + width: 100%; + height: auto; + border-radius: var(--border-radius-m); + } +} + +.o-operator-search__actions { + margin-top: 1rem; +} + +.o-operator-search__separator { + margin: 3rem 0; +} + +.o-operator-search__header { + display: flex; + gap: 1rem; + align-items: center; + width: 100%; +} + +.o-operator-search__title { + display: flex; + gap: 0.4rem; + align-items: center; + font-weight: 600; +} + +.o-operator-search__title-text { + line-height: 1.1; +} diff --git a/content/country/czechia/index.de.md b/content/country/czechia/index.de.md index 206d7f20..8f8ea8f5 100644 --- a/content/country/czechia/index.de.md +++ b/content/country/czechia/index.de.md @@ -19,6 +19,8 @@ Tschechien ist nicht das einfachste Land für die Nutzung von FIP, lässt sich j Jedoch ist zu beachten, dass nicht mehr auf allen Strecken, auf denen die ČD fährt, auch FIP gültig ist. Zudem gibt es einzelne _kommerzielle Verbindungen_, bei denen ein Aufschlag zu zahlen ist. Mit einem FIP-Freifahrtschein müssen diese Ausnahmen alle beachtet werden, bei durch die ČD verkauften FIP 50 Tickets sollte es einfacher erkenntlich sein, für welche Züge diese gelten. Bei den privaten Betreibern wie Arriva oder Die Länderbahn wird FIP in keinem Fall anerkannt, allerdings sind die Tickets in Tschechien vergleichsweise günstig. +{{< operator-search operators="db-website,cd-website" >}} + ## Wissenswertes Tschechien besitzt eines der dichtesten Bahnnetze weltweit. Es ist somit möglich, in viele Orte des Landes per Bahn zu gelangen. Die Geschwindigkeiten sind meist nicht besonders hoch, auch gibt es bisher keine Hochgeschwindigkeitsstrecken im Land. Trotzdem ist der Reisekomfort meistens gut oder es herrscht zumindest eine gewisse Nostalgie in älteren Zügen mit. diff --git a/content/country/czechia/index.en.md b/content/country/czechia/index.en.md index 78252612..02505f15 100644 --- a/content/country/czechia/index.en.md +++ b/content/country/czechia/index.en.md @@ -19,6 +19,8 @@ Czechia is not the easiest country for using FIP, but it is still quite possible However, note that FIP is no longer valid on all routes operated by ČD. There are also some _commercial services_ where a supplement must be paid. With a FIP Coupon, all these exceptions must be considered, while FIP 50 Tickets sold by ČD should make it easier to see which trains are valid. Private operators like Arriva or Die Länderbahn do not accept FIP at all, but tickets in Czechia are generally quite affordable. +{{< operator-search operators="db-website,cd-website" >}} + ## Interesting Czechia has one of the densest rail networks in the world. It is possible to reach many places in the country by train. Speeds are usually not very high, and there are currently no high-speed lines in the country. Nevertheless, travel comfort is usually good, or there is at least a certain nostalgia in older trains. diff --git a/content/country/czechia/index.fr.md b/content/country/czechia/index.fr.md index 51f3783b..cae8a791 100644 --- a/content/country/czechia/index.fr.md +++ b/content/country/czechia/index.fr.md @@ -19,6 +19,8 @@ La Tchéquie n'est pas le pays le plus simple pour utiliser la FIP, mais il rest Attention, la FIP n'est plus valable sur toutes les lignes exploitées par la ČD. Il existe aussi certains _services commerciaux_ nécessitant un supplément. Avec un Coupon FIP, il faut tenir compte de toutes ces exceptions, tandis que les Billets FIP 50 vendus par la ČD devraient permettre d'identifier plus facilement les trains valables. Les opérateurs privés comme Arriva ou Die Länderbahn n'acceptent pas du tout la FIP, mais les billets en Tchéquie restent généralement très abordables. +{{< operator-search operators="db-website,cd-website" >}} + ## Informations générales La Tchéquie possède l'un des réseaux ferroviaires les plus denses au monde. Il est possible de rejoindre de nombreux endroits du pays en train. Les vitesses ne sont généralement pas très élevées et il n'existe actuellement pas de lignes à grande vitesse. Le confort de voyage est cependant bon, ou il règne au moins une certaine nostalgie dans les trains plus anciens. diff --git a/data/operator-search/cd-website/index.de.md b/data/operator-search/cd-website/index.de.md new file mode 100644 index 00000000..ff73bf9f --- /dev/null +++ b/data/operator-search/cd-website/index.de.md @@ -0,0 +1,7 @@ +--- +title: "DB Website" +url: "https://example.com/de/mehr" +--- + +Willkommen auf unserer deutschen Seite! +Hier erfährst du mehr über unsere Produkte. diff --git a/data/operator-search/cd-website/index.en.md b/data/operator-search/cd-website/index.en.md new file mode 100644 index 00000000..41991af4 --- /dev/null +++ b/data/operator-search/cd-website/index.en.md @@ -0,0 +1,7 @@ +--- +title: "DB Website" +url: "https://example.com/en/more" +--- + +Welcome to our English page! +Find out more about our services here. diff --git a/data/operator-search/cd-website/index.fr.md b/data/operator-search/cd-website/index.fr.md new file mode 100644 index 00000000..325c572b --- /dev/null +++ b/data/operator-search/cd-website/index.fr.md @@ -0,0 +1,7 @@ +--- +title: "DB Website" +url: "https://example.com/fr/plus" +--- + +Bienvenue sur notre page française! +Découvrez nos services ici. diff --git a/data/operator-search/db-website/index.de.md b/data/operator-search/db-website/index.de.md new file mode 100644 index 00000000..7b228087 --- /dev/null +++ b/data/operator-search/db-website/index.de.md @@ -0,0 +1,6 @@ +--- +title: "DB Website" +url: "https://bahn.de" +--- + +Die Zug kann mit der Verbindungsauskunft gesucht werden. In den _Weiteren Informationen_ des Zuges ist der Betreiber (_Beförderer_) angegeben. Bei grenzüberschreitenden Verbindungen sind oftmals mehrere Betreiber beteiligt. diff --git a/data/operator-search/db-website/index.en.md b/data/operator-search/db-website/index.en.md new file mode 100644 index 00000000..45f3bb14 --- /dev/null +++ b/data/operator-search/db-website/index.en.md @@ -0,0 +1,6 @@ +--- +title: "DB Website" +url: "https://int.bahn.de/en" +--- + +You can search for trains using the journey planner. In the _More Information_ section for each train, the operator is specified. For cross-border connections, multiple operators are often involved. diff --git a/data/operator-search/db-website/index.fr.md b/data/operator-search/db-website/index.fr.md new file mode 100644 index 00000000..c2c78937 --- /dev/null +++ b/data/operator-search/db-website/index.fr.md @@ -0,0 +1,6 @@ +--- +title: "Site Web DB" +url: "https://int.bahn.de/fr" +--- + +Vous pouvez rechercher des trains à l’aide du planificateur de voyage. Dans la section _Informations supplémentaires_ de chaque train, l’opérateur (_Transporteur_) est indiqué. Pour les liaisons transfrontalières, plusieurs opérateurs sont souvent impliqués. diff --git a/i18n/de.yaml b/i18n/de.yaml index ea8efe6c..d1247c4b 100644 --- a/i18n/de.yaml +++ b/i18n/de.yaml @@ -78,6 +78,9 @@ menu: navigate-to-country: Gehe zu Land news-headline: Was gibt's Neues? news-other: Weitere News +operator-search: + learn-more: Zur Website + title: Zugbetreiber identifizieren operators_without_fip: Betreiber ohne FIP related: countries: Verwandte Länder diff --git a/i18n/en.yaml b/i18n/en.yaml index c55f8f6e..2a0f7041 100644 --- a/i18n/en.yaml +++ b/i18n/en.yaml @@ -77,6 +77,9 @@ menu: navigate-to-country: Navigate to country news-headline: What's new? news-other: Other News +operator-search: + learn-more: To Website + title: Identify Train Operators operators_without_fip: Operators without FIP related: countries: Related Countries diff --git a/i18n/fr.yaml b/i18n/fr.yaml index aa3fd665..4b94db49 100644 --- a/i18n/fr.yaml +++ b/i18n/fr.yaml @@ -77,6 +77,9 @@ menu: navigate-to-country: Aller au pays news-headline: Quoi de neuf ? news-other: Autres actualités +operator-search: + learn-more: Vers le site Web + title: Identifier les opérateurs de trains operators_without_fip: Opérateurs sans FIP related: countries: Pays associés diff --git a/layouts/partials/operator-search.html b/layouts/partials/operator-search.html new file mode 100644 index 00000000..aecdc1eb --- /dev/null +++ b/layouts/partials/operator-search.html @@ -0,0 +1,52 @@ + +
+
+ {{- partial "icon" "search" -}} + {{ T "operator-search.title" }} +
+
+ {{- partial "icon" "keyboard_arrow_down" -}} +
+ +
+ {{ range $index, $operator := .operators }} + {{ if gt $index 0 }} +
+ {{ end }} + + +
+

{{ $operator.title }}

+ +
+
+
+ {{ $operator.content | $.original_page.RenderString | safeHTML }} +
+ + {{ if $operator.url }} + + {{ end }} +
+ + {{ if $operator.image_resource }} +
+ {{- partial "image" $operator.image_resource -}} +
+ {{ end }} +
+
+ {{ end }} +
diff --git a/layouts/shortcodes/operator-search.html b/layouts/shortcodes/operator-search.html new file mode 100644 index 00000000..f4bc1602 --- /dev/null +++ b/layouts/shortcodes/operator-search.html @@ -0,0 +1,75 @@ +{{ $operatorsParam := .Get "operators" }} +{{ $operators := split $operatorsParam "," }} +{{ $lang := .Site.Language.Lang }} + +{{ $operatorData := slice }} + +{{ range $operators }} + {{ $operator := strings.TrimSpace . }} + {{ $dir := printf "data/operator-search/%s" $operator }} + {{ $file := printf "%s/index.%s.md" $dir $lang }} + + {{ if not (fileExists $file) }} + {{ errorf "❌ Missing operator-search markdown: %q (language: %s)" $file $lang }} + {{ end }} + + {{ $raw := readFile $file }} + + {{ $url := "" }} + {{ $title := "" }} + {{ $content := $raw }} + + {{ if strings.Contains $raw "---" }} + {{ $parts := split $raw "---" }} + {{ if ge (len $parts) 3 }} + {{ $frontmatterStr := index $parts 1 }} + {{ range split $frontmatterStr "\n" }} + {{ if strings.Contains . "url:" }} + {{ $url = trim (index (split . "url:") 1) "\" \n\r" }} + {{ end }} + {{ if strings.Contains . "title:" }} + {{ $title = trim (index (split . "title:") 1) "\" \n\r" }} + {{ end }} + {{ end }} + {{ $content = strings.TrimSpace (index $parts 2) }} + {{ end }} + {{ end }} + + {{ $imagePath := printf "images/operator-search/%s.webp" $operator }} + {{ $imagePathLang := printf "images/operator-search/%s.%s.webp" $operator $lang }} + {{ $imageResource := "" }} + {{ with resources.Get $imagePathLang }} + {{ $imageResource = . }} + {{ else }} + {{ with resources.Get $imagePath }} + {{ $imageResource = . }} + {{ end }} + {{ end }} + + {{ if not $imageResource }} + {{ errorf "❌ Missing image for operator-search: %q (language: %s). Expected %q or %q" $operator $lang $imagePathLang $imagePath }} + {{ end }} + + {{ $item := dict + "title" $title + "image_resource" $imageResource + "url" $url + "content" $content + }} + + {{ $operatorData = $operatorData | append $item }} +{{ end }} + +{{ $params := dict + "operators" $operatorData + "original_page" .Page +}} + + + + +