Compare commits

...

11 Commits

27 changed files with 2026 additions and 276 deletions
+2 -1
View File
@@ -20,7 +20,7 @@ RewriteEngine on
# In some environments it's necessary to
# set the RewriteBase to:
#
# RewriteBase /
RewriteBase /
# block files and folders beginning with a dot, such as .git
# except for the .well-known folder, which is used for Let's Encrypt and security.txt
@@ -34,6 +34,7 @@ RewriteRule ^site/(.*) index.php [L]
# block direct access to Kirby and the Panel sources
RewriteRule ^kirby/(.*) index.php [L]
RewriteRule ^vendor/getkirby/(.*) index.php [L]
# make site links work
RewriteCond %{REQUEST_FILENAME} !-f
Generated
+47 -51
View File
@@ -67,16 +67,16 @@
},
{
"name": "claviska/simpleimage",
"version": "4.2.1",
"version": "4.4.0",
"source": {
"type": "git",
"url": "https://github.com/claviska/SimpleImage.git",
"reference": "ec6d5021e5a7153a2520d64c59b86b6f3c4157c5"
"reference": "6d928c779e343100cef40f75bac3e301c32c3741"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/claviska/SimpleImage/zipball/ec6d5021e5a7153a2520d64c59b86b6f3c4157c5",
"reference": "ec6d5021e5a7153a2520d64c59b86b6f3c4157c5",
"url": "https://api.github.com/repos/claviska/SimpleImage/zipball/6d928c779e343100cef40f75bac3e301c32c3741",
"reference": "6d928c779e343100cef40f75bac3e301c32c3741",
"shasum": ""
},
"require": {
@@ -108,7 +108,7 @@
"description": "A PHP class that makes working with images as simple as possible.",
"support": {
"issues": "https://github.com/claviska/SimpleImage/issues",
"source": "https://github.com/claviska/SimpleImage/tree/4.2.1"
"source": "https://github.com/claviska/SimpleImage/tree/4.4.0"
},
"funding": [
{
@@ -116,7 +116,7 @@
"type": "github"
}
],
"time": "2024-11-22T13:25:03+00:00"
"time": "2025-11-20T16:58:37+00:00"
},
{
"name": "composer/semver",
@@ -268,21 +268,21 @@
},
{
"name": "getkirby/cms",
"version": "5.1.1",
"version": "5.2.1",
"source": {
"type": "git",
"url": "https://github.com/getkirby/kirby.git",
"reference": "fb11f5e3ec422e948fb1a52f16988335bb3489b4"
"reference": "42cd286dab62d87a331e53abfe103e4fba118dd6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/getkirby/kirby/zipball/fb11f5e3ec422e948fb1a52f16988335bb3489b4",
"reference": "fb11f5e3ec422e948fb1a52f16988335bb3489b4",
"url": "https://api.github.com/repos/getkirby/kirby/zipball/42cd286dab62d87a331e53abfe103e4fba118dd6",
"reference": "42cd286dab62d87a331e53abfe103e4fba118dd6",
"shasum": ""
},
"require": {
"christian-riesen/base32": "1.6.0",
"claviska/simpleimage": "4.2.1",
"claviska/simpleimage": "4.4.0",
"composer/semver": "3.4.4",
"ext-ctype": "*",
"ext-curl": "*",
@@ -297,36 +297,31 @@
"ext-simplexml": "*",
"filp/whoops": "2.18.4",
"getkirby/composer-installer": "^1.2.1",
"laminas/laminas-escaper": "2.17.0",
"laminas/laminas-escaper": "2.18.0",
"michelf/php-smartypants": "1.8.1",
"php": "~8.2.0 || ~8.3.0 || ~8.4.0",
"phpmailer/phpmailer": "6.10.0",
"php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0",
"phpmailer/phpmailer": "7.0.1",
"symfony/polyfill-intl-idn": "1.33.0",
"symfony/polyfill-mbstring": "1.33.0",
"symfony/yaml": "7.3.3"
"symfony/yaml": "7.4.1"
},
"replace": {
"symfony/polyfill-php72": "*"
},
"suggest": {
"ext-PDO": "Support for using databases",
"ext-apcu": "Support for the Apcu cache driver",
"ext-exif": "Support for exif information from images",
"ext-fileinfo": "Improved mime type detection for files",
"ext-imagick": "Improved thumbnail generation",
"ext-intl": "Improved i18n number formatting",
"ext-memcached": "Support for the Memcached cache driver",
"ext-pdo": "Support for using databases",
"ext-redis": "Support for the Redis cache driver",
"ext-sodium": "Support for the crypto class and more robust session handling",
"ext-zip": "Support for ZIP archive file functions",
"ext-zlib": "Sanitization and validation for svgz files"
},
"type": "kirby-cms",
"extra": {
"unused": [
"symfony/polyfill-intl-idn"
]
},
"autoload": {
"files": [
"config/setup.php",
@@ -369,7 +364,7 @@
"type": "custom"
}
],
"time": "2025-09-16T13:06:53+00:00"
"time": "2025-12-16T09:23:12+00:00"
},
{
"name": "getkirby/composer-installer",
@@ -420,32 +415,32 @@
},
{
"name": "laminas/laminas-escaper",
"version": "2.17.0",
"version": "2.18.0",
"source": {
"type": "git",
"url": "https://github.com/laminas/laminas-escaper.git",
"reference": "df1ef9503299a8e3920079a16263b578eaf7c3ba"
"reference": "06f211dfffff18d91844c1f55250d5d13c007e18"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/df1ef9503299a8e3920079a16263b578eaf7c3ba",
"reference": "df1ef9503299a8e3920079a16263b578eaf7c3ba",
"url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/06f211dfffff18d91844c1f55250d5d13c007e18",
"reference": "06f211dfffff18d91844c1f55250d5d13c007e18",
"shasum": ""
},
"require": {
"ext-ctype": "*",
"ext-mbstring": "*",
"php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0"
"php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0"
},
"conflict": {
"zendframework/zend-escaper": "*"
},
"require-dev": {
"infection/infection": "^0.29.8",
"laminas/laminas-coding-standard": "~3.0.1",
"phpunit/phpunit": "^10.5.45",
"psalm/plugin-phpunit": "^0.19.2",
"vimeo/psalm": "^6.6.2"
"infection/infection": "^0.31.0",
"laminas/laminas-coding-standard": "~3.1.0",
"phpunit/phpunit": "^11.5.42",
"psalm/plugin-phpunit": "^0.19.5",
"vimeo/psalm": "^6.13.1"
},
"type": "library",
"autoload": {
@@ -477,7 +472,7 @@
"type": "community_bridge"
}
],
"time": "2025-05-06T19:29:36+00:00"
"time": "2025-10-14T18:31:13+00:00"
},
{
"name": "league/color-extractor",
@@ -596,16 +591,16 @@
},
{
"name": "phpmailer/phpmailer",
"version": "v6.10.0",
"version": "v7.0.1",
"source": {
"type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git",
"reference": "bf74d75a1fde6beaa34a0ddae2ec5fce0f72a144"
"reference": "360ae911ce62e25e11249f6140fa58939f556ebe"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/bf74d75a1fde6beaa34a0ddae2ec5fce0f72a144",
"reference": "bf74d75a1fde6beaa34a0ddae2ec5fce0f72a144",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/360ae911ce62e25e11249f6140fa58939f556ebe",
"reference": "360ae911ce62e25e11249f6140fa58939f556ebe",
"shasum": ""
},
"require": {
@@ -619,13 +614,14 @@
"doctrine/annotations": "^1.2.6 || ^1.13.3",
"php-parallel-lint/php-console-highlighter": "^1.0.0",
"php-parallel-lint/php-parallel-lint": "^1.3.2",
"phpcompatibility/php-compatibility": "^9.3.5",
"roave/security-advisories": "dev-latest",
"squizlabs/php_codesniffer": "^3.7.2",
"phpcompatibility/php-compatibility": "^10.0.0@dev",
"squizlabs/php_codesniffer": "^3.13.5",
"yoast/phpunit-polyfills": "^1.0.4"
},
"suggest": {
"decomplexity/SendOauth2": "Adapter for using XOAUTH2 authentication",
"directorytree/imapengine": "For uploading sent messages via IMAP, see gmail example",
"ext-imap": "Needed to support advanced email address parsing according to RFC822",
"ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses",
"ext-openssl": "Needed for secure SMTP sending and DKIM signing",
"greew/oauth2-azure-provider": "Needed for Microsoft Azure XOAUTH2 authentication",
@@ -665,7 +661,7 @@
"description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"support": {
"issues": "https://github.com/PHPMailer/PHPMailer/issues",
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.10.0"
"source": "https://github.com/PHPMailer/PHPMailer/tree/v7.0.1"
},
"funding": [
{
@@ -673,7 +669,7 @@
"type": "github"
}
],
"time": "2025-04-24T15:19:31+00:00"
"time": "2025-11-25T07:18:09+00:00"
},
{
"name": "psr/log",
@@ -1134,28 +1130,28 @@
},
{
"name": "symfony/yaml",
"version": "v7.3.3",
"version": "v7.4.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
"reference": "d4f4a66866fe2451f61296924767280ab5732d9d"
"reference": "24dd4de28d2e3988b311751ac49e684d783e2345"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/d4f4a66866fe2451f61296924767280ab5732d9d",
"reference": "d4f4a66866fe2451f61296924767280ab5732d9d",
"url": "https://api.github.com/repos/symfony/yaml/zipball/24dd4de28d2e3988b311751ac49e684d783e2345",
"reference": "24dd4de28d2e3988b311751ac49e684d783e2345",
"shasum": ""
},
"require": {
"php": ">=8.2",
"symfony/deprecation-contracts": "^2.5|^3.0",
"symfony/deprecation-contracts": "^2.5|^3",
"symfony/polyfill-ctype": "^1.8"
},
"conflict": {
"symfony/console": "<6.4"
},
"require-dev": {
"symfony/console": "^6.4|^7.0"
"symfony/console": "^6.4|^7.0|^8.0"
},
"bin": [
"Resources/bin/yaml-lint"
@@ -1186,7 +1182,7 @@
"description": "Loads and dumps YAML files",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/yaml/tree/v7.3.3"
"source": "https://github.com/symfony/yaml/tree/v7.4.1"
},
"funding": [
{
@@ -1206,7 +1202,7 @@
"type": "tidelift"
}
],
"time": "2025-08-27T11:34:33+00:00"
"time": "2025-12-04T18:11:45+00:00"
}
],
"packages-dev": [],
@@ -1219,5 +1215,5 @@
"php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0"
},
"platform-dev": {},
"plugin-api-version": "2.6.0"
"plugin-api-version": "2.9.0"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 830 KiB

@@ -0,0 +1,5 @@
Uuid: bwjwjg6rtabbwkrt
----
Template: blocks/image
@@ -0,0 +1,15 @@
[Event "A-Klasse 2025/2026 - TSV Bindlach Aktionär 3"]
[Site "Bindlach"]
[Date "2025.11.30"]
[Round "4"]
[White "Feigel, Tobias"]
[Black "Dederer, Alexej"]
[Result "1-0"]
[WhiteElo "1358"]
[BlackElo "1487"]
[EventDate "2025.11.30"]
[ECO "B01"]
[PlyCount "57"]
1.e4 d5 2.exd5 Qxd5 3.Nc3 Qe6+ $146 4.Be2 Qg6 5.g3 $2 c6 6.d4 Bf5 7.Bd3 $2 Bxd3 8.cxd3 e6 9.Nf3 Qh5 $1 10.Qe2 Nf6 11.a3 Nbd7 12.Bf4 Nd5 13.Nxd5 Qxd5 14.O-O Nf6 15.Rfe1 Rd8 16.Qd1 Be7 17.Rc1 Qh5 $2 18.Re5 Qh3 19.Ng5 $1 Qg4 $4 20.f3 Qh5 21.Nxe6 $1 Qh3 22.Nxd8 Kxd8 23.Qb3 Qd7 24.Rce1 Qxd4+ $2 25.Kg2 Bc5 26.Rxc5 $1 Qxc5 27.Qxb7 Qa5 28.Re7 Qb6 29.Bc7+ 1-0
@@ -0,0 +1 @@
Uuid: zrylk3mmhvof3dy3
@@ -0,0 +1,80 @@
Title: 20251201-Erfolg-in-Bindlach
----
Blocks:
[
{
"content": {
"text": "<p>Nach drei Niederlagen in Folge fuhren wir am 30.11.2025 mit geringen Erwartungen zur 3.Mannschaft des TSV Bindlach.</p><p>An den Brettern 2 <strong>(Alexander Döge</strong>), 6 (<strong>Rainald Müller</strong>) und 8 (<strong>Reinhardt Schmalz</strong>) waren schnell Remisen vereinbart. Aber am Spitzenbrett konnte <strong>Dominik Döge</strong> in einem Springerendspiel mit Minusbauern das Unentschieden nicht realisieren und <strong>Fred Zimmerbauer</strong> am vierten Brett verlor nach einem missglückten Springerzug Material und schließlich die Partie. Die Bindlacher wähnten sich bei diesem Zwischenstand mit 3,5 zu 1,5 schon auf der Siegerstraße. Alles deutete schon auf eine erneute Niederlage der Spielgemeinschaft SF Bad Steben/TV Reinersreuth hin. </p><p>Aber die drei letzten Partien verliefen hochspannend mit einem glücklichen Finale für die Kurstädter. <strong>Tobias Feigel</strong> konnte mit einem Figurenopfer die schwache Königsstellung seines Gegners aufreißen und auf der 7. Reihe mit konzentriertem Schwerfigurenangriff dann mattsetzen. <strong>Klaus Frommelt</strong> übte mit den weißen Steinen einen großen Druck auf die gegnerische Stellung aus, opferte seine Qualität gegen eine Fünfbauernphalanx am Damenflügel, welche beim Vorrücken trotz großen Widerstandes seines Gegenübers nicht mehr aufzuhalten war. Jetzt lag es an <strong>Dominik Kadlic</strong> den nötigen Gewinnpunkt zum Mannschaftssieg einzufahren. In einer turbulenten Auseinandersetzung mit beiderseitigen Gewinnchancen konnte er nach Abtausch aller Schwerfiguren solide in ein gewonnenes Bauernendspiel abwickeln.</p><p>Ein überraschender Sieg gegen die favorisierten Bindlacher, welchen man eigentlich nicht erwarten konnte. Dies gibt Hoffnung für das neue Jahr, wenn man zum Heimspiel am 11.01.2026 die sehr stark besetzte 2.Vertretung des SC Bayreuth empfängt.</p>"
},
"id": "dea24cf8-2397-4bf7-83da-f1baab4a3ca8",
"isHidden": false,
"type": "text"
},
{
"content": {
"fen": "3k3r/pp3ppp/2p2n2/2b1R3/3q1B2/PQ1P1PP1/1P4KP/4R3 w - - 2 26"
},
"id": "f09ceaf2-6442-4b7f-8846-2df40fe0f6d0",
"isHidden": false,
"type": "fen"
},
{
"content": {
"text": "<p>Die Stellung stammt aus der Partie an Brett 7 von <strong>Tobias Feige</strong>l gegen <strong>Alexej Dederer</strong>, vor dem 26. Zug von Weiß. Tobias opferte mit 26. Txc5! seine Qualität zurück um dann nach 26. ... Dxc5 mit 27. Dxb7 gefolgt von Te7 und schließlich Lc7 einen gewinnbringenden Mattangriff zu starten, der nur durch Damenverlust aufgehalten werden konnte:</p>"
},
"id": "36746cbf-384a-4f6c-be7c-ed0233464d22",
"isHidden": false,
"type": "text"
},
{
"content": {
"fen": "3k3r/pQB1Rppp/1qp2n2/8/8/P2P1PP1/1P4KP/8 b - - 4 29"
},
"id": "f7e62a19-884e-472f-8f11-bb0e9fdaf9a4",
"isHidden": false,
"type": "fen"
},
{
"content": {
"text": "<p>Ein schönes Ende der Partie, die Alexej an der Stelle sofort aufgab!</p>"
},
"id": "7601756e-536a-4ed6-b299-8506ec9d1ae9",
"isHidden": false,
"type": "text"
}
]
----
Image: - file://bwjwjg6rtabbwkrt
----
Headline: Erfolg gegen Bindlach!
----
Subheadline: Der erste Sieg der Saison ist eingefahren!
----
Summary: Nach drei Niederlagen in Folge fuhren wir am 30.11.2025 mit geringen Erwartungen zur 3.Mannschaft des TSV Bindlach - zu Unrecht, wie sich herausstellen sollte!
----
Tags: Spielbericht
----
Author: - user://P4aiY3HI
----
Date: 2025-12-01
----
Uuid: gqvlabgfoko535r9
Binary file not shown.

After

Width:  |  Height:  |  Size: 495 KiB

@@ -0,0 +1 @@
Uuid: dgspiwstnipmybks
@@ -0,0 +1,48 @@
Title: 20251020-Saisonauftakt
----
Blocks:
[
{
"content": {
"text": "<p>Der Start in die neue Saison verläuft für die SG SF Bad Steben/TV Reinersreuth&nbsp; äußerst unglücklich.</p><p>Im ersten Heimspiel setzte es gegen die SG Helmbrechts/Presseck eine 3,5 : 4,5 Niederlage. Dabei&nbsp; gelang es uns nicht, ein vollständiges Team mit acht Spielern zu gewährleisten.&nbsp; Nur sieben Akteure&nbsp;&nbsp;zum Saisonauftakt bedeuteten schon ein Handikap.</p><p>Am 19.10.2025 mussten wir zur ersten Auswärtsbegegnung beim vorläufigen Spitzenreiter SC Pegnitz antreten und es gab ein deutliches&nbsp; 2 : 6. Trotz großer Bemühungen unseres Spielleiters konnte er nur sechs Schachfreunde gegen die Heimmannschaft gewinnen. Mit einem anfänglichen 0 : 2-Rückstand ist es dann fast aussichtslos, auf einen Mannschafts-punktgewinn zu schielen. Nur Dominik Kadlic konnte seine Partie gewinnen, während Jürgen Franz und Rainald Müller ihre Spiele remisierten. Besonders&nbsp; hervorzuheben ist dabei die Punkteteilung unseres Spielleiters (DWZ: 1668), welcher am Spitzenbrett Markus Müller (DWZ: 1988) erfolgreich Paroli bieten konnte.</p><p>Nach den zwei Spieltagen stecken wir schon mitten im Abstiegskampf. Am 09.11.25 gilt es dann in der Heimbegegnung gegen den Aufsteiger ATSV Oberkotzau 2 nicht den Anschluss an das untere Mittelfeld in der Tabelle zu verlieren und endlich mal mit „voller Kapelle“ anzutreten.</p>"
},
"id": "e9def111-1209-4d1f-be78-985818f8c593",
"isHidden": false,
"type": "text"
}
]
----
Image: - file://dgspiwstnipmybks
----
Headline: Holpriger Saisonauftakt
----
Subheadline: Es läuft nicht rund!
----
Summary: Der Start in die neue Saison verläuft für die SG SF Bad Steben/TV Reinersreuth äußerst unglücklich.
----
Tags: Spielbericht
----
Author: - user://P4aiY3HI
----
Date: 2025-10-19
----
Uuid: 8qlli8wrp1tbkgap
@@ -0,0 +1,56 @@
Title: 20250922-Engagement
----
Blocks:
[
{
"content": {
"text": "<p>Neben dem Engagement im eigenen Verein wurden bei der Versammlung des Schachkreis Hof-Bayreuth-Kulmbach am vergangenen Freitag zwei SF in die Ämter des Kreisjugendleiter und seines Stellvertreters gewählt.</p>"
},
"id": "c9741947-2e75-49e6-a4c5-47e35f183528",
"isHidden": false,
"type": "text"
},
{
"content": {
"text": "**Tobias Feigel** (2. von links im Bild) amtierender Jugendleiter der SF und seit 2017 auch Kreisjugendleiter räumte seinen Posten auf Kreisebene und trat in die zweite Reihe zurück, um Platz zu machen für **Alexander Döge** (2. von rechts im Bild), der Kassenprüfer der SF ist und nun neuer Kreisjugendleiter. Tobias wird Alexander als sein Stellvertreter die nächsten zwei Jahre unterstützen und sich dann ganz aus der Vorstandschaft des Kreises verabschieden. Bei der nächsten Wahl soll dann Alexanders Bruder **Dominik Döge** in den Vorstand des Kreises an die Stelle von Tobias treten.\n\nEs seien mir dazu ein paar persönliche Worte erlaubt: In wenigen Jahren werde ich schachlich gesehen als Senior gewertet und da wird es höchste Zeit, den Posten in jüngere Hände abzugeben! Ich bin mir sicher, dass mit Alexander und Dominik zwei hervorragende Kandidaten für den Posten gefunden wurden und ich werde beide während der Übergangszeit unterstützen!"
},
"id": "6a2ee75a-db20-4861-80ee-db49f191c16e",
"isHidden": false,
"type": "markdown"
}
]
----
Image: - file://ioxhz3ujwtl6un8k
----
Headline: SF engagieren sich auf Kreisebene
----
Subheadline: Zwei SF im Vorstand des Schachkreises
----
Summary: Neben dem Engagement im eigenen Verein wurden bei der Versammlung des Schachkreis Hof-Bayreuth-Kulmbach am vergangenen Freitag zwei SF in die Ämter des Kreisjugendleiter und seines Stellvertreters gewählt.
----
Tags: Vereinsleben
----
Author: - user://KOY9VcGi
----
Date: 2025-09-22
----
Uuid: kbtd9a8so9mbkvti
Binary file not shown.

After

Width:  |  Height:  |  Size: 509 KiB

@@ -0,0 +1 @@
Uuid: ioxhz3ujwtl6un8k
@@ -37,7 +37,7 @@ Tags: Spielbericht, Turnierbericht
----
Author: - user://myU6sssZ
Author: - user://KOY9VcGi
----

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 69 KiB

Before

Width:  |  Height:  |  Size: 546 KiB

After

Width:  |  Height:  |  Size: 546 KiB

+1428
View File
File diff suppressed because it is too large Load Diff
+12 -9
View File
@@ -1,23 +1,26 @@
User-agent: *
Allow: /
Crawl-delay: 1
# Spezielle Erlaubnis für DSGVO/Legal Scanner
User-agent: LegalCockpitBot
Allow: /
Crawl-delay: 0
User-agent: CookieBot
User-agent: cockpit.legal
Allow: /
Crawl-delay: 0
User-agent: Mozilla*
Allow: /
User-agent: DataProtectionBot
Allow: /
User-agent: GDPRBot
Allow: /
# Sitemap (falls vorhanden)
# Sitemap: https://www.schachfreunde-badsteben.de/sitemap.xml
# Sitemap
Sitemap: https://www.schachfreunde-badsteben.de/sitemap.xml
# Wichtige Seiten explizit erlauben
Allow: /
Allow: /datenschutz
Allow: /impressum
Allow: /kontakt
Allow: /home
Allow: /news
+22 -9
View File
@@ -1,4 +1,3 @@
<?php
// URL der öffentlichen ICS-Datei
define(
@@ -83,13 +82,10 @@ function format_ics_date_with_timezone($date, $timezone = null)
}
}
// ICS-Datei laden
$ics = @file_get_contents(CAL_URL);
if (!$ics) {
echo '<div class="text-red-600">Kalender konnte nicht geladen werden.</div>';
return;
}
// Cache für 24 Stunden (in Minuten)
$cacheDuration = 24 * 60;
$cacheId = 'google_calendar_events';
$cache = kirby()->cache('pages');
// Termine parsen
function parse_ics($ics)
@@ -134,9 +130,26 @@ function parse_ics($ics)
return $events;
}
return function () use ($cache, $cacheId, $cacheDuration) {
// Versuche Daten aus dem Cache zu laden
$events = $cache->get($cacheId);
if ($events === null) {
// Wenn nicht im Cache, neu laden
$ics = @file_get_contents(CAL_URL);
if (!$ics) {
// Fehler beim Laden (z.B. 429 Error)
return null;
}
// Termine parsen
$events = parse_ics($ics);
return function () use ($events) {
// In Cache speichern
$cache->set($cacheId, $events, $cacheDuration);
}
return $events;
};
+11 -1
View File
@@ -1,13 +1,23 @@
<?php
return [
'debug' => true,
'debug' => false,
// Home-Seite explizit definieren
'home' => 'home',
'panel' => [
'vue' => [
'compiler' => false
]
],
'routes' => [
[
'pattern' => '/',
'action' => function() {
return site()->homePage();
}
],
[
'pattern' => 'sitemap.xml',
'action' => function() {
+45 -16
View File
@@ -1,6 +1,13 @@
<?php
$events = collection('termine');
if ($events === null): ?>
<div class="container mx-auto py-8">
<h2>Bevorstehende Termine</h2>
<div class="text-red-600">Die Termine können gerade nicht geladen werden.</div>
</div>
<?php return; endif;
// Aktuelles Datum - PHP 8.3 kompatibel
$today = (new DateTime('now'))->format('Ymd');
@@ -35,8 +42,12 @@ $de_months = [
<h2>Bevorstehende Termine</h2>
<div class="relative flex items-center justify-center">
<button id="scroll-left" class="flex-shrink-0 bg-white p-3 rounded-full shadow-lg hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 z-10 hidden md:block mr-4">
<svg class="w-6 h-6 text-gray-700" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path></svg>
<button id="scroll-left"
class="flex-shrink-0 bg-white p-3 rounded-full shadow-lg hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 z-10 hidden md:block mr-4">
<svg class="w-6 h-6 text-gray-700" fill="none" stroke="currentColor" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
</svg>
</button>
<div id="termine-wrapper" class="relative w-full max-w-7xl overflow-hidden">
@@ -69,11 +80,13 @@ $de_months = [
$safe_time = htmlspecialchars($time, ENT_QUOTES, 'UTF-8');
?>
<div class="termine-card flex-none w-full md:w-1/2 bg-gradient-to-br from-blue-50 to-blue-100 rounded-2xl transform hover:scale-102 transition-all duration-300 ease-in-out border border-blue-200">
<div
class="termine-card flex-none w-full md:w-1/2 bg-gradient-to-br from-blue-50 to-blue-100 rounded-2xl transform hover:scale-102 transition-all duration-300 ease-in-out border border-blue-200">
<!-- Inhalt der ersten Karte bleibt unverändert -->
<div class="p-6 flex flex-col h-full">
<div class="flex items-top mb-5">
<div class="relative flex-shrink-0 bg-white rounded-lg shadow-md overflow-hidden w-16 h-16 flex flex-col border border-blue-200">
<div
class="relative flex-shrink-0 bg-white rounded-lg shadow-md overflow-hidden w-16 h-16 flex flex-col border border-blue-200">
<!-- Kopfzeile des Kalenders mit Monat -->
<div class="bg-blue-600 text-white text-xs font-semibold py-1 text-center uppercase">
<span data-month><?= $month_name ?></span>
@@ -99,7 +112,8 @@ $de_months = [
<p class="text-xl font-medium text-sf_grau-900"><?= $event_summary ?></p>
<p class="text-sf_blau-700 text-lg font-medium mt-1">
<?php if ($date_info['has_time'] ?? false): ?>
ab <span class="local-time" data-iso-date="<?= $safe_iso_date ?>"><?= $safe_time ?></span> Uhr
ab <span class="local-time"
data-iso-date="<?= $safe_iso_date ?>"><?= $safe_time ?></span> Uhr
<?php else: ?>
ganztägig
<?php endif; ?>
@@ -112,8 +126,12 @@ $de_months = [
</div>
</div>
<button id="scroll-right" class="flex-shrink-0 bg-white p-3 rounded-full shadow-lg hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 z-10 hidden md:block ml-4">
<svg class="w-6 h-6 text-gray-700" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path></svg>
<button id="scroll-right"
class="flex-shrink-0 bg-white p-3 rounded-full shadow-lg hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 z-10 hidden md:block ml-4">
<svg class="w-6 h-6 text-gray-700" fill="none" stroke="currentColor" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
</svg>
</button>
</div>
</div>
@@ -250,32 +268,41 @@ $de_months = [
<style>
/* Versteckt die Scrollbar vollständig, behält aber die Scrollfunktionalität */
#termine-container {
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none;
/* IE and Edge */
scrollbar-width: none;
/* Firefox */
overflow-x: visible;
}
#termine-container::-webkit-scrollbar {
display: none; /* Chrome, Safari, Opera */
display: none;
/* Chrome, Safari, Opera */
}
/* Gleiche Kartenbreiten sicherstellen */
@media (min-width: 1280px) {
.termine-card {
width: 100%; /* 100% minus 2 Gaps (2 * 24px) geteilt durch 3 */
width: 100%;
/* 100% minus 2 Gaps (2 * 24px) geteilt durch 3 */
}
#termine-container {
space-x-0; /* Kein Abstand zwischen Karten nötig */
space-x-0;
/* Kein Abstand zwischen Karten nötig */
}
}
/* Auf mobilen Geräten eine Karte anzeigen */
@media (max-width: 1280px) {
.termine-card {
width: 100%; /* Volle Breite */
width: 100%;
/* Volle Breite */
}
#termine-container {
space-x-0; /* Kein Abstand zwischen Karten nötig */
space-x-0;
/* Kein Abstand zwischen Karten nötig */
}
}
@@ -283,9 +310,11 @@ $de_months = [
.termine-card h3 {
overflow: hidden;
text-overflow: ellipsis;
/* white-space: nowrap; */ /* Diese Zeile entfernen oder kommentieren */
/* white-space: nowrap; */
/* Diese Zeile entfernen oder kommentieren */
display: -webkit-box;
-webkit-line-clamp: 2; /* Maximal 2 Zeilen anzeigen */
-webkit-line-clamp: 2;
/* Maximal 2 Zeilen anzeigen */
-webkit-box-orient: vertical;
line-height: 1.3;
}
+12 -3
View File
@@ -2,6 +2,14 @@
$events = collection('termine');
if ($events === null): ?>
<section class="py-24 bg-sf_grau-50">
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div class="text-red-600 bg-white p-6 rounded-lg shadow">Die Termine können gerade nicht geladen werden.</div>
</div>
</section>
<?php return; endif;
// Nur Events mit DTSTART berücksichtigen
$events = array_filter($events, function ($event) {
return isset($event['DTSTART']) && !empty($event['DTSTART']);
@@ -99,9 +107,10 @@ if ($filter_jahr && $filter_monat) {
onclick="event.stopPropagation(); openYear('<?= $safe_year ?>')">
<span><?= $safe_year ?></span>
</a>
<button type="button" class="ml-1 focus:outline-none" onclick="toggleYear('<?= $safe_year ?>')">
<svg class="w-4 h-4 transition-transform" id="arrow-<?= $safe_year ?>" fill="none" stroke="currentColor" stroke-width="2"
viewBox="0 0 24 24">
<button type="button" class="ml-1 focus:outline-none"
onclick="toggleYear('<?= $safe_year ?>')">
<svg class="w-4 h-4 transition-transform" id="arrow-<?= $safe_year ?>" fill="none"
stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7" />
</svg>
</button>
+35 -5
View File
@@ -2,7 +2,7 @@
<?php
// Filterfunktionalität implementieren
$posts = $page->children()->sortBy('date', 'desc');
$posts = $page->children()->sortBy('date', 'desc')->paginate(5);
// Nach Kategorie (Tag) filtern
if ($tag = param('tag')) {
@@ -23,7 +23,8 @@
</div>
<div>
<?php foreach ($post->tags()->split() as $tag): ?>
<a href="<?= $page->url(['params' => ['tag' => $tag]]) ?>" class="relative z-10 rounded-full bg-gray-50 px-3 py-1.5 font-medium text-gray-600 hover:bg-gray-100"><?= $tag ?></a>
<a href="<?= $page->url(['params' => ['tag' => $tag]]) ?>"
class="relative z-10 rounded-full bg-gray-50 px-3 py-1.5 font-medium text-gray-600 hover:bg-gray-100"><?= $tag ?></a>
<?php endforeach; ?>
</div>
</div>
@@ -57,6 +58,37 @@
</div>
</article>
<?php endforeach ?>
<?php $pagination = $posts->pagination(); ?>
<?php if ($pagination->hasPages()): ?>
<nav class="flex justify-between items-center my-12 border-t border-gray-100 pt-8">
<?php if ($pagination->hasPrevPage()): ?>
<a href="<?= $pagination->prevPageUrl() ?>"
class="flex items-center gap-2 rounded-full bg-gray-50 px-4 py-2 text-sm font-medium text-gray-600 hover:bg-gray-100 transition-colors">
&larr; Neuere Beiträge
</a>
<?php else: ?>
<span class="flex items-center gap-2 rounded-full px-4 py-2 text-sm font-medium text-gray-300 cursor-not-allowed">
&larr; Neuere Beiträge
</span>
<?php endif ?>
<span class="text-xs font-medium text-gray-400">
Seite <?= $pagination->page() ?> von <?= $pagination->pages() ?>
</span>
<?php if ($pagination->hasNextPage()): ?>
<a href="<?= $pagination->nextPageUrl() ?>"
class="flex items-center gap-2 rounded-full bg-gray-50 px-4 py-2 text-sm font-medium text-gray-600 hover:bg-gray-100 transition-colors">
Ältere Beiträge &rarr;
</a>
<?php else: ?>
<span class="flex items-center gap-2 rounded-full px-4 py-2 text-sm font-medium text-gray-300 cursor-not-allowed">
Ältere Beiträge &rarr;
</span>
<?php endif ?>
</nav>
<?php endif ?>
<?php if (param('tag')): ?>
<div class="my-8">
@@ -64,6 +96,4 @@
Alle Beiträge anzeigen
</a>
</div>
<?php endif ?>
<?php endsnippet() ?>
<?php endif ?><?php endsnippet() ?>
+27 -3
View File
@@ -1,5 +1,29 @@
<?php snippet('layout', slots: true) ?>
<?php
// Wenn dies die Startseite ist, verwende die Home-Vorlage
if ($page->isHomePage()) {
snippet('layout', slots: true);
?>
<h1>Herzlich Willkommen!</h1>
<h1>Hallo Welt!</h1>
<?= $page->text()->kirbytext() ?>
<?php endsnippet() ?>
<?php snippet('home-news', [
'news' => page('news')->children()->limit(3)->sortBy('date', 'desc'),
]); ?>
<?php snippet('home-termine'); ?>
<?php snippet('puzzle'); ?>
<?php
endsnippet();
} else {
// Für andere Seiten
snippet('layout', slots: true);
?>
<h1><?= $page->title()->esc() ?></h1>
<?= $page->text()->kirbytext() ?>
<?php
endsnippet();
}
?>