Joomla! Template Tutorial Teil 4 - Ein flexibles Spaltenraster |
Geschrieben von Tom | |||||||||||||||||||||||||||||||||||||
Samstag, 20. Februar 2010 | |||||||||||||||||||||||||||||||||||||
Nachdem wir im dritten Teil des Joomla Template Tutorials das Template soweit umgesetzt haben, dass eine flexible Breite mit allen gestalterischen Elementen zusammenspielt und Navigation und rechte Spalte soweit waren, wollen wir uns nun als erstes überlegen wie wir das mit den Spalten angehen wollen. Für den weiteren Verlauf des Tutorials, haben wir eine Flows Demo-Seite eingerichtet, unter der der aktuelle Stand des Templates eingesehen werden kann.
Bis jetzt war ich der Meinung,
für ein Demo-Template reicht es aus, wenn wir eine Spalte auf der
rechten Seite haben, bei fehlenden Modulen die rechte Spalte verschwindet und der Content über die gesamte Template Breite läuft. Teil 5 des Joomla! 1.5 Template Tutorials ist fertig! Das Ziel ist klar. Es soll sowohl auf der linken, wie auch auf der rechten Seite des Contents eine Modulspalte möglich sein. Das heißt wir haben insgesamt vier verschiedene Layouts:
Obwohl ich in diesem Teil auch noch Content Overrides behandeln wollte, habe ich nun meine Meinung geändert. Content Overrides sind ein Thema für sich und verdienen einen eigenen Abschnitt. Abgesehen davon, wollte ich den vierten Teil des Tutorials nicht ganz so ausarten lassen wie den dritten. Der Ruf nach mehr SpaltenHier ist es nochmal sehr, sehr, sehr wichtig das zugrunde liegende Konstrukt des Templates verstanden zu haben. Wir haben uns im zweiten Teil des Tutorials für das "Equal-Height-Columns"-Layout von Matthew James Taylor entschieden. Auf seiner Seite ist wunderbar beschrieben und illustriert, wie das Konstrukt genau funktioniert. Wie alle genialen Dinge ist es ausgesprochen einfach, nur dauert es ein wenig hinter die eigentliche Idee zu kommen. Grundsätzlich müssen Sie sich das Konstrukt wie, mmmhh... eine Schultafel vorstellen! Man kann eine Tafel hochschieben und darunter liegt eine Zweite. In der Schule gibt, es soweit ich weiss, nicht drei übereinanderliegende Tafeln, bei unserem Konstrukt schon. Was in der Schule die Tafeln, sind bei unserem Konstrukt die DIVs mit den Klassen .wrap1, .wrap2 und .wrap3. Diese werden anders als in der Schule nicht vertikal, sondern horizontal verschoben. Welches .wrap3 werden Sie sagen. So ein DIV gibt es doch in unserem Template gar nicht? Richtig, aber um eine dritte Spalte realisieren zu können, müssen wir es einführen. Was also vorher so aussah ... <div class="wrap1"> <div class="wrap2"> ...wird nun zu ... <div class="wrap1"> <div class="wrap2"> <div class="wrap3"> ... Drei verschiebbare Tafeln ...äh, DIVs. Das CSS des Konstrukts hat bis jetzt die einzelnen DIVs exakt so verschoben, dass ein Zwei-Spalten Layout entstand. Der wesentliche Punkt war eigentlich nur das CSS right:250px; für das .wrap2 DIV. Genau hier wird die Tafel nach links verschoben, indem der Abstand zum rechten Rand definiert wird. Lassen Sie dies sacken und versuchen Sie das Gesamtkonstrukt zu verstehen.
Hinweis Gut. Wir müssen also die DIVs abhängig von der Anzahl und Kombination der darzustellenden Spalten (Modulpositionen left und right) aktivieren und deaktivieren.
Da
wir IMMER Content darstellen werden, dieser also nicht wie die Spalten
aktiviert oder deaktiviert wird, benötigen wir auf jeden Fall ein DIV
für den Content. Wir lassen also das DIV mit der Klasse .wrap1 unberührt. <?php if($this->countModules('left') || $this->countModules('right')) : ?> <div class="wrap2"> <?php endif ?> Damit stellen wir sicher, dass das DIV dargestellt wird, wenn, entweder in der linken oder in der rechten Modulposition, Module dargestellt werden sollen. Anders formuliert: Das DIV wird ausgegeben, wenn mindestens eine Modulposition Module beinhaltet. Ähnlich sieht es mit dem neuen .wrap3 DIV aus. Dieses benötigen wir allerdings nur, wenn wirklich beide Spalten dargestellt werden sollen. Aus einem ODER wird also ein UND. <?php if($this->countModules('left') && $this->countModules('right')) : ?> <div class="wrap3"> <?php endif ?> Das Gleiche müssen wir natürlich noch bei den schließenden DIV-Tags weiter unten in der index.php machen: <?php if($this->countModules('left') || $this->countModules('right')) : ?> </div> <?php endif ?> Jetzt haben wir das nötige HTML um entsprechend der darzustellenden Modulpositionen (Spalten) dass CSS so zu formulieren, dass diese passend verschoben werden. Schauen Sie sich zu diesem Zeitpunkt bloß nicht das Frontend an. Es ist ein Chaos. Ein gutes Template bringt eigene Werkzeuge mit
Um Herr über das Chaos zu werden, gibt es nur einen Weg: Mathematik! <style type="text/css"> .wrapper {width: <?php echo $this->params->get('width'); ?>px;} #main {width:<?php echo $this->params->get('width')-270; ?>px;} .page {min-width:<?php echo $this->params->get('width'); ?>px;} </style> Das ist im Prinzip die einfache Version von dem was wir benötigen, um unsere Spalten so flexibel wie gewünscht darzustellen. Um unsere index.php jetzt allerdings nicht mit PHP-Anweisungen zu überfrachten, betreiben wir ein wenig Outsourcing. Ich werde die nötigen Abfragen und die daraus resultierenden Anweisungen in eine separate PHP-Datei auslagern, welche uns vielleicht an späterer Stelle noch weitere Hilfsarbeiten rund um das Template abnehmen kann. Eine kleine Werkzeugkiste für das Flows-Template wenn Sie so wollen. Wir erzeugen im Template Verzeichnis eine leere PHP-Datei namens flowtools.php. Darin erstellen wir erstmal eine Basis Hilfsklasse: <?php // unsere Hilfsklasse class flowtools { // ein Klassenattribut var $tmpl = null; // Konstruktor der Klasse. Weist dem Klassenattribut tmpl das aktuelle Template zu function flowtools(&$tmpl) { $this->tmpl = $tmpl; } // Funktion generiert nötiges inline CSS function genInlineCSS() { $css = array(); $css[] = '<style type="text/css">'; $css[] = '.wrapper {width: ' . $this->tmpl->params->get('width') . 'px;}'; $css[] = '#main {width:<?php echo $this->params->get('width')-270; ?>px;}'; $css[] = '.page {min-width: ' . $this->tmpl->params->get('width') . 'px;}'; $css[] = '</style>'; // liefert das inline CSS. Durch Zeilenumbrüche getrennt ums leserlicher zu machen return implode("\n", $css); } } // Erzeugt das flowtools Objekt und übergibt dem Konstruktor das aktuelle Template $ftools = new flowtools($this); ?> In der index.php wo vorher unser inline CSS stand ersetzen wir dieses mit <?php echo $ftools->genInlineCSS(); ?> Mit ein wenig PHP-Kenntnissen erkennt jeder was hier passiert. Im Grunde genau das Gleiche wie vorher im inline-CSS. Nur dass wir uns jetzt in der eigens angelegten Funktion genInlineCSS austoben können und die index.php übersichtlich bleibt. genInlineCSS soll übrigens "generiere das inline CSS" heissen... Ein wenig Mathe muss seinAs nächsten Schritt gilt es, die oben genannten vier verschiedenen Layoutfälle (linke Spalte hier, rechte Spalte da, usw.) in unserer Klasse abzufragen und entsprechendes inline CSS zu generieren. Fangen wir mit dem einfachsten Fall an. Dieser wäre das Layout ohne Spalten, also nur Content über die gesamte Breite. Da wir das #main DIV abhängig vom aktuellen Layout definieren müssen, nehmen wir es in die Abfragen hinein. Der erste Fall sieht dann so aus: // keine Spalten + Content if(!($this->tmpl->countModules('left') || $this->tmpl->countModules('right'))) { $css[] = '#main {'; $css[] = 'width:' . ($this->tmpl->params->get('width')-20) .'px;'; $css[] = 'left:0px;'; $css[] = '}'; $css[] = '.wrap1 {background-color:#fff;}'; } Das war recht einfach. Wenn keine Module in Position left oder right sind, wird die Breite des #main DIV auf die komplette im Backend angegebene Template Breite gesetzt, fertig. Da bei vorhandenen Spalten das .wrap1 DIV auch mal für eine Spalte genutzt wird, müssen wir ihm hier eine Hintergrundfarbe zuweisen, um die Farbe aus den Farbvariation CSS (aus Teil zwei des Tutorials) zu überschreiben. Die index.php kümmert sich darum, siehe oben, dass die DIVs .wrap2 und .wrap3 gar nicht erst ausgegeben werden. Machen wir weiter mit der Layoutvariante, bei der nur die rechten Spalte dargestellt werden soll. Dabei müssen wir beachten, dass die Spalten eine feste Breite von 250px haben sollen. // rechte Spalte + Content if((!$this->tmpl->countModules('left') && $this->tmpl->countModules('right'))) { $css[] = '#main {'; $css[] = 'width:' . (($this->tmpl->params->get('width')-270)) .'px;'; $css[] = 'left:250px;'; $css[] = '}'; $css[] = '#right {'; $css[] = 'left: 250px;'; $css[] = 'width: 250px;'; $css[] = '}'; $css[] = '.wrap2 {background-color:#fff;right: 250px; }'; } Im Prinzip war dies der Standard Fall im Verlauf des Tutorials. das #main DIV wird um die Breite der Modulspalte, also um 250px schlanker. Die 270px kommen durch die 10px padding auf jeder Seite zu Stande. Die restlichen Anweisungen sind das übliche "Tafelschieben" für diese Layoutvariante.
Die Layoutvariante mit nur einer linken Spalte sieht nicht viel anders aus. Der einzige Unterschied liegt in der Art, wie wir die DIVs verschieben, also den Pixelangaben. // nur linke Spalte if((!$this->tmpl->countModules('right') && $this->tmpl->countModules('left'))) { $css[] = '#main {'; $css[] = 'width:' . ($this->tmpl->params->get('width')-270) .'px;'; $css[] = 'left:' . ($this->tmpl->params->get('width')-270) .'px;'; $css[] = '}'; $css[] = '#left {'; $css[] = 'left: ' . ($this->tmpl->params->get('width')-270) .'px;'; $css[] = 'width:250px;'; $css[] = '}'; $css[] = '.wrap1 {background-color:#fff;}'; $css[] = '.wrap2 {right:' . ($this->tmpl->params->get('width')-270) .'px;}'; } Als letztes folgt noch der Fall, in dem ein Drei-Spalten-Layout möglich sein soll. Dies ist der einzige Fall, in dem alle drei Tafeln bzw. DIVs (.wrap1, wrap2 und wrap3) zum Einsatz kommen. Dementsprechend müssen wir hier etwas mehr CSS definieren. // beide Spalten if($this->tmpl->countModules('right') && $this->tmpl->countModules('left')) { $css[] = '#main {'; $css[] = 'width:' . ($this->tmpl->params->get('width')-520) .'px;'; $css[] = 'left:' . ($this->tmpl->params->get('width')-270) .'px;'; $css[] = '}'; $css[] = '#left {'; $css[] = 'left:' . ($this->tmpl->params->get('width')-270) .'px;'; $css[] = 'width: 250px;'; $css[] = '}'; $css[] = '#right {'; $css[] = 'left:' . ($this->tmpl->params->get('width')-270) .'px;'; $css[] = 'width: 250px;'; $css[] = '}'; $css[] = '.wrap2 {background-color:#fff;right:250px;}'; $css[] = '.wrap3 {right:' . ($this->tmpl->params->get('width')-520) .'px;}'; }
Die
Breite des #main DIVs wird um die Breiten der beiden Spalten reduziert
(250px + 250px + 20px padding). Der Rest ist die übliche Schieberei,
die bei drei DIVs nötig ist. Warum nicht variable Spaltenbreiten?Wenn man sich das layoutabhängige inline CSS dort oben anschaut, kommt man als Templatebauer nicht um eine Frage herum: Warum ersetzen wir diese ganzen Konstanten nicht durch definierbare Parameter? Mit anderen Worten: Warum lassen wir den Webseitenbetreiber nicht über die Spaltenbreite per Templateparameter entscheiden. Und zwar für jede separat...Muahahaa! Schließlich haben wir eine flexible Templatebreite und da macht es Sinn in machen Fällen die rechte Spalte auf eine Breite von z.B. 400px zu setzen. Gesagt, getan. Wie im vorigen Teil des Tutorials beschrieben, erstellen wir zwei weitere Template Parameter für die linke und rechte Spalte. Diese Parameter habe ich width-left und width-right genannt. Das ganze sieht im Backend dann wie im Bild links aus. So, nun müssen wir nur noch zusehen, dass die Parameterwerte auch ihren Weg in das inline CSS finden. In der genInlineCSS Funktion holen wir uns zunächst die Werte aus dem Parameter Objekt. ... function genInlineCSS() { $leftw = $this->tmpl->params->get('width-left'); $rightw = $this->tmpl->params->get('width-right'); ...
Nun haben wir die im Backend definierten Breiten der beiden Spalten in den Variablen $leftw und $rightw. Diese können wir recht einfach in das inline CSS einbauen. // rechte Spalte + Content if((!$this->tmpl->countModules('left') && $this->tmpl->countModules('right'))) { $css[] = '#main {'; $css[] = 'width:' . (($this->tmpl->params->get('width')-270)) .'px;'; $css[] = 'left:250px;'; $css[] = '}'; $css[] = '#right {'; $css[] = 'left: 250px;'; $css[] = 'width: 250px;'; $css[] = '}'; $css[] = '.wrap2 {background-color:#fff;right: 250px; }'; } wird nun zu // rechte Spalte + Content if((!$this->tmpl->countModules('left') && $this->tmpl->countModules('right'))) { $css[] = '#main {'; $css[] = 'width:' . (($this->tmpl->params->get('width')-$rightw-20)) .'px;'; $css[] = 'left:'.$rightw.'px;'; $css[] = '}'; $css[] = '#right {'; $css[] = 'left: '.$rightw.'px;'; $css[] = 'width: '.$rightw.'px;'; $css[] = '}'; $css[] = '.wrap2 {background-color:#fff;right: '.$rightw.'px; }'; } Trivial, nicht wahr? Die ganze Funktion mit Parametern ersetzt, erspare ich mir hier einzufügen. Wichtig ist das Ergebnis, und das kann sich sehen lassen.
Hinweis Das Flows Template wird installationsfähigWozu die templateDetails.xml da ist und was sie beinhaltet, haben wir bereits besprochen. Nun erweitern wir sie derart, dass unser Template nicht mehr manuell in das Template Verzeichnis kopiert werden muss, sondern wie jedes andere Template installiert werden kann. Dazu führen wir direkt hinter dem Description Tag ein neuen Bereich names Files hinzu: ... <description>Flows template</description> <files> ... </files> ...
Hier
listen wir nun alle Dateien auf, welche zu unserem Template gehören und
bei der Installation beachtet werden müssen. Das Joomla Framework
kümmert sich darum, dass diese an die richtige Stelle kopiert werden. <files> <filename>templateDetails.xml</filename> <filename>template_thumbnail.png</filename> <filename>params.ini</filename> <filename>flowtools.php</filename> <filename>index.php</filename> <filename>index.html</filename> <filename>favicon.ico</filename> <folder>images</folder> <folder>html</folder> <folder>css</folder> </files> Das sollte alles sein (bis jetzt). Es sind zwei neue Dateien hinzugekommen: template_thumbnail.png und favicon.ico. Das PNG-Bild ist eine kleine Vorschaugrafik unseres Templates und wird nur im Backend bei der Templateauswahl angezeigt. Der Begriff Favicon sollte bekannt sein. Es dient der Darstellung eines kleinen Identifizierungssymbols in der Adresszeile der meisten Browser oder bei deren Favouritenverwaltung. Jetzt müssen wir nur noch das ganze Template Verzeichnis zu einem ZIP-Archiv zusammenpacken und schon haben wir ein installierbares Joomla Template.
Flows-Template mit flexiblem Raster: Teil 5 des Joomla! 1.5 Template Tutorials ist fertig!
Im nächsten Schritt des Tutorials wollen wir uns dann mit den Content Overrides beschäftigen. Wer sich vorab darüber informieren möchte, kann das über einen Artikel zum Thema Overrides tun, den ich vor einer Weile für ein Schweizer Joomla Portal geschrieben habe. Lesezeichen setzen Hits: 50422
Kommentar schreiben
|