Man kennt das Problem als Template-Bauer - bei mehrspaltigen Listen muss man immer einen Zähler mitlaufen lassen, damit “bei Erreichen der gewünschten Spalten-Zahl” eine neue Zeile angefangen wird.

Meistens kommt man um “eingebundenes” PHP nicht herum - Und eigentlich einfache “Regeln” werden im Code ziemlich schnell ziemlich unübersichtlich.

 

Tabellen-Layout

Ich mag’s nicht. Ist mir viel zu kompliziert. Warum, sollte in den folgenden Beispielen deutlich werden.

Trotzdem ist diese “Technik” in vielen (wenn nicht gar den meisten) Shop-Templates zu finden - Und diese Tabellen-Templates bauen ihre mehrspaltigen Auflistungen (hier: dreispaltig) dann auch noch in etwa so auf …


{php} $col=0; {/php}
<table>
<tr>
{foreach name=aussen item=module_data from=$module_content}
{php} $col++; {/php}
<td>
... {$module_data.CATEGORIES_NAME} ... <br />
... und so weiter ... <br />
</td>
{php} if ($col>=3) { $col=0; echo "</tr><tr>"; } {/php}
{/foreach}
</tr>
</table>

… und übernehmen dabei brav alle Fehler im Standard-Template “xtc4″ (Das Ding ist sowieso die reine Frechheit). Im Grunde müsste man nach dem Ende der Schleife nachprüfen, wie viele Tabellen-Zellen noch kommen müssten, damit keine unvollständigen Zeilen zurückbleiben.

Denn wenn man nur vier Kategorien (oder Produkte, was auch immer) zu zeigen hat, hätte die letzte Zeile nur eine statt drei Zellen. Ei was machen wir da …


{php} $col=0; {/php}
<table>
<tr>
{foreach name=aussen item=module_data from=$module_content}
{php} $col++; {/php}
<td>
... {$module_data.CATEGORIES_NAME} ... <br />
... und so weiter ... <br />
</td>
{php} if ($col>=3) { $col=0; echo "</tr><tr>"; } {/php}
{/foreach}
{php} if ($col!=0) { echo str_repeat("<td></td>", 3-$col); } {/php}
</tr>
</table>

… das ist besser, aber immer noch nicht ganz korrekt. Zwar wären schon mal die Fehler bei “unvollständigen Zeilen” behoben. In beiden vorhergehenden Beispielen würde (bei einer durch drei teilbaren Anzahl von Kategorien) am Ende immer noch eine leere Tabellenzeile <tr></tr> ausgegeben werden. Und das dann auch noch ohne Zellen. Hm …

Für eine wirklich “ordentliche” Tabelle (Harhar, ein Hohn!) müsste man daher noch ein bisschen mehr PHP-Gefummel veranstalten:


{php} $col=0; {/php}
<table>
{foreach name=aussen item=module_data from=$module_content}
{php} $col++; if($col == 0) { echo "<tr>"; } {/php}
<td>
... {$module_data.CATEGORIES_NAME} ... <br />
... und so weiter ... <br />
</td>
{php} if ($col>=3) { $col=0; { echo "</tr>"; } {/php}
{/foreach}
{php} if ($col!=0) { echo str_repeat("<td></td>", 3-$col); echo "</tr>"; } {/php}
</table>
	

… ja, sonst noch Fragen?

 

DIV-Layout

Deutlich weniger HickHack hat man bei CSS-basierten Templates. Der Code ist übersichtlicher, man verdaddelt sich nicht so leicht - und die Suchmaschinen freuen sich auch.

Da braucht man nur etwas nach diesem Prinzip in seine Listing-Dateien zu schreiben:

{php} $col=0; {/php}
{foreach name=aussen item=module_data from=$module_content}
{php} $col++; {/php}
<div>
... {$module_data.CATEGORIES_NAME} ... <br />
... und so weiter ... <br />
</div>
{php} if ($col>=3) { $col=0; {/php}
<br style="clear:both" />
{php} } {/php}
{/foreach}

… und das sieht doch schon mal erheblich freundlicher aus.

Es geht aber noch ein Stückchen freundlicher.

 

Kein Gefummel mit “Zähler-Variablen”

Egal ob DIV- oder Tabellen-Layout - Die eingebauten php-Zähler fördern nicht unbedingt die Übersicht. Auf der Suche nach einer eleganteren Lösung bin ich bei den Smarty-PlugIns fündig geworden.

Das PlugIn, das meinen Wünschen am nächsten kam, kann » hier begutachtet werden. Doch das Teil hat einen ärgerlichen Schönheitsfehler: Es funktioniert einfach nicht.

Und es ist außerdem für PHP5 geschrieben - Dort “kennt” die Funktion array_slice ein paar Parameter mehr als mein olles PHP vierkommanochwas. Zudem werden die ursprünglichen “Reihenfolgen” durcheinandergeworfen.

Ob das mit den “durcheinandergeworfenen Reihenfolgen” unter PHP5 auch noch so ist, konnte ich nicht ausprobieren. Aber ein paar Kontroll-Ausgaben einiger Zähler etc. (es lebe print_r) haben mich zu dem Schluss gebracht, dass die Sache auch auf neueren Servern nicht ordentlich laufen kann.

Daher waren ein paar Überarbeitungen nötig. Bei der Gelegenheit hab ich das PlugIn zudem “umgetauft” und dafür gesorgt, dass einige “Zähler” (vorwärts und rückwärts laufend) gleich in Smarty-Tags umgewandelt werden, mit denen man weitere lustige Sachen anstellen kann.

 

Block-Funktion: {ListingVars}{/ListingVars}

“Alles neu, macht der Mai April” … Den Download finden Sie » weiter unten … So geht’s - Anwendung bei Tabellen-Layout (Beispiel: dreispaltig)


<table>
{ListingVars count=3 from=$module_content item=outer}
<tr>
{foreach item=module_data from=$outer}
<td>
... {$module_data.CATEGORIES_NAME} ... <br />
... und so weiter ... <br />
</td>
{/foreach}
</tr>
{/ListingVars}
</table>

… und die fehlenden Tabellenzellen ignoriere ich hier einfach mal.

Es läuft jedoch eine Variable $ColCount mit, die man zum Beheben der HTML-Fehler gerne einsetzen kann. Nur da meiner Meinung nach Tabellen für SO etwas ohnehin schon ein Fehler sind, gehe ich an dieser Stelle nicht weiter darauf ein.

:-)

… jetzt nich’ schimpfen. Lieber keine Tabellen benutzen!

 

Das hier macht (mir jedenfalls) sehr viel mehr Spaß - Anwendung bei DIV-Layout (Beispiel: dreispaltig)


{ListingVars count=3 from=$module_content item=outer}
{foreach item=module_data from=$outer}
<div>
... {$module_data.CATEGORIES_NAME} ... <br />
... und so weiter ... <br />
</div>
{/foreach}
<br style="clear:both" />
{/ListingVars}

Knurz und kapp. Kurz und knapp. Ohne reingefummeltes PHP. Und wenn man von drei- auf vierspaltig “umsteigen” möchte, braucht man nur den Wert für count umzustellen.

 

Die “Listing-Variablen”

Gezählt werden muss manchmal trotzdem. Daher laufen in “ListingVars” fünf Zählervariablen und einige weitere Hilfsvariablen mit, die automatisch in “direkt einsetzbare” Smarty-Tags umgewandelt werden. Man kann die Zeilen-Nummer (vorwärts und rückwärts) sowie die Spaltennummer (vorwärts und rückwärts) im Template benutzen.

Diese “ListingVars” (deswegen überhaupt auch meine Umbenennung) heißen so …


$FirstRow 	(true in der ersten Zeile, sonst false, außerhalb foreach)
$LastRow  	(true in der letzte Zeile, sonst false, außerhalb foreach)
$RowClass 	("FirstRow" in der ersten Zeile,
		"LastRow" in der letzten Zeile,
		ansonsten leer, außerhalb foreach)
$RowCount 	(Zeilen-Nummer, außerhalb foreach)
$revRowCount 	("reverse" Zeilen-Nummer, außerhalb foreach)

$FirstCol  	(true in der ersten Spalte, sonst false, außerhalb foreach)
$LastCol  	(true in der letzte Spalte, sonst false, außerhalb foreach)
$ColClass 	("FirstCol" in der ersten Spalte,
		"LastCol" in der letzten Spalte,
		ansonsten leer, innerhalb foreach)
$ColCount 	(Spalten-Nummer, innerhalb foreach)
$revColCount 	("reverse" Spalten-Nummer, innerhalb foreach)

$FirstItem 	(true beim ersten Element, sonst false, innerhalb foreach)
$LastItem 	(true beim letzten Element, sonst false, innerhalb foreach)
$ItemClass 	("FirstItem" beim allerersten Element,
		 "LastItem" beim allerletzen Element,
 		 innerhalb foreach)

$AbsCount 	(durchlaufender Zähler, innerhalb foreach)
	

… und stehen teils innerhalb und teils außerhalb der foreach-Schleife zur Verfügung.

Ein Einsatzbeispiel für diese zusätzlichen “Smartys” wären mehrspaltige Auflistungen, in denen die erste und letzte Zeile anders als die “Mitten-Zeilen” aussehen sollen. Das Gleiche könnte man auch mit der ersten und letzte Spalte einer Zeile machen …


{ListingVars count=3 from=$module_content item=outer}
<div class="{$RowClass}">
{foreach item=module_data from=$outer}
<div class="{$ColClass}">
... {$module_data.CATEGORIES_NAME} ... <br />
... und so weiter ... <br />
</div>
{/foreach}
</div>
{/ListingVars}
	

… den <br style="clear:both" /> brauchen wir dann (in den meisten Fällen) auch nicht mehr, denn ob “umgebrochen” werden soll oder nicht - ist dann eine Sache des Stylesheets.

Und im Stylesheet kann man jetzt bequem die “Eigenarten” der Rand-Zeilen (bzw. Spalten) ausarbeiten, wobei der “letzte Eintrag” (ebenso wie der erste) immer die Nummer 1 hat. Das kann dann in etwa so aussehen:

div.FirstRow 	{ ... Besonderheiten für die erste Zeile ... }
div.LastRow 	{ ... Besonderheiten für die letzte Zeile ... }
div.FirstCol 	{ ... Besonderheiten für die erste Spalte ... }
div.LastCol 	{ ... Besonderheiten für die letzte Spalte ... }

 

Am besten testen:

Um einen Überblick darüber zu bekommen, welche Smartys von “ListingVars” innerhalb der “foreach”-Schleife gebaut werden (außerhalb sind’s nur $RowCount und $revRowCount), einfach mal (z.B. in einem der Kategorie-Listen Templates) Folgendes eintragen:

{ListingVars count=3 from=$module_content item=outer}
FirstRow: {$FirstRow}<br />
LastRow: {$LastRow}<br />
RowClass: {$RowClass}<br />
RowCount: {$RowCount}<br />
revRowCount: {$revRowCount}<br />
{foreach name=aussen item=module_data from=$outer}
<pre>{php} print_r($this->_tpl_vars[module_data]); {/php}</pre>
{/foreach}
{/ListingVars}

… das dürfte die Template-Bauer unter Ihnen auf einige Vereinfachungs-Ideen bringen. Für viele Layout-Anforderungen könnte so etwas hier ebenso interessant sein:


{ListingVars count=3 from=$module_content item=outer}
{foreach item=module_data from=$outer}
{if $module_data.FirstItem}Ich bin erster:
{elseif $module_data.LastItem}Ich bin letzter:
{else}Ich bin mittendrin: {/if}{$module_data.CATEGORIES_NAME} <br />
{/foreach}
{/ListingVars}
	


Zur Erinnerung:
Ohne “ListingVars” würde oben genanntes Beispiel in etwa so aussehen:

{php}
$count = 0;
$alle = count($this->_tpl_vars[module_content]);
{/php}
{foreach name=aussen item=module_data from=$module_content}
{php}
if($count==0)
	echo 'Ich bin erster: ';
elseif($alle-$count > 1)
	echo 'Ich bin mittendrin: ';
else
	echo 'Ich bin letzter: ';
$count++;
{/php}
{$module_data.CATEGORIES_NAME} <br />
{/foreach}

… womit jedoch nur eine Unterscheidung zwischen “erster” und “letzter” Kategorie möglich wäre. Dinge wie “erste/letzte Spalte”, “erste/letzte Reihe” sind dabei noch gar nicht drin …

Ergo: Mit ListingVars geht’s deutlich einfacher.


Ich wünsche viel Spaß beim Basteln

:-)

 

Download und Installation

» block_ListingVars_10.zip (Version 1.0, April 2007)
» block_ListingVars_11.zip (Update 1.1, April 2007)

  1. Legen Sie einen zusätzlichen PlugIn-Ordner für Ihr Template fest
    (Eine Anleitung dazu finden Sie » hier …)
  2. Speichern Sie die entpackte Datei in diesem Ordner ab
  3. Danach kann die Block-Funktion wie oben beschrieben im Template benutzt werden

 

Noch ein Tipp:

… zum weniger tippen: Wer keine Lust hat, die Bezeichnungen module_data etc. zu übernehmen, kann seinen Smartys (geht aber nur innerhalb der foreach-Schleife) auch andere Namen zuweisen - Zum Beispiel “dings” und “bums” …


{ListingVars count=3 from=$module_content item=dings}
{foreach item=bums from=$dings}
{if $bums.FirstItem}Ich bin erster:
{elseif $bums.LastItem}Ich bin letzter:
{else}Ich bin mittendrin: {/if}{$bums.CATEGORIES_NAME} <br />
{/foreach}
{/ListingVars}
	

Wirklich “festgeklopft” ist nur der Name, aus dem sich das “äußerste from” seine Daten holt. Den Rest können Sie nach Belieben auch gerne in “Leberwurst” oder “KastenBier” etc. umbenennen. Und es funktioniert immer noch.