['onPluginsInitialized', 0] ]; } public function onPluginsInitialized() { if ($this->isAdmin()) { return; } $this->enable([ 'onPagesInitialized' => ['onPagesInitialized', 0] ]); } public function onPagesInitialized() { $uri = $this->grav['uri']; $path = $uri->path(); if (strpos($path, '/api/') !== 0) { return; } $lang = $_GET['lang'] ?? 'en'; header('Content-Type: application/json'); header('Access-Control-Allow-Origin: *'); if ($path === '/api/stations') { echo json_encode($this->getStationsList($lang), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } if (preg_match('#^/api/station/([a-zA-Z0-9-]+)$#', $path, $matches)) { $station = $this->getStation($matches[1], $lang); if ($station) { echo json_encode($station, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); } else { http_response_code(404); echo json_encode(['error' => 'Station not found']); } exit; } if ($path === '/api/translations') { echo json_encode($this->getTranslations($lang), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); exit; } } private function getStationsList($lang) { $pages = $this->grav['pages']; $stations = []; foreach ($pages->all() as $page) { if ($page->template() === 'station') { $header = $page->header(); if (!($header->active ?? true)) continue; $stations[] = [ 'id' => $header->station_id ?? $page->slug(), 'type' => $header->station_type ?? 'exhibit', 'title' => $this->getTranslated($header->title_translations ?? [], $lang), 'description' => $this->getTranslated($header->description_translations ?? [], $lang), 'order' => $header->order ?? 0 ]; } } usort($stations, fn($a, $b) => $a['order'] <=> $b['order']); return $stations; } private function getStation($stationId, $lang) { $pages = $this->grav['pages']; foreach ($pages->all() as $page) { if ($page->template() === 'station') { $header = $page->header(); $id = $header->station_id ?? $page->slug(); if ($id === $stationId) { return $this->formatStation($page, $lang); } } } return null; } private function formatStation($page, $lang) { $header = $page->header(); $station = [ 'id' => $header->station_id ?? $page->slug(), 'type' => $header->station_type ?? 'exhibit', 'language' => $lang, 'title' => $this->getTranslated($header->title_translations ?? [], $lang), 'description' => $this->getTranslated($header->description_translations ?? [], $lang), 'components' => [] ]; if (isset($header->components) && is_array($header->components)) { foreach ($header->components as $comp) { $station['components'][] = $this->formatComponent($comp, $lang); } } return $station; } private function formatComponent($comp, $lang) { $out = [ 'id' => $comp['id'] ?? uniqid(), 'type' => $comp['type'] ?? 'text' ]; switch ($comp['type']) { case 'heading': $out['level'] = $comp['level'] ?? 'h2'; $out['content'] = $this->getTranslated($comp['content'] ?? [], $lang); break; case 'text': $out['content'] = $this->getTranslated($comp['content'] ?? [], $lang); break; case 'video': $out['src'] = $this->getTranslated($comp['src'] ?? [], $lang); $out['poster'] = $comp['poster'] ?? null; $out['caption'] = $this->getTranslated($comp['caption'] ?? [], $lang); break; case 'audio': $out['src'] = $this->getTranslated($comp['src'] ?? [], $lang); $out['caption'] = $this->getTranslated($comp['caption'] ?? [], $lang); break; case 'tabs': $out['tabs'] = []; foreach ($comp['tabs'] ?? [] as $tab) { $out['tabs'][] = [ 'title' => $this->getTranslated($tab['title'] ?? [], $lang), 'content' => $this->getTranslated($tab['content'] ?? [], $lang) ]; } break; case 'slideshow': $out['slides'] = []; foreach ($comp['slides'] ?? [] as $slide) { $out['slides'][] = [ 'image' => $slide['image'] ?? '', 'caption' => $this->getTranslated($slide['caption'] ?? [], $lang) ]; } break; } return $out; } private function getTranslated($field, $lang) { if (is_string($field)) return $field; return $field[$lang] ?? $field['en'] ?? reset($field) ?: ''; } private function getTranslations($lang) { $t = [ 'en' => [ 'appTitle' => 'EU Media Guide', 'scanQR' => 'Scan QR Code', 'selectLanguage' => 'Select Language', 'contentLibrary' => 'Content Library', 'loading' => 'Loading...', 'play' => 'Play', 'pause' => 'Pause', 'next' => 'Next', 'previous' => 'Previous', 'menu' => 'Menu', 'close' => 'Close' ], 'fr' => [ 'appTitle' => 'Guide Média UE', 'scanQR' => 'Scanner le code QR', 'selectLanguage' => 'Choisir la langue', 'contentLibrary' => 'Bibliothèque', 'loading' => 'Chargement...', 'play' => 'Lecture', 'pause' => 'Pause', 'next' => 'Suivant', 'previous' => 'Précédent', 'menu' => 'Menu', 'close' => 'Fermer' ], 'de' => [ 'appTitle' => 'EU Medienführer', 'scanQR' => 'QR-Code scannen', 'selectLanguage' => 'Sprache wählen', 'contentLibrary' => 'Inhaltsbibliothek', 'loading' => 'Laden...', 'play' => 'Abspielen', 'pause' => 'Pause', 'next' => 'Weiter', 'previous' => 'Zurück', 'menu' => 'Menü', 'close' => 'Schließen' ], 'nl' => [ 'appTitle' => 'EU Mediagids', 'scanQR' => 'QR-code scannen', 'selectLanguage' => 'Taal selecteren', 'contentLibrary' => 'Inhoudsbibliotheek', 'loading' => 'Laden...', 'play' => 'Afspelen', 'pause' => 'Pauze', 'next' => 'Volgende', 'previous' => 'Vorige', 'menu' => 'Menu', 'close' => 'Sluiten' ], 'it' => [ 'appTitle' => 'Guida Media UE', 'scanQR' => 'Scansiona codice QR', 'selectLanguage' => 'Seleziona lingua', 'contentLibrary' => 'Libreria contenuti', 'loading' => 'Caricamento...', 'play' => 'Riproduci', 'pause' => 'Pausa', 'next' => 'Successivo', 'previous' => 'Precedente', 'menu' => 'Menu', 'close' => 'Chiudi' ], 'es' => [ 'appTitle' => 'Guía de Medios UE', 'scanQR' => 'Escanear código QR', 'selectLanguage' => 'Seleccionar idioma', 'contentLibrary' => 'Biblioteca de contenido', 'loading' => 'Cargando...', 'play' => 'Reproducir', 'pause' => 'Pausa', 'next' => 'Siguiente', 'previous' => 'Anterior', 'menu' => 'Menú', 'close' => 'Cerrar' ] ]; return $t[$lang] ?? $t['en']; } }