Auf unserer Now-Seite loggen wir Orte, die uns inspiriert haben. Als Hintergrund wollten wir gerne eine Karte einbinden, um den Ort subtil zu kennzeichnen. Jetzt könnten wir das natürlich manuell per Screenshot lösen, aber wofür gibt es schon Computer, wenn wir das nicht automatisieren könnten.
Wir brauchen also einen Weg, statische Karten zu erstellen. Fündig wurden wir bei php-osm-static-api von Franck Alary. Diese Library generiert Karten auf Open Street Map Daten und speichert sie als statisches Bild.
Die Geo-Daten kommen aus Kirby CMS:
Damit unsere Besucher nicht bei jedem Seitenaufruf auf die Bild-Datei warten müssen, generieren wir die png-Bilddatei nach dem Speichern der Seite. In einem Hook. In Kirby CMS gibt es verschiedene Hooks, also Momente im Lifecycle der Applikation, in denen wir unseren eigenen Code "einhaken" können.
App::plugin('project/visited', [
'hooks' => [
'page.create:after' => function (Kirby\Cms\Page $page) {
// Only generate map for pages with "location" template
if ($page->intendedTemplate()->name() !== 'location') {
return;
}
generateLocationMap($page);
},
'page.update:after' => function (Kirby\Cms\Page $newPage, Kirby\Cms\Page $oldPage) {
// Only generate map for pages with "location" template
if ($newPage->intendedTemplate()->name() !== 'location') {
return;
}
$latChanged = $newPage->lat()->value() !== $oldPage->lat()->value();
$lngChanged = $newPage->lng()->value() !== $oldPage->lng()->value();
// Only regenerate image if geo data has changed
if ($latChanged || $lngChanged) {
generateLocationMap($newPage);
}
}
],
]);
Die Funktion dafür sieht wie folgt aus:
- Geo-Daten laden, die wir gerade gespeichert haben
- Mit diesen Daten und der oben genannten Library ein Bild erstellen
- Temporäres Bild als Ressource in Kirby erstellen
- Map-Feld auf der Seite mit neuem Bild updaten
function generateLocationMap(Kirby\Cms\Page $page)
{
// Ensure REQUEST_SCHEME is set for the library
if (!isset($_SERVER['REQUEST_SCHEME'])) {
$_SERVER['REQUEST_SCHEME'] = 'https';
}
// Get geo data from page content
$lat = $page->lat()->toFloat();
$lng = $page->lng()->toFloat();
if (!$lat || !$lng) return;
try {
// Use library to generate png
$map = new OpenStreetMap(
new LatLng($lat, $lng),
12,
460,
320
);
// Create temporary image
$mapImage = $map->getImage();
$mapFilename = 'map-' . $page->slug() . time() . '_temp.png';
$mapPath = $page->root() . '/' . $mapFilename;
// Save the temporary image to the page directory
$mapImage->savePNG($mapPath);
// Create Kirby Image instance (copies file)
$kirbyMapImage = $page->createFile([
'source' => $mapPath,
'template' => 'image',
'filename' => Str::replace($mapFilename, '_temp', ''),
'content' => []
]);
// Update page with new image
$page->update(['map' => $kirbyMapImage->filename()]);
// Remove temporary image
F::remove($mapPath);
} catch (Exception) {
// Handle Error
}
}
So easy kann es sein. Wir haben ein schickes Bild für jeden Eintrag, ohne jedes Mal das Grafik-Programm zu öffnen.