Manche Templates oder Layout-Vorstellungen scheinen mit xt:Commerce kaum umsetzbar zu sein. Oftmals sind es Kleinigkeiten, für die es entweder kein Smarty-Tag gibt - oder ausgerechnet dort, wo man’s braucht, funktioniert es nicht.

Aber man muss nicht gleich im System herumbasteln, um das gewünschte Design zu verwirklichen. Als Anregung dieser Beitrag mit einem Beispiel “aus der Praxis”.

 

“Stimmungsbilder”

Wenn man die Kategorien-Bilder in xt:Commerce als zentrales Gestaltungs-Element bzw. “Header-Grafik” einsetzen möchte, muss man ein wenig in die Trickkiste greifen. Denn normalerweise stehen die hinterlegten Grafiken dem Template-System nur für Kategorien-Ansichten zur Verfügung. Sobald man jedoch beispielsweise einen einzelnen Artikel gewählt hat, “weiß” der Shop nichts mehr vom schönen Bild.

Außerdem ist es oftmals schwierig, den Quelltext so zu gestalten, dass die Kategorien-Bilder über dem eigentlichen “Content” erscheinen. In einem aktuellen Projekt stand ich vor genau diesem Problem.

 

Das Layout

Hier zwei Screenshots (nur Ausschnitte, der Shop ist noch nicht fertig) - Damit sollte deutlich werden, wieso das übliche Template-Tag {$CATEGORIES_IMAGE} für meine Zwecke nicht einsetzbar gewesen ist.

xt:Commerce Category Images

Die Kategorien-Bilder mussten für mein Layout also in der “index.html” des Templates aufgerufen und angezeigt werden. Bloß ist die “Bild-Adresse” da gewissermaßen “noch nicht bekannt” - und es gibt auch kein Smarty-Tag, mit dem man sich die URL von dort aus holen könnte.

 

“Mehrfacher Einsatz”

Nicht alle Artikelbilder sind wirkliche “Hingucker”. Bei Kleidung, bei der Designer Stereo-Anlage oder der ergonomischen Tastatur ist das tatsächliche Produktfoto zweifelsohne eine wichtige Sache. Aber “die Tube” eines Pflegeproduktes hat als Abbildung eher informativen Charakter: “Ist die Tube in einer weiteren Schachtel verpackt?”, “Kann man dies und das im Ladenregal stapeln oder muss ein Boden freigeräumt werden?”

Großflächiger Blickfang sollten daher auch in den Produkt-Details die “Header-Bilder” sein. Damit man nicht für jeden einzelnen Artikel ein solches Bild hochladen muss, bieten sich “Category Images” an. Und nach Möglichkeit sollte ein Bild auch gleich für alle Unterkategorien gelten - jedenfalls für die, die noch kein “eigenes Bild” haben.

 

Arbeit mit $GLOBALS und PHP im Template

In den global verfügbaren Variablen von xt:Commerce stecken etliche Informationen, mit denen man Einiges anstellen kann.

Zusätzlich ist es möglich, lauter PHP-Funktionen in der “xtc_show_category.inc.php” zu hinterlegen, auf die man dann von wirklich jeder Template-Datei aus zugreifen kann. Wenn man das zu nutzen weiß, kann man sich oftmals den Einbau von “Modulen” sparen und seinen Shop ohne System-Eingriffe nach seinen Wünschen zurechtbauen.


1) Category-ID feststellen

Um in der index.html das zugeordnete Kategorien-Bild zu laden, brauchen wir zunächst einmal die ID der momentan aktiven Kategorie. Und mit dieser ID wird danach eine Datenbank-Abfrage gestartet.

Befindet man sich aktuell in einer “Kategorie mit Bild” braucht man diese Abfrage natürlich nicht, weil die Bildadresse in den $GLOBALS hinterlegt ist. Sonst könnte das Bild ja nicht angezeigt werden. Aber wenn’s kein Bild gibt, soll das Image der übergeordneten Artikelgruppe gezeigt werden und in den Produkt-Details genauso.

Die ID der aktiven Kategorie ist auch in den Produkt-Details bekannt. Sonst würde erstens die BreadCrumb-Navigation nicht funktionieren und zweitens würde sich die Kategorien-Navigation auf “product_info_xyz.html”-Seiten immer wieder “einklappen”.

Wir nutzen den “Category-Path” für unsere erste Funktion als als Ausgangspunkt:


function get_CurrentCat() {
	$CategoryPath = explode('_',$GLOBALS['cPath']);
	$CurrentCat = array_pop($CategoryPath);
	if($CurrentCat != '')
		return $CurrentCat;
	else
		return 0;
}
	

Wenn man auf der Startseite, im Bezahlprozess, in Suchergebnissen etc. surft, gibt’s als Rückgabewert die Null, ansonsten die “letzte Nummer” im cPath-Array.


2) Bild-Adresse anhand einer ID feststellen

Da diese nicht an jeder Stelle global hinterlegt ist, kommt man um eine Datenbank-Abfrage nicht herum. Wir brauchen eine Funktion, in die man eine ID “reintut” und eine “Bild-Adresse” wieder herausbekommt:


function get_CatImage($CategoryID = 0) {
	$CatImage = false;
	if ($CategoryID != 0) {
		$CatImageQuery = xtDBquery("
					select categories_image from ".TABLE_CATEGORIES."
					where categories_id = ".$CategoryID);
		$CatImageQuery = xtc_db_fetch_array($CatImageQuery,true);
		if (!empty($CatImageQuery['categories_image'])) {
			$CatImage = $CatImageQuery['categories_image'];
		}
	}
	return $CatImage;
}
	

Zurückgegeben wird der Bildname (noch ohne Dateipfad) sofern für die Kategorie mit der Nummer $CategoryID eine Grafik abgespeichert worden ist. Andernfalls ist das Ergebnis “false”.


3) Mutterkategorie ermitteln

Damit kommt man nicht weiter, wenn’s für die aktive Kategorie kein Bild gibt. Diese beiden Funktionen “reichen” höchstens in den Produkt-Details von Artikeln, die direkt in einer “Kategorie mit Bild” liegen …

Daher braucht man einen allgemeinen Weg, um die ID der übergeordneten Kategorie zu einer beliebigen anderen Kategorie zu finden. Die aktuelle “parent_id” ist zwar in den $GLOBALS hinterlegt, aber für den Fall, dass man noch ein paar Schritte “weiter nach oben” gehen muss - oder die “gesuchte” ID nichts mit der “aktuellen” ID zu tun haben sollte - brauchen wir wieder eine Datenbank-Abfrage:


function get_CatParent($CategoryID = 0) {
	$CatParent = 0;
	if ($CategoryID != 0) {
		$CatParentQuery = xtDBquery("
					select parent_id from ".TABLE_CATEGORIES."
					where categories_id = ".$CategoryID);
		$CatParentQuery = xtc_db_fetch_array($CatParentQuery,true);
		if (!empty($CatParentQuery['parent_id'])) {
			$CatParent = $CatParentQuery['parent_id'];
		}
	}
	return $CatParent;
}
	

Und nur so ist auch der nächste Schritt möglich …


4) Bild-Adresse rekursiv ermitteln

Das Prinzip ist recht einfach: Eine Funktion bekommt eine ID und guckt nach, ob es dazu ein Bild gibt. Wenn ja - ist prima. Bildname wird zurückgegeben und Ende. Wenn nein, schade. Aber macht nix - Funktion guckt nach, ob es zu der ID eine “Mutter-ID” gibt - und ruft sich selbst mit dieser “Mutter-ID” auf …

Vorsicht: Die Sache könnte sich in einer Endlos-Schleife verlaufen, denn falls für den gesamten Kategorien-Zweig nirgends ein Bild definiert ist, wird immer weiter nach dem Bild einer “Mutter-ID” gesucht, auch wenn die Funktion längst in der “Top” angekommen ist.

Also muss eine weitere “Abbruchsbedingung” festgelegt werden: Sobald die abgefragte ID “Null” ist, ist Schluss.


function get_CurrentCatImage($CategoryID = 0) {
	$CatImage = get_CatImage($CategoryID);
	if(!$CatImage && $CategoryID != 0)
		$CatImage = get_CurrentCatImage(get_CatParent($CategoryID));
	return $CatImage;
}
	

Beinahe fertig - Damit erhalten wir einen Bildnamen, wenn eines gespeichert wurde - und ein “false”, wenn entweder keines gespeichert wurde oder schlichtweg eine “Kategorie” nicht feststellbar ist.


5) Ausgabefunktion

Der letzte Schritt ist schließlich die Anzeige des Bildes - abhängig von der aktuellen “Position” im Shop. Und dafür setzen wir unsere allererste Funktion ein, mit der man die gültige Kategorien-ID feststellen und so die ganze Geschichte mit einem passenden Anfangswert starten kann.

Ebenso muss der Dateienpfad auf dem Server zum Bild hinzugefügt und bei nicht vorhandenem Bild ein “Standard-Image” angezeigt werden:


function show_CurrentCatImage() {
	$CatImage = get_CurrentCatImage(get_CurrentCat());
	if(!$CatImage)
		echo 'Pfad/zu_einem/Standard-Bild.jpg';
	else
		echo DIR_WS_IMAGES.'categories/'.$CatImage;
}
	

 

Aufruf im Template

Wenn all diese Mini-Funktionen in der Datei “xtc_show_category.inc.php” abgelegt wurden, kann man überall im Template die Bild-Adresse des Category-Images ausgeben und sicher sein, dass auch ohne konkretes Bild wenigstens das einer dazugehörigen, übergeordneten Kategorie gezeigt wird.

Der Aufruf könnte dann beispielsweise so aussehen …

<img id="CatImage" src="{php}show_CurrentCatImage();{/php} alt="Beispiel.jpg" />

… oder für den Einsatz als Hintergrundbild einer DIV-Ebene:


<div id="MainHeader" style="background-image: url('{php}show_CurrentCatImage();{/php}')"> 

<!-- Inhalte --> 

</div>
	

… eben ganz so, wie es für das Layout erforderlich ist. Und wo es erforderlich ist. Egal, ob das Bild in der “index.html” oder vielleicht sogar in der “box_last_viewed.html” eingesetzt werden soll …