Joomla 4: Einleitungs-, Beitragsbild. Komische Pfade. (Kill the worm!)
Mein Bild-Optimierer-Plugin meckert unter Joomla 4 plötzlich rum, dass Einleitungsbild (image_intro
) und so genanntes "Komplettes Beitragsbild" (image_fulltext
) nicht existieren, wenn ich sie mit dem neuen Joomla-Medienmanager in einem Beitrag auswähle. Schuld sind "komische" Anhängsel an die Bildpfade, die Joomla jetzt automatisch mitspeichert und die in meinem Fall störend sind. Wie man sie los wird?
Joomla 3 versus Joomla 4
In beiden Szenarien lege ich einen neuen Beitrag an und wähle im Tabulator "Bilder und Links" ein "Einleitungsbild" und ein Bild im Feld mit dem blöden Namen "Komplettes Beitragsbild". Wichtig ist, dass ich nicht den JCE-Editor verwende, sondern den Joomla-Standard, der wiederum den joomlaeigenen Medienmanager für die Bild-Auswahl anbietet.
Mein eingesetztes Beispielbild ist images/headers/maple.jpg
.
Nach dem Speichern des Beitrags kann ich entweder in der Datenbank in der Tabelle #__content
den Beitrag suchen und mir das Datenbank-Feld images
anschauen oder ich verwende zum Debuggen folgenden, altbekannten Code in einer Beitragsansicht im Frontend:
defined('_JEXEC') or die;
$images = json_decode($this->item->images);
echo ' DEBUG $images: <pre>' . print_r($images, true) . '</pre>';exit;
Ergebnis in Joomla 3
Meinen Debug-Code habe ich an den Anfang der Datei components\com_content\views\article\tmpl\default.php
eingebaut und rufe dann meinen neuen Beitrag im Frontend auf.
Der Ausgabe-Code sieht (gekürzt) so aus:
stdClass Object
(
[image_intro] => images/headers/maple.jpg
...
[image_fulltext] => images/headers/maple.jpg
...
)
Ergebnis in Joomla 4
Meinen Debug-Code habe ich an den Anfang der Datei components\com_content\tmpl\article\default.php
eingebaut und rufe dann meinen neuen Beitrag im Frontend auf.
Der Ausgabe-Code sieht (gekürzt) so aus:
stdClass Object
(
[image_intro] => images/headers/maple.jpg#joomlaImage://local-images/headers/maple.jpg?width=700&height=180
...
[image_fulltext] => images/headers/maple.jpg#joomlaImage://local-images/headers/maple.jpg?width=700&height=180
...
)
Man beachte die "komischen" Würmer #joomlaImage://local-images/...
nach den normalen Pfaden images/headers/maple.jpg
im Unterschied zur Joomla-3-Ausgabe.
Wann stört das nicht?
Wenn ich die Pfade so wie sie sind in einen <img>
-Tag einbaue. Die Bilder werden trotzdem angezeigt und das ganze Gedöns hinter dem Gatterzeichen (#
) bleibt wirkungslos. width
und height
machen in dieser Form zum Beispiel gar nix.
<img src=<?php echo $images->image_intro; ?> alt="">
=> ERGIBT:
<img src=images/headers/maple.jpg#joomlaImage://local-images/headers/maple.jpg?width=700&height=180 alt="">
Wann stört das?
Wenn ich prüfen will, ob das Bild unter dem Pfad existiert, was mein Bild-Optimierer-Plugin beispielsweise macht.
if (is_file(JPATH_SITE . '/' . $images->image_intro))
{
---TU WAS---
}
Joomla 3 wird was tun, Joomla 4 aber nicht.
Lösung? Die Peter-Henderson-&-Co-Methode
Neben Joomla-Methoden, z.B. aus der JUri
-Klasse, kann man auch puristisches PHP verwenden, um den Wurm loszuwerden:
$images->intro_image = explode('#', $images->image_intro)[0];
if (is_file(JPATH_SITE . '/' . $images->image_intro))
{
---TU WAS---
}
oder etwas ausführlicher in einer eigenen Methode/Funktion (für Joomla 3 und 4), wenn man's öfter mal braucht:
/** Since Joomla 4 new stupid path format like
* images/blue.jpg#joomlaImage://local-images/blue.jpg?width=80&height=80
*/
public static function extractImagePath($image)
{
if (empty($image) || version_compare(JVERSION, '4', 'lt')
|| strpos($image, '#') === false)
{
return $image;
}
return explode('#', $image)[0];
}
oder etwas geraffter ohne tiefere Prüfung, ob's Joomla-Version 3 oder 4 ist:
/*
* images/blue.jpg#joomlaImage://local-images/blue.jpg?width=80&height=80
*/
public static function extractImagePath($image)
{
if ($pos = strpos($image, '#')) {
return substr($image, 0, $pos);
}
return $image;
}
Möglichkeit MediaHelper::getCleanMediaFieldValue()
im Joomla-4-Core
Joomla 4 hat folgende Variante dabei, um den puren Bildpfad zurück zu bekommen:
$images->intro_image = \Joomla\CMS\Helper\MediaHelper::getCleanMediaFieldValue($images->intro_image);
Anderes Szenario unter Joomla 4 - Den "Wurm" entschlüsseln
Oben geht es ja darum, dass ich den Pfad so haben möchte, dass eine Prüfung durchgeführt werden kann, ob die Bilddatei existiert und das sowohl kompatibel mit Joomla 3 als auch Joomla 4.
Bembelimen aus dem Joomla-Forum hat uns darauf hingewiesen, dass es in Joomla 4 auch eine HTMLHelper/JHtml
-Methode gibt (cleanImageURL()
), mit der man den Pfad ermitteln kann. Die dient dem Zweck, den "Wurm" in seine Bestandteile zu zerlegen und die darin enthaltenen Informationen (z.B. width
und height)
in einem PHP-Object
zurückzugeben, wenn man sie weiter nutzen möchte und zusätzlich den gesäuberten Pfad haben möchte. Die Verwendung kann dann so aussehen:
// z.B. das zurückerhaltene image_intro mit dem "Wurm" hinten dran:
$meinBild = 'images/headers/maple.jpg#joomlaImage://local-images/headers/maple.jpg?width=700&height=180';
// Zerlegen:
$wurmInfos = HTMLHelper::_('cleanImageURL', $meinBild);
// $wurmInfos debuggen:
echo ' DEBUG $wurmInfos : <pre>' . print_r($wurmInfos , true) . '</pre>';exit;
Die Debug-Ausgabe sieht dann so aus:
stdClass Object
(
[attributes] => Array
(
[width] => 700
[height] => 180
)
[url] => images/headers/maple.jpg
)
Um den gesäuberten Pfad auszugeben, greife ich auf die Objekteigenschaft url
zurück:
echo $wurmInfos->url;
Oder die width
?
echo $wurmInfos->attributes['width'];
Nach ein paar Tests und Spielereien: Die Methode dient ausschließlich dieser spezifischen Entschlüsselung! Sie ist anderweitig nicht sonderlich intelligent und spuckt auch Unsinn aus, wenn der "Wurm" nicht exakt so angehängt und aufgebaut ist, wie ihn der Medienmanager abspeichert.