Schlankerer Code für Navigation

xt:Commerce bietet fünf Navigationen an, die man in der “index.html” des Templates mittels der zur Verfügung gestellten Smarty-Tags aufrufen und an beliebiger Stelle platzieren kann. In Version 3.04 sind dies:

  • {$navtrail}
    Damit wird die typische “Breadcrumb”-Navigation erzeugt.
  • {$box_MANUFACTURERS}
    … erzeugt eine “Hersteller-Liste”, so dass sich der Besucher alle Artikel des gewünschten Herstellers anzeigen lassen kann. Ausgegeben werden nur die Hersteller, von denen es mindestens einen aktiven Artikel im Warenbestand gibt.
    Ab einer (einstellbaren) Anzahl kann diese Navigation zudem in Form eines Dropdown-Formularfeldes ausgegeben werden - Das spart Platz bei Shops mit sehr vielen Herstellern.
  • {$box_CATEGORIES}
    … zeigt alle aktivierten Artikel-Kategorien an. Auf Wunsch erscheint hinter jedem Eintrag in Klammern die Anzahl der in dieser Kategorie enthaltenen Artikel.
    Diese Navigation “klappt” auf: Erst wenn man auf eine Kategorie mit weiteren “Unter-Kategorien”, werden diese (ein bisschen eingerückt) angezeigt. So wird der Besucher nicht gleich mit unzähligen Klickmöglichkeiten “erschlagen”
  • {$box_CONTENT} und {$box_INFORMATION}
    Unabhängig vom Artikelstamm kann xt:Commerce auch “statische” Seiten verwalten - Für einen Online-Shop braucht man beispielsweise AGBs, ein Kontaktformular, Versandkosten-Informationen, Site-Map und vieles mehr.
    xt:Commerce stellt dazu in der Standard-Installation zwei “Gruppen” zur Verfügung, deren Seiten entweder über die “CONTENT” oder die “INFORMATION”-Navigation erreicht werden können. Im Administrations-Bereich des Shops können unter dem Menüpunkt “Content Manager” Gruppen-Zuordnung sowie die Reihenfolge bestimmt werden, so dass nach man seine Zusatz-Infos nach Wunsch innerhalb dieser beiden “boxes” ein- und anordnen kann.

Die meisten dieser Navigationen produzieren in den mitgelieferten Templates einen extrem überladenen Quellcode, der schnelle Design-Änderungen mittels CSS unmöglich werden lässt. Zu viele Gestaltungs-Elemente werden direkt im HTML-Text festgelegt.

Am “schlimmsten” ist hierbei die Kategorien-Anzeige. Wie man dort für mehr “Ordnung” sorgt, kommt in einem weiteren Beitrag an späterer Stelle kann hier nachgelesen werden.

Glücklicherweise ist das Template-System von xt:Commerce so flexibel, dass man die Ausgabe der meisten Funktionen seinen Wünschen und Anforderungen genau anpassen kann.

Thema für heute: “Content” und “Information”

Zu Anfang kümmern wir uns um die statischen Seiten. Denn der ausgegebene HTML-Text von {$box_INFORMATION} sowie {$box_CONTENT} lässt ebenfalls stark zu wünschen übrig. Und abgesehen vom überladenen Code wird (im Gegensatz zur Kategorien-Navigation) die jeweils aktive Seite in keiner Weise gekennzeichnet. Das kann und sollte behoben werden.

Bestandsaufnahme

Im vom Shopsystem mitgelieferten Standard-Template “xtc4″ sorgt {$box_CONTENT} für eine HTML-Ausgabe nach folgendem Muster:

<table width="100%" border="0" cellpadding="2" cellspacing="0">
<tr>
<td class="infoBoxHeading">
<table width="100%"  border="0" cellpadding="0" cellspacing="0">
<tr>
<td class="infoBoxHeading">Mehr über.. </td>
<td width="10">
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td class="infoBox" align="right">
<table width="95%"  border="0" cellpadding="2" cellspacing="0">
<tr>
<td class="boxText">
<img src="templates/xtc4/img/icon_arrow.jpg"> <a href="#">Liefer- und Versandkosten</a><br>
<img src="templates/xtc4/img/icon_arrow.jpg"> <a href="#">Privatsphäre und Datenschutz</a><br>
<img src="templates/xtc4/img/icon_arrow.jpg"> <a href="#">Unsere AGB's</a><br>
<img src="templates/xtc4/img/icon_arrow.jpg"> <a href="#">Impressum</a><br>
<img src="templates/xtc4/img/icon_arrow.jpg"> <a href="#">Kontakt</a><br>
</td>
</tr>
</table>
</td>
</tr>
</table> 

… das ist schon eine ganze Menge HTML für so wenig Inhalt. Also ganz und gar nichts für echte CSS-Fans.

“Erste Hilfe”

Die ersten Verschlankungsmaßnahmen sind relativ schnell erledigt: Im Template-Ordner “boxes” des aktiven Templates finden sich die Dateien “box_content.html” sowie “box_information.html” - Diese Dateien werden von der “index.html” des Templates aus über die beiden Tags {$box_CONTENT} bzw. {$box_INFORMATION} aufgerufen hier ist auch die Ursache der Tabellen.

Beide Dateien sind nach dem gleichen Muster konstruiert, hier der Code der Datei “box_content.html”:

{config_load file="$language/lang_$language.conf" section="boxes"}
<table width="100%" border="0" cellpadding="2" cellspacing="0">
<tr>
<td class="infoBoxHeading"><table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td class="infoBoxHeading">{#heading_content#} </td>
<td></td>
</tr>
</table></td>
</tr>
<tr>
<td class="infoBox" align="left"><table width="95%" border="0" cellpadding="2" cellspacing="0">
<tr>
<td class="boxText">{$BOX_CONTENT}</td>
</tr>
</table></td>
</tr>
</table>

Grundsätzlich schreiben alle “boxes” sehr viele Tabellen. Um allgemein für weniger Verschachtelung zu sorgen, ist es empfehlenswert, gleich alle “boxes”-Dateien durchzugehen und nach schlankerem Muster zu konstruieren. Bei den meisten Dateien ist das recht einfach. Wichtig dabei ist, dass man jeder Box eine individuelle CSS-ID gibt, damit man sie nachher (falls gewünscht) auch einzeln “ansprechen” und mit besonderen “Gestaltungs-Eigenschaften” versehen kann.

Ein (natürlich unverbindlicher) Vorschlag für einen geeigneten Muster-Aufbau von “boxes”-Dateien ist dieser:

<div class="box" id="eindeutiger-boxname">
<h4><span>{#heading_content#}</span></h4>
<div class="boxcontent">
{$BOX_CONTENT}
</div>
</div>

Über die CSS-Klasse “box” können so Eigenschaften festgelegt werden, die für alle Boxen, alle darin enthaltenen Überschriften und alle weiteren Inhalte gleichsam gelten. Das <span>-Tag um die h4-Überschrift sorgt für zusätzliche Flexibilität, wenn man z.B. die Box-Überschriften nicht nur farblich hinterlegen möchte, sondern für sie auch noch Abstände festlegen, mehrfarbige Unterstreichungen, Hintergrundbilder oder was auch immer festlegen möchte.

Die CSS-ID “eindeutiger-boxname” ist natürlich mit einer jeweils sinnvollen Bezeichnung auszutauschen, die nur einmal auf einer Seite auftauchen darf. Übrigens eine häufige Fehlerquelle, da sich eine xt:Commerce-Seite aus vielen Einzel-Dateien zusammensetzt - so dass man leicht den Überblick verlieren kann, welche ID schon “besetzt” ist.

Finden der “Funktion”

Jetzt sind die äußeren Tabellen entfernt. Die “Content”- und “Information”-Navigationen werden jedoch weiterhin mit lauter Bildern als “Dekoration” ausgegeben. Flexibler in der Gestaltung wäre jedoch eine Ausgabe in Form der allgemein empfohlenen “ungeordneten Liste” nach dem Muster:

<ul class="navilist">
<li><a href="#">Men&uuml;punkt 1</a></li>
<li><a href="#">Men&uuml;punkt 2</a></li>
<li><a href="#">Men&uuml;punkt 3</a></li>
</ul>

Was die im Template zur Verfügung stehenden Smarty-Tags ausgeben, wird größtenteils im Template festgelegt. So muss man nicht im Kernsystem herumbasteln, bloß um die HTML-Ausgabe nach eigenen Wünschen zu gestalten.

Die meisten dieser Programmteile befinden sich im Template-Ordner “source”/”boxes” des aktiven Templates. Hier sind diese beiden Dateien zu bearbeiten:

  1. “information.php”
  2. “content.php”

Erstere ist verantwortlich für das {$BOX_INFORMATION}, das in der Datei “box_information.html” aufgerufen wird, die zweite entsprechend verantwortlich für das {$BOX_CONTENT} in der Datei “box_content.html”.

Es werden also mit exakt denselben Smarty-Tags unterschiedliche Dinge angezeigt - Entscheidend ist für xt:Commerce immer, aus welcher Datei heraus sie aufgerufen werden.

Analyse und Erzeugen einer Liste

Die “information.php” und die “content.php” sind nach demselben Muster aufgebaut. Beide füllen in einer Schleife eine Variable namens $content_string mit Informationen aus Datenbank-Abfragen und zusätzlichen HTML-Tags. Am Ende wird der Inhalt abgefragt - und (sofern Inhalt vorhanden ist) dieser der Anweisung BOX_CONTENT zugeteilt. Ebenso wird festgelegt, in welcher Box-Datei man diese Anweisung benutzen kann.

Für die HTML-Ausgabe sind also alle Stellen wichtig, in denen der Wert von $content_string verändert wird. Diese Stellen sind leicht zu erkennen. Man muss nur nach folgendem Code suchen:

$content_string .= 

Hier kann man dann seine Verbesserungen vornehmen. Im Template “xtc4″ wäre in der Datei “content.php” die Zeile 59 zu ändern. Im Original steht dort:

$content_string .= '<img src="templates/'.CURRENT_TEMPLATE.'/img/icon_arrow.jpg" alt="" /> <a href="'.xtc_href_link(FILENAME_CONTENT, 'coID='.$content_data['content_group'].$SEF_parameter).'">'.$content_data['content_title'].'</a><br />';

Das Bild vornedran brauchen wir nicht. Stattdessen nehmen wir ein <li>-Tag. Ebenso ist das abschließende <br>-Tag unnötig und kann (wir möchten ja XHTML schreiben) durch </li>-Tag ersetzt werden. Es ergibt sich damit Folgendes für Zeile 59:

$content_string .= '<li><a href="'.xtc_href_link(FILENAME_CONTENT, 'coID='.$content_data['content_group'].$SEF_parameter).'">'.$content_data['content_title'].'</a></li>';

Damit würde die Seiten-Navigation folgenden HTML-Text ausgeben:

<li><a href="#">Men&uuml;punkt 1</a></li>
<li><a href="#">Men&uuml;punkt 2</a></li>
<li><a href="#">Men&uuml;punkt 3</a></li>

Es fehlen noch das öffnende sowie das schließende <ul>-Tag. Das ist an den entsprechenden Stellen in der Datei nachzutragen. Das Öffnen der Liste kann gleich zu Anfang passieren. Am Besten gleich in der Zeile 19:

$content_string = '';

ersetzen durch

$content_string = '<ul class="navilist">';

Das Schließen der Liste erfolgt nach Ablauf der While-Schleife. Vor Zeile 61

if ($content_string != '')

ist folgende Zeile hinzuzufügen:

$content_string .= '</ul>';

Damit wird die Navigation als ungeordnete Liste ausgegeben. Jedoch muss noch abgefangen werden, dass bei “leerer” Navigation (also sollten keine Content-Seiten vorhanden sein) trotzdem noch etwas ausgegeben wird. Denn sonst hätten wir ein <ul class="navilist"></ul> im Quelltext stehen, was zu Anzeigefehlern führen kann und außerdem kein valides XHTML ist.

xt:Commerce verhindert die Ausgabe “leerer” Navigationen mit dieser Abfrage (Zeile 61 / 62)

if ($content_string != '')
$box_smarty->assign('BOX_CONTENT', $content_string);

Das muss dann entsprechend angepasst werden - in die Bedingung $content_string != ” wäre dann das einzutragen, was bei nicht-vorhandenen Seiten von der Navigation “übrig” bleiben würde. In unserem Fall würde das so aussehen:

if ($content_string != '<ul class="navilist"></ul>  ')
$box_smarty->assign('BOX_CONTENT', $content_string);

Markieren der gerade aktiven Seite

Innerhalb der erwähnten While-Schleife muss noch dafür gesorgt werden, dass xt:Commerce je nach “Zustand” der Variablen $content_string eine entsprechende CSS-Klasse hinzufügt. Mit folgender Abfrage

if ($_GET['coID'] == $content_data['content_group']) { ... } else { ... }

… kann man vergleichen, ob die aktive Seite mit der gerade in der Schleife abgefragten Seite übereinstimmt. Ich hab mich dazu entschieden, den aktiven Links die CSS-Klasse “gewaehlt” zu geben. Die angepasste While-Schleife sieht dann so aus:

while ($content_data = xtc_db_fetch_array($content_query, true))
{
$SEF_parameter = '';
if (SEARCH_ENGINE_FRIENDLY_URLS == 'true')
{
$SEF_parameter = '&content='.xtc_cleanName($content_data['content_title']);
}
if ($_GET['coID'] == $content_data['content_group'])
{
$content_string .= '<li><a class="gewaehlt" href="'.xtc_href_link(FILENAME_CONTENT, 'coID='.$content_data['content_group'].$SEF_parameter).'">'.$content_data['content_title'].'</a></li>';
}
else
{
$content_string .= '<li><a href="'.xtc_href_link(FILENAME_CONTENT, 'coID='.$content_data['content_group'].$SEF_parameter).'">'.$content_data['content_title'].'</a></li>';
}
}
$content_string .= '</ul>';
if ($content_string != '<ul class="navilist"></ul>')
{
$box_smarty->assign('BOX_CONTENT', $content_string);
}

Damit wäre die HTML-Ausgabe der Seiten-Navigation wie gewünscht realisiert.

Download

Ein wichtiger Hinweis: Mit den hier gezeigten Code-Beispielen wäre der Quelltext nicht “ordentlich” eingerückt. Leider hab ich noch keine geeignete Möglichkeit gefunden, in Wordpress Code-Beispiele so zu posten, dass man sie einfach kopieren und einfügen kann. Und bei den xt:Commerce-Beispielen werden bisweilen auch die Zeilenumbrüche und Tabulatoren in diversen Zeichenketten miteinander verglichen.

Also am besten herunterladen! Dann funktioniert’s auch wie gewünscht. Die Dateien liegen gezippt zum Download bereit:

  1. “information.php”: xt:Commerce - “information.php” tabellenfrei
  2. “content.php”: xt:Commerce - “content.php” tabellenfrei

Beide Dateien entpacken und die “information.php” sowie die “content.php” in das Template-Verzeichnis “source”/”boxes” hochladen. Der Pfad könnte also heißen:
“http://www.meinshop.de/templates/meintemplate/source/boxes/”

Weitere Hinweise:

Wie immer gilt: Vor solchen Aktionen immer eine Sicherheitskopie der zu überschreibenden Dateien anfertigen! Oder aber die Original-Dateien vorm Upload der neuen Dateien umbennen, beispielsweise in “information_ORIGINAL.php” und “content_ORIGINAL.php”. Das spart Nerven, falls etwas plötzlich gar nicht mehr funktionieren mag.

Diese geänderten Dateien sind für xt:Commerce in der Version 3.04 gedacht. Ältere Versionen benutzen teilweise andere Benennungen! Die hier beschriebene Vorgehensweise kann zwar durchaus auch mit 3.03-Installationen funktionieren, man sollte aber unbearbeitete Template-Dateien “zum Vergleichen” vorliegen haben …

 

Bitte beachten Sie unbedingt die allgemeinen Hinweise zur Verwendung hier veröffentlichter Code-Beispiele!