Joomla! Template Tutorial Teil 5 - Content Overrides

Geschrieben von Tom   
Montag, 10. Mai 2010

In diesem Teil des Template Tutorials wollen wir uns mit den sogenannten Content Overrides beschäftigen.

Bevor wir jedoch anfangen, möchte ich Ihnen zeigen, wie vielfältig das Flows Template einsetzbar ist. Wir haben kürzlich zwei kleine Kundenprojekte realisiert, für dessen Templateumsetzung wir die Flows Basis herangezogen haben. Sie finden die entstandene Seiten unter www.cmcpu.de und www.vaircon.com. Wie Sie sehen, haben wir einen Slider und eine Dropdown Navigation integriert. Der Rest ist allerdings nur eine Flows Variation, wie in Teil 3 des Joomla Template Tutorials beschrieben. Die index.php mussten wir nicht anfassen.

Keine Sorge, nachdem Sie diesen etwas trockenen Teil des Tutorials hinter sich gebracht haben, werden wir uns im nächsten Teil (und vielleicht letzten) so schicken Dingen wie Slidern und Dropdown Navigationen widmen.

Warum Joomla schlecht kochen kann

Zurück zu den Content Overrides. Diese sind eine Technik, die mit Joomla 1.5 eingeführt wurde. Bei Joomla 1.0 wurden die darzustellenden Inhalte, z. B. der Text eines Artikels, größtenteils durch HTML-Tabellen realisiert. Jeder Webdesigner weiß, dass dies kein guter Ansatz ist, wenn es um Flexibilität, Barrierefreiheit, Semantik und Suchmaschinenoptimierung geht. Bei Joomla 1.0 konnte man nicht viel dagegen tun. Joomla 1.5 hat dies zur Enttäuschung vieler immer noch getan, bot aber gleichzeitig die Möglichkeit, durch Content Overrides Einfluss zu nehmen. Wie also funktionieren Content Overrides?

Stellen Sie sich vor, die darzustellenden Inhalte (also die reinen Daten) entsprechen den Zutaten für ein leckeres Essen. Die Zubereitung und Anrichtung des Essens entspricht dann dem Layout welches die Daten darstellt. Es hängt wie immer am Koch, etwas vernünftiges aus den Zutaten bzw. Daten zu machen. Der Joomlaeigene Koch hat leider schlechte Rezepte und sein Essen entspricht von der Qualität der HTML-Struktur ungefähr einer Pommesbude. Content Overrides sind sozusagen alternative Köche, die man Joomla für die Zubereitung seiner Daten anbieten kann. Der Webdesigner kann seinen Köchen ganz genau sagen, wie er die Zutaten zubereitet haben möchte.

Dies ist möglich, durch das sogenannte MVC-Prinzip, welches bei Joomla 1.5 eingeführt wurde. Sie müssen nicht wirklich wissen, was MVC bedeutet. Für Sie als Templatebauer ist das einzig Wichtige das "V". Dies bedeutet "View" und der View kümmert sich darum, die Daten in ein passendes Layout zu gießen. Dabei kommt es immer darauf an, welche Daten dargestellt werden sollen. In der Regel werden Artikel innerhalb von Joomla von der integrierten Artikel Komponente dargestellt (com_content). Zum Standardumfang gehören aber auch Kontaktdaten, Umfragen, Weblinks usw. All dies sind Komponenten, welche Joomla bereithält und welche auf MVC Basis umgesetzt wurden. Dies ist wichtig, da nur solche Komponenten den Vorteil der Content Overrides nutzen können. Sie können also für jede MVC-Komponente ein Override erstellen. Komponenten wie z. B. Virtuemart oder der Community Builder basieren (noch) nicht auf MVC und können somit nicht auf diese Weise beeinflusst werden.

Ein wichtiger Vorteil hierbei ist, das sämtliche Updates, welche Sie auf Ihrem Joomla System durchführen, ihre Overrides nicht berühren und diese somit weiterhin funktionieren. Wollte man bei Joomla 1.0 die Ausgabe beeinflussen, hätte man das am Core, also an den Joomla Kerndateien selbst tun müssen. Erschien ein Joomla Updat, musste man sich die Änderungen merken, das Update einspielen und die Änderungen erneut durchführen. Da sind Content Overrides viel praktischer, den diese befinden sich außerhalb des Joomla Core und bleiben von Updates unberührt.

Um ein Content Override zu erstellen, müssen Sie nur die entsprechenden Layoutdateien (alternative Köche) in das richtige Verzeichniss legen und Joomla nutzt von da an diese zur Ausgabe der Daten. In welches Verzeichniss müssen die Dateien also rein? Und wie müssen diese Dateien aussehen?

Zur ersten Frage: Ein Content Override muss immer vom aktuellen Template angeboten werden. Wenn Sie also das mitgelieferte Purity Template nutzen, sucht Joomla in dessen Verzeichniss nach vorhandenen Overrides. Das gleiche gilt für das Milkyway, Beez und jedes andere Joomla Template. Sind keine Overrides vorhanden, wird der komponenteneigene View zur Ausgabe genutzt (buuuh!). Ein Joomla Template, welches heutzutage keine Overrides anbietet sollte recht kritisch beäugt werden. Content Overrides gehören zum guten Ton eines jeden Joomla Templates. Auf jeden Fall sollten Overrides für die Artikelkomponente (com_content) vorhanden sein.

Die Umsetzung eines einfachen Content Overrides

Gehen wir nun zum praktischen Teil über, indem wir ein Override für das Flows Template erstellen. Um ein Override anzubieten, müssen wir uns erstmal überlegen, für welche Komponente wir eines erstellen wollen. Natürlich muss Flows ein Override für die Artikelkomponente bereithalten. Overrides für diese Komponente sind allerdings etwas umfangreicher, und deswegen möchte ich mit etwas einfacherem anfangen.
Nehmen wir die Kontakt Komponente. Diese kümmert sich um die Darstellung der unter "Kontakte" vorhandenen Inhalte. Also eines einzelnen Kontakts und einer Kontaktkategorie. Wenn kein Override vorhanden ist, stellt Joomla die Daten auch hier in einem hässlichen Tabellenlayout dar. Hier wollen wir Abhilfe schaffen und ein Override erstellen, welches eine vernünftige Darstellung sicherstellt.

Die Kontakt Komponente ohne OverridesIm Bild links sehen Sie eine beispielhafte Kontaktansicht ohne Override. In dem blauen Bereich sehen sie die Firebug Ausgabe der HTML-Struktur. Hier kann man sehen, dass der entsprechende Inhalt mit HTML-Tabellen ausgegeben wird.

Um dies zu ändern, müssen wir ein Override für die Komponente (com_contact), dessen Ausgabe wir beeinflussen wollen, erstellen und an den richtigen Ort legen. Wie bereits oben erwähnt, befinden sich Overrides in den Template Ordnern. Die Platzierung der Overrides hängt direkt mit den Views der entsprechenden Komponente zusammen. Wenn wir also ein Menüpunkt erzeugen, welcher auf die Detailansicht eines Kontakts verweist, sieht das wie auf dem Bild unten aus. Views der Kontakt KomponenteSie sehen hier die zwei möglichen Views der Kontakt Komponente. Einmal die Anzeige einer Kontakt Kategorie und einmal die Anzeige eines einzelnen Kontaktes. Für das Zweitere wollen wir ein Override erstellen.

Es gibt verschiedene Wege, damit zu beginnen. Am einfachsten ist es, das Joomla Standard Layout (den hauseigenen Koch) zu nehmen, in das passende Override Verzeichnis zu kopieren und anzupassen. Also das Tabellenlayout in ein tabellenfreies Layout umzuwandeln. Das Joomla eigene Layout finden Sie im Verzeichnis der Kontaktkomponente. Sie können aber auch ein Override eines anderen Templates als Ausgangsbasis nehmen.

Verzeichnisstruktur der Kontakt Komponente Im Bild links sehen sie die Joomla Verzeichnisstruktur der Kontakt Komponente. Im Verzeichnis views sehen Sie die beiden Layoutverzeichnisse contact und categorie. Diese entsprechen den beiden möglichen Views der Kontakt Komponente.

Nun wollen wir endlich das Override erstellen. Im Flows Verzeichnis haben wir bereits ein html Verzeichnis erstellt, welches das im Teil 4 des Template Tutorials behandelte Modul Chrome enthällt. In diesem Verzeichnis sucht Joomla auch nach evtl. vorhandenen Content Overrides. Wir erstellen also im html Verzeichnis des Flows Templates das Verzeichnis com_contact. Darin werden sich die Overrides für die Kontakt Komponente befinden. Nun bietet die Komponente die oben beschriebenen zwei möglichen Views. Um ein Override für die Kontakt Detailansicht zu erstellen, erstellen wir im com_contact Verzeichnis das Verzeichnis contact. Hier hinein plazieren wir die Overrides für die Darstellung eines einzelnen Kontaktes. Wie gesagt können wir das tun, indem wir das Joomla eigene Layout für diesen Fall einfach übernehmen und anpassen.

Das Joomla eigene Layout für diesen Fall entnehmen wir also dem tmpl Verzeichnis innerhalb des contact Verzeichnisses wie auf Bild 3 dargestellt. Die Layout Dateien, welche wir benötigen heißen default.php, default_address.php und default_form.php.

Warum drei Dateien für die Darstellung der Kontakt Detailansicht, werden Sie fragen?
Nun, Layouts können auch Sublayouts beinhalten. Wenn Sie z. B. an die Blogansicht einer Kategorie denken, werden dort alle Artikel einer Kategorie untereinander dargestellt. Um sich die Arbeit zu erleichtern, kann man also in einer Schleife alle darzustellenden Artikel durchgehen und mit Hilfe eines Subtemplates darstellen. Dieses Subtemplate ist dann nur für die Darstellung eines Artikels zuständig und wird vom Haupttemplate beliebig oft aufgerufen.

Ähnlich ist es bei unserem Kontakt Override. Das Haupttemplate heisst hier default.php. Dieses Haupttemplate bindet die beiden Subtemplates default_address.php und default_form.php ein. Sie können Ihr Override natürlich auch ohne Subtemplate erstellen. Mit wird das Override einfach etwas unübersichtlicher.
Verzeichnis des Kontakt OverridesNachdem Sie also die Joomla eigenen Layouts in das passende Flows Verzeichnis kopiert haben, sollte das Verzeichnis wie in Bild 4 ausschauen.

Nun schauen wir uns mal die Joomla eigenen Köche an, in der Hoffnung Ihnen ein besseres Rezept beibringen zu können. Sehen wir uns zunächst (und nur kurz!!) den Quellcode des Hauptlayouts default.php an:

<?php
/**
 * $Id: default.php 11917 2009-05-29 19:37:05Z ian $
 */
defined(
'_JEXEC' ) or die( 'Restricted access' );
$cparams =
JComponentHelper::getParams ('com_media');
?>
<?php if (
$this->params->get( 'show_page_title', 1 ) &&
!$this->contact->params->get( 'popup' ) &&
$this->params->get('page_title') != $this->contact->name ) :
?>
    <div class="componentheading<?php echo $this->escape($this->params->get('pageclass_sfx')); ?>"> 
     <?php echo $this->params->get( 'page_title' ); ?>  
 </div>
<?php endif; ?>
<div
id="component-contact">
<table width="100%" cellpadding="0"
cellspacing="0" border="0" class="contentpaneopen<?php echo
$this->escape($this->params->get('pageclass_sfx')); ?>">
<?php
if ( $this->params->get( 'show_contact_list' ) && count(
$this->contacts ) > 1) : ?>
<tr>
    <td
colspan="2" align="center">
        <br />
      
 <form action="<?php echo JRoute::_('index.php') ?>"
method="post" name="selectForm" id="selectForm">
        <?php
echo JText::_( 'Select Contact' ); ?>:
            <br />
  
         <?php echo JHTML::_('select.genericlist', 
$this->contacts, 'contact_id', 'class="inputbox"
onchange="this.form.submit()"', 'id', 'name',
$this->contact->id);?>
            <input type="hidden"
name="option" value="com_contact" />
        </form>  
 </td>
</tr>
<?php endif; ?>
<?php if (
$this->contact->name &&
$this->contact->params->get( 'show_name' ) ) : ?>
<tr> 
 <td width="100%" class="contentheading<?php echo $this->escape($this->params->get('pageclass_sfx')); ?>"> 
     <?php echo $this->escape($this->contact->name); ?> 
 </td>
</tr>
<?php endif; ?>
<?php if (
$this->contact->con_position &&
$this->contact->params->get( 'show_position' ) ) : ?>
<tr> 
 <td colspan="2">
    <?php echo $this->escape($this->contact->con_position); ?>      
 <br /><br />
    </td>
</tr>
<?php
endif; ?>
<tr>
    <td>
        <table border="0" width="100%">
        <tr>          
 <td></td>
            <td rowspan="2" align="right" valign="top">
            <?php if ( $this->contact->image && $this->contact->params->get( 'show_image' ) ) : ?>     
         <div style="float: right;">                  
 <?php echo JHTML::_('image', 'images/stories' . '/'.$this->contact->image, JText::_( 'Contact' ), array('align' => 'middle')); ?>
                </div>          
 <?php endif; ?>
            </td>
        </tr> 
     <tr>
            <td>
                <?php echo $this->loadTemplate('address'); ?>
            </td> 
     </tr>
        </table>
    </td>  
 <td> </td>
</tr>
<?php if ( $this->contact->params->get( 'allow_vcard' ) ) : ?>
<tr> 
 <td colspan="2">
    <?php echo JText::_( 'Download information as a' );?>
        <a href="<?php echo JURI::base(); ?>index.php?option=com_contact&task=vcard&contact_id=<?phpecho $this->contact->id; ?>&format=raw&tmpl=component">          
 <?php echo JText::_( 'VCard' );?></a>
    </td>
</tr>
<?php
endif;
if ( $this->contact->params->get('show_email_form') && ($this->contact->email_to || $this->contact->user_id))
    echo $this->loadTemplate('form');
?>
</table>
</div>  

Halt! Bevor Sie die Flinte ins Korn werfen, werde ich Ihnen zu einem schnellen Erfolgserlebnis verhelfen. Ersetzen Sie den Quelltext des Layouts (im Flows Override Verzeichnis!) mit folgenden vier Zeilen:

<?php
defined( '_JEXEC' ) or die( 'Restricted access' );
echo $this->contact->name;
?> 

Kontakt Override ohne allesIhr Override für die Kontakt Detailansicht ist fertig! Wenn Sie die Webseite neu laden, sollte Joomla Ihr Override finden und das Ergebnis sollte so aussehen, wie auf Bild 5 dargestellt. Wir kümmern uns in diesem Override um nichts anderes als die Ausgabe des Kontaktnames. Das ist zugegeben nicht viel, aber wenn Sie den Prozess bis hierhin verstanden haben, wissen Sie wie Content Overrides funktionieren. Sie haben Joomla soeben einen neuen Koch verpasst!

Alles, was jetzt folgt, ist die Anpassung bzw. Übernahme der verschiedenen Elemente aus dem großen Layout oben (dem Joomla Koch) in unser eigenes Override. Wenn Sie also wollen, dass die Position des Kontaktes auch ausgegeben wird, machen Sie folgendes:

<?php defined( '_JEXEC' ) or die( 'Restricted access' ); ?>
<p><?php echo $this->contact->name; ?></p>
<p><?php echo $this->contact->con_position; ?></p>

Knaller! Damit sind wir dem Joomla eigenem Layout schon voraus, denn es stellt diese Informationen mit Tabellen dar. Wir nutzen dafür Paragraphen.

Sie werden sich nun zwei Dinge fragen:

  1. Was zum Teufel ist das dort oben alles für PHP-Code?
  2. Woher weiß ich, was es alles für Datenfelder gibt, z. B. con_position?

PHP-Code? Hilfe!

Paramterer der Kontaktkomponente Natürlich stellt ein Layout nicht nur stupide Daten dar. Vielmehr kann es auf bestimmte Einstellungen reagieren und entsprechend die Darstellung der Daten beeinflussen. In der Joomla Kontaktverwaltung sehen sie in der Detailansicht z. B. Kontaktparameter wie in Bild 6 dargestellt.

Welchen Sinn hätte es, diese zu konfigurieren, wenn das Layout nicht darauf reagiert? Wenn unser Override also auf die Einstellung, ob der Kontaktname dargestellt werden soll oder nicht reagieren soll, passen wir das Override wie folgt an:

<?php defined( '_JEXEC' ) or die( 'Restricted access' );?>
<?php
if ($this->contact->params->get('show_name')) : ?> 
<p><?php echo $this->contact->name; ?></p>
<?php endif; ?>
<p><?php echo $this->contact->con_position;
?></p>

Ähnlich wie bei den im Tutorial Teil 4 besprochenen Modulparametern, greifen wir hier mittels $this->contact->params->get auf Komponentenparameter zu, um die aktuelle Einstellung zu erfahren. Mann kann diese Abfrage noch wie folgt erweitern:

<?php if ($this->contact->name && $this->contact->params->get('show_name')) : ?> 

Damit ist auch sichergestellt, das kein leerer Paragraph dargestellt wird, wenn der Name zwar ausgegeben werden soll, aber ein Name in der Kontaktverwaltung gar nicht eingegeben wurde. Der Name ist nämlich kein Pflichtfeld.

Nun, ein Teil des PHP-Codes erklärt sich also durch die Abfragen der Komponenteneinstellungen. Und da es für die Kontaktkomponente einige davon gibt, muss auch ein wenig PHP-Code rein. Natürlich können Sie in Ihren Overrides auf PHP-Code verzichten und nur die Daten darstellen, von denen Sie wissen, dass Sie sie sehen wollen. Dann sind die Einstellungen der Komponente im Backend für die Katz, aber genau dafür gibt es Overrides. Hier sind Sie Herr und Meister und können sämtlichen Unsinn anstellen.

Zur zweiten Frage: Auf welche Felder Sie überhaupt in Ihrem Override Zugriff haben, richtet sich natürlich nach der Komponente, für die das Override erstellt wird. Im Backend sehen Sie zwar wie in Bild 6 die vorhandenen Felder, jedoch nicht deren konkrete Variablennamen. Diese erfahren Sie nur von den Joomla eigenen Layouts/Köchen. Bei der Erstellung eines Overrides sollten Sie also immer einen Blick entweder in die Joomla eigenen Layouts oder in sein bereits vorhandenes Override eines anderen Template werfen, z. B. des Beez Templates. Dieses besitzt Overrides für alle elementaren Komponenten.

Templates, die Templates laden: Subtemplates!

Schauen wir uns weitere, nicht triviale Elemente des Kontakt Overrides an. Sie finden im Joomla eigenem Layout folgende Zeile:

<?php echo $this->loadTemplate('address'); ?>

Damit wird ein Subtemplate geladen. Das Kontaktlayout besitzt also ein Sublayout, welches allein für die Ausgabe der Adresse zuständig ist. Hierbei ist wichtig zu wissen, dass Namen von Subtemplates immer der Name ihres Haupttemplates vorangestellt ist. Die Datei des Adressen Subtemplates heisst also default_address. Richtig, diese Datei mit Namen default_address.php befindet sich bereits in unserem Override Verzeichniss.

Passen Sie unser Override wie folgt an:

<?php defined('_JEXEC' ) or die( 'Restricted access' ); ?>
<?php if ($this->contact->params->get('show_name')) : ?> 
<p><?phpecho $this->contact->name; ?></p>
<?php endif; ?>
<p><?php echo $this->contact->con_position;?></p>
<?php echo $this->loadTemplate('address'); ?>
und das Adressen Subtemplate default_address.php wie folgt:
<?php defined( '_JEXEC' ) or die( 'Restricted access' );
echo $this->contact->address; 
?>

Damit haben Sie auch Ihr erstes Subtemplate fertiggestellt. Dieses gibt einfach die in der Adressverwaltung eingegebene Adresse des Kontaktes aus. Da ich sämtlichen PHP-Code weggelassen habe, werden die Komponentenparameter nicht berücksichtigt.

Von hier an sollten Sie in der Lage sein, das Override für die Kontaktkomponente fertigzustellen. Natürlich wird Ihnen das Leben durch Exzesse in Sachen Abfragelogik, welche Sie in den Joomla Layouts finden,  schwer gemacht, wie z. B.:

<?php if ( ( $this->contact->params->get( 'address_check' ) > 0 ) &&  ( $this->contact->address || $this->contact->suburb  || $this->contact->state || $this->contact->country || $this->contact->postcode ) ) : ?> 

Aber was passiert hier schlimmes? Hier wird geprüft, ob der Parameter address_check gesetzt ist und ob wenigstens eins der folgenden Felder eingegeben wurde. Damit wird also einfach geprüft, ob überhaupt eine Adresse dargestellt werden soll.

Dann taucht auch folgender Code auf:

<?php echo JHTML::_('image', 'images/stories' . '/'.$this->contact->image, JText::_( 'Contact' ), array('align' => 'middle')); ?> 

Bildparameter der KontaktverwaltungWie Sie wissen, kann in der Kontaktverwaltung einem Kontakt ein Bild zugeordnet werden. Um dieses auszugeben, gibt es verschiedene Möglichkeiten. Mit Hilfe von JHTML geht es natürlich besonders elegant. Aber denken Sie daran: Es ist Ihr Override! Wenn Sie noch nie etwas von JHTML gehört haben, können Sie folgendes machen:

<?php echo '<img  src="images/stories/'.$this->contact->image" />'; ?>

Es geht schließlich nur darum ein Bild auszugeben, richtig? Natürlich ist die obere Methode besser und wenn Sie ernsthaft Joomla Templates bauen wollen, werden Sie früher oder später ein wenig in das Joomla Framework abtauchen müssen.

Das fertige Override für die Kontakt Komponente finden Sie im Download für das Flows Template dieses Tutorial Teils. Dort befindet sich ebenfalls das Override für die zweite Ansicht der Kontaktkomponente, die Kategorieansicht der Kontakte.

com_content - Die Königsdisziplin in Sachen Overrides

Das Override, welches Angst und Schrecken verbreitet ist natürlich jenes für die Hauptkomponente von Joomla, die Artikelverwaltung (com_content).

Mögliche Views der ArtikelkomponenteAlleine die möglichen Anzeigearten, wie links zu sehen, lassen erahnen, wieviele Overrides hier zum Zuge kommen können.

Im Prinzip geht hier aber auch nichts anderes vor, als in der Kontaktkomponente. Wir wollen auch für die Artikelkomponente ein beispielhaftes Override erstellen. Und zwar werden wir ein Override für die Darstellung eines einzelnen Artikels erstellen. Die Prozedur gleicht jener der Kontaktkomponente.
Innerhalb des html Verzeichnisses unseres Flows Templates erstellen wir das Verzeichnis com_content. Darin Erstellen wir das Unterverzeichnis article. Das entspricht wieder genau den Verzeichnissen des Joomla Views (Bild rechts).

Verzeichnisstruktur des Artikel Views

In das Verzeichnis article kommen also die Overrides für die Darstellung eines Artikels.  Kopieren Sie die drei Dateien default.php und form.php in unser Override Verzeichniss. Die Datei default.php ist das Hauptlayout, die form.php ignorieren wir fürs erste. Wenn Sie sich diese Datei ansehen, werden Sie feststellen...so schlimm ist es nicht, oder?

Frontend Editing - wer's braucht...

Was bei den com_content Overrides natürlich ins Gewicht fällt ist der Umstand, dass Joomla auch das sogenannte Frontend Editing erlaubt. Damit können Artikel nicht nur im Backend bearbeitet werden, sondern (wenn die Rechte vorliegen) auch im Frontend, d. h. direkt in der Webseite. Um dies zu ermöglichen, muss das Layout natürlich einiges beachten.
Falls Sie wie ich kein Freund des Frontend Editing sind, können Sie in Ihren Overrides die ganzen Funktionalitäten, welche dafür benötigt werden einfach weglassen. Dann ist Ihr Override einfach für die Darstellung zuständig. Ich werde für das Flows Template natürlich alle Funktionalitäten integrieren, aber im Rahmen des Tutorials das Frontend Editing weglassen.

OK, wir waren beim default.php Override. Löschen Sie alles, was Sie hier sehen und ersetzen Sie es mit:

<?php
// no direct access
defined('_JEXEC') or die('Restricted access');
echo $this->article->title; 
?>

Das war's! Ihr Override für die übermächtige com_content ist fertig. Es kann zwar nur den Titel des Artikels ausgeben, aber immerhin. Auch bei diesem Override geht es wieder darum, alle möglichen Komponentenparameter zu berücksichtigen und in das Override zu integrieren.
Ein ArtikelparameterWie Sie wissen, kann bei der Erstellung eines Menüpunktes, welcher auf einen einzelnen Artikel verweist, ein alternativer Seitentitel eingegeben werden, wie links zu sehen. Um diesen in unserem Override darzustellen und auch die Option "Seitentitel darstellen", weiter unten, einzubauen, machen wir folgendes:

<?php // no direct access
defined('_JEXEC') or die('Restricted access'); ?>
<?php if ($this->params->get('show_page_title', 1)) : ?>
<h1><?php echo  $this->escape($this->params->get('page_title')); ?></h1>
<?php endif; ?>
<?php if 
($this->params->get('show_title')) : ?>
<h2><?php echo $this->article->title;  ?></h2>
<?php endif; ?>

Mit dem Parameter show_page_title fragen wir ab, ob der alternative Seitentitel dargestellt werden soll, und falls ja stellen wir ihn innerhalb eines H1 Tags dar. Den eigentlichen Artikeltitel stellen wir darunter in einem H2 Tag dar, aber nur wenn es im Backend so konfiguriert wurde (show_title).

Der Parameter Verlinkte TitelSie kennen sicherlich den Parameter "Verlinkte Titel" aus dem Backend (Bild links). Damit kann erreicht werden, dass bei Klick auf den Artikeltitel auf den Artikel verlinkt wird. Dies ist in einer Blogansicht sehr praktisch, um nicht immer auf das "weiterlesen" klicken zu müssen.

Nichts weiter als Parameterabfragen:

<?php // no direct access
defined('_JEXEC') or die('Restricted access');?>
<?php if ($this->params->get('show_page_title', 1)) : ?>
<h1><?php echo $this->escape($this->params->get('page_title')); ?></h1>
<?php endif; ?>
<h2>
    <?php if ($this->params->get('link_titles') && $this->article->readmore_link != '') : ?>
    <a  href="<?php echo $this->article->readmore_link; ?>"><?php echo $this->escape($this->article->title); ?></a>
    <?php else :
        echo $this->escape($this->article->title);
    endif; ?>
</h2>

Der fertige Titel Abschnitt des Flows Content Overrides für einen einzelnen Artikel sieht wie folgt aus:

<?php if ($this->params->get('show_page_title',1) && $this->params->get('page_title') != $this->article->title) :?>
<h1 class="componentheading<?php echo $this->escape($this->params->get('pageclass_sfx')); ?>">
       <?php echo $this->escape($this->params->get('page_title'));
?>
</h1>
<?php endif; ?>
<?php $hlvl = ($this->params->get('show_page_title',1) && $this->params->get('page_title') != $this->article->title) ? 2 : 1; ?>
<?php if ($this->params->get('show_title')) : ?>
<h<?php echo $hlvl; ?> class="contentheading<?php echo $this->escape($this->params->get('pageclass_sfx')); ?>">
  
<?php if ($this->params->get('link_titles') && $this->article->readmore_link != '') : ?>
    <a  href="<?php echo $this->article->readmore_link; ?>" class="contentpagetitle<?php echo $this->escape($this->params->get('pageclass_sfx')); ?>">  
     <?php echo $this->escape($this->article->title); ?></a>
    <?php else :
        echo $this->escape($this->article->title);
    endif; ?>
</h<?php echo $hlvl; ?>>
<?php endif; ?> 

Ich finde es immer dumm, wenn der Administrator die Darstellung des Pagetitles deaktiviert und das Template dann den Seitentitel mit einem H2 ausgibt. Hier habe ich mich darum gekümmert, dass eine korrekte Überschriftenstruktur entsteht, egal was man im Backend konfiguriert.

So gilt es, das Artikel Override weiter anzupassen. Wie oben beschrieben, existieren für die Artikelkomponente com_content weitere Darstellungsarten, die hier kurz beschrieben werden und sich im Override Verzeichnis des Flows Templates wiederfinden.

Override View Name im Backend primäre Override Datei
Artikel
article 
Layout: Beitrag (Joomla!-Standard)
default.php
Kategorie category Layout: Kategorieliste (Joomla!-Standard) default.php
Kategorie category Layout: Kategorie-Blog blog.php
Bereich section Layout: Bereichsliste (Joomla!-Standard) default.php
Bereich section Layout: Bereichs-Blog blog.php
Startseite frontpage Layout: Startseiten-Blog default.php

Ein professionelles Joomla 1.5 Template sollte mindestens diese Overrides besitzen.

Was beim Styling von Overrides beachtet werden muss

Die Generierung semantischem, suchmaschinenfreundlichem und barrierefreien HTML-Codes mit Hilfe von Overrides ist eine Sache. Natürlich sollen die Inhalte der Overrides auch gut aussehen. Um die Inhalte mit CSS zu stylen, benötigen diese natürlich ein paar Klassen und IDs. Das haben wir bis jetzt ausgeklammert.

Den Artikelnamen haben wir wie folgt ausgeben:

<h1><?php echo 
$this->escape($this->params->get('page_title')); 
?></h1>

Das Styling des H1 Tags ist also nur über das Tag selbst möglich. Nun kommt eine wichtige Lektion für alle Templatebauer. Joomla selbst und die meisten Templateentwickler nutzen einen kleinen Pool an CSS-Klassen und IDs zum stylen Ihrer Tags. Sie werden in den CSS-Dateien verschiedener Joomla Templates Überschneidungen finden, welche diesen Pool darstellen. Ich hätte es befürwortet, wenn man sich hier, besonders in Richtung Semantik, auf einen wirklch festen Bestand an CSS-Auszeichnungen festgelegt hätte. Damit wäre beim Styling des HTML Codes immer klar, welche Elemente der Seite, welche Klassen bekommen können. Auch könnten Komponentenentwickler damit sicherstellen, dass die Ausgaben ihrer Komponente bereits vom Template selbst gestylt werden. Stattdessen binden viele Komponenten weitere, eigene CSS-Dateien ein, um ihre Ausgabe zu stylen. Joomla 1.6 geht diesen Weg glücklicherweise etwas konsequenter.

Um den Artikeltitel von oben passend zu stylen können wir folgendes machen:

<h1 class="componentheading"><?php echo $this->escape($this->params->get('page_title')); ?></h1>

Damit haben wir dem Titel die Klasse componentheading verpasst. Diese Klasse ist in fast jedem Joomla Template definiert und muss somit nicht neu beschrieben werden.

Wenn Sie das Erstellungsdatum des Artikels ausgeben machen Sie folgendes:

<span class="createdate">
        <?php echo JHTML::_('date', $this->article->created, JText::_('DATE_FORMAT_LC2')); ?>
</span>

Hier kümmert sich die meistens definierte createdate Klasse um das passende Styling. Sie sollten also, besonders wenn Sie Overrides für Joomla eigene Komponenten erstellen, immer CSS-Klassen nutzen, welche bereits im Joomla Template definiert wurden.

Hier ein Auszug einiger in den meisten Joomla Templates eingesetzten CSS-Klassen:


.buttonheading, .button, .inputbox, small, .small, .smalldark, .mosimage_caption, .createby, .createdate, .modifydate, .readon, .img_caption, .article_separator, .article_column, .column_separator, .sectiontableentry0, .sectiontableentry1, .sectiontableentry2, .contenttoc, .pagenavbar, .pagination, .moduletable, ...

Diese und weitere Klassen werden zum Stylen von Buttons, Tabellen, Artikeln, Links, Navigationen usw. eingesetzt. Natürlich müssen sie sinnvoll innerhalb der CSS-Struktur genutzt werden. Wenn Sie also die Seitennavigation der Blogansicht stylen wollen schreiben sie z. B. ul.pagination li.

Overrides leichtgemacht

Niemand erstellt Overrides für Standardkomponenten von der Pike auf neu. Der einfachste Weg ein Override zu erstellen ist, die Overrides eines anderen Templates einfach in das eigene Templateverzeichnis zu kopieren und wo nötig anzupassen. Joomla bringt die drei Templates Purity, Beez und Milkyway mit sich. Milkyway nutzt leider keine Overrides, hier ist also nichts zu holen. Purity und Beez haben beide Overrides für die Artikelkomponente. Beez enthällt auch Overrides für die Kontakt-, User-, Newsfeeds-, Umfragen-, Such- und Weblinks Komponente. Die Jungs von Yootheme bieten Ihr Override Paket ebenfalls zum Download an.

Overrides für Module

Sie werden feststellen, dass es in den html Override Verzeichnissen der Templates nicht nur Overrides für Komponenten, sondern auch für Module gibt. Damit kann analog zur Ausgabe von Komponenten auch die Ausgabe von Modulen beeinflusst werden.

Sie werden sich fragen, wozu wir ein Override für Module erstellen sollten, wenn wir im vorigen Teil des Tutorials bereits ein eigenes Module Chrome erstellt haben. Die Antwort lautet Module Chromes steuern das HTML-Konstrukt mit dem Module generiert werden können. Modul Overrides dagegen beeinflussen den Inhalt der Module und werden individuell für jedes Modul erstellt.

Nehmen wir als Beispiel das klassische "Latest News" Modul. Dieses teasert eine bestimmte Anzahl an Artikeln einer bestimmten Kategorie an. Das Joomla eigene Template hierfür sieht wie folgt aus:

<?php // no direct access
defined('_JEXEC') or die('Restricted access'); ?>
<ul class="latestnews<?php echo $params->get('moduleclass_sfx'); ?>">
<?php foreach ($list as $item) :  ?>
    <li class="latestnews<?php echo $params->get('moduleclass_sfx'); ?>">
        <a href="<?php echo $item->link; ?>" class="latestnews<?php echo $params->get('moduleclass_sfx'); ?>">
            <?php echo $item->text; ?></a>
  </li>
<?php endforeach; ?>
</ul>

In einer Listendarstellung werden die Artikeltitel untereinander dargestellt. Viel gibt es hierzu nicht zu sagen. Was kann ein Override hier verbessern?
Nun das Override des Beez Templates z.B. sieht wie folgt aus:

<?php // no direct access
defined('_JEXEC') or die('Restricted access');?>
<?php if (count($list)) : ?>
<ul class="latestnews<?php echo $params->get('pageclass_sfx'); ?>">
    <?php foreach ($list as $item) : ?>
    <li class="latestnews<?php echo $params->get('pageclass_sfx');?>">
        <a href="<?php echo $item->link; ?>" class="latestnews<?php echo $params->get('pageclass_sfx'); ?>">
            <?php echo $item->text; ?></a>
   </li>
    <?php endforeach; ?>
</ul>
<?php
endif; 

Der einzige Unterschied ist, das hier überprüft wird, ob es überhaupt auszugebende Artikel gibt. Denn falls nicht, wird auch nicht die Liste mit dem ul-Tag ausgegeben. Das ist sinnvoll, um nicht eine leere Liste in seiner Webseite stehen zu haben.

Um das Override etwas individuell auszubauen, könnten wir das Bedürfniss haben die Anzahl der vorhandenen News über der Liste auszugeben. Nichts leicher als das:

<?php // no direct access
defined('_JEXEC') or die('Restricted access');
?>
<?php if (count($list)) : ?>
<ul class="latestnews<?php echo $params->get('pageclass_sfx'); ?>">
    <h4><?php echo count($list); ?> News</h4>
    <?php foreach ($list as $item) : ?>
    <li class="latestnews<?php echo $params->get('pageclass_sfx'); ?>">    
        <a  href="<?php echo $item->link; ?>" class="latestnews<?php echo $params->get('pageclass_sfx'); ?>">
        <?php echo $item->text; ?></a>
    </li>
    <?php endforeach; ?>
</ul>
<?php endif;

Sie sehen, wie leicht es ist, sowohl Aussehen als auch die Ausgabe und sogar gewisse Funktionalitäten von Modulen Ihren Bedürfnissen anzupassen. Das Beste dabei ist, dass Sie durch die Nutzung von Overrides nicht den "Core hacken", also Joomla eigene Dateien verändern. Wenn Sie das tun, um Einfluss auf bestimmte Dinge zu haben, werden Ihre Anpassungen mit dem nächsten Joomla Update höchstwahrscheinlich verloren gehen. Ihre Overrides aber werden durch ein Update nicht beeinflusst und funktionieren weiter.

Bei manchen Kundenprojekten haben wir mit Hilfe von Overrides im Komponentenbereich umfangreiche Aufgabenstellungen gelöst. In Overrides können Sie auf die Datenbank zugreifen und das gesamte Joomla Framework nutzen. Sie können also beliebig Funktionalitäten erweitern oder verändern (ohne Joomla anfassen zu müssen).

Im nächsten und vielleicht letztem Teil des Tutorials werden wir neben kleinen Optimierungen im Hintergrund eine schicke Suckerfish Dropdown Navigation und einen Contentslider für den Header einbauen.

Flows-Template mit Overrides:
Ansehen: Flows Template Step 10
Download: Flows Template Step 10

feed16 Kommentare
Maik
Mai 11, 2010
Stimmen: +2

Wie immer ;-) tolle Tipps und Einsichten in die wirklich wichtigen Dinge.

Bei der Thematik Overrides kommt mir immer wieder der gleiche Gedanke:
Warum wurde dieses Feature nicht dahingehend erweitert, dass man mehrere Varianten eines Overrides nutzen kann?!? Alles beschwert sich ständig über die wenigen Anzeige Optionen: Artikel, Blog, Liste. Wäre es nicht "relativ" simpel, nicht nur nach dem erste, verfügbaren Override zu suchen, sondern z.B. dem MenuItem genau zu sagen welchen Override es nutzen soll? Ich könnte mir einen Parameter/Select im Menu-Manager vorstellen, oder sogar bei den Parametern des entsprechen Artikel/Kategorie oder Bereiches...

Nicht falsch verstehen: Es ist schön, dass es überhaupt die Möglichkeit gibt, aber ist das nicht etwas "halbherzig" und kurzsichtig gelöst?

Was meinst du dazu Tom?

report abuse
vote down
vote up
Tom
Mai 11, 2010
Stimmen: +1

Hallo Maik,
Sie müssen bedenken, dass z.B. in einem Category View auch das Category Model genutzt wird. Dieses liefert genau die Daten, welche der View braucht. Ein Override in diesem View, welcher andere bzw. nicht angelieferte Daten darstellt, macht wenig Sinn.

Ich finde den Ansatz der Overrides auf Basis des MVC eigentlich recht gut. Mit J1.6 werde die Overrides etwas weichen, da J1.6 besseres HTML liefert.

Nach meinem letzten Kentnissstand kann man bei J1.6 einem Menüpunkt den ein Template Style zuweisen, analog zu den Menüzuweisungen aus J1.5.

report abuse
vote down
vote up
Maik
Mai 11, 2010
Stimmen: +1

Hallo Tom,
zugegeben... ich habe in diesem Bereich nur ein gefährliches Halbwissen. Ich meinte auch keine Anreicherung mit anderen Daten... im Grunde wird doch das momentane Feature für HTML-Optimierungen oder Layout Änderungen genutzt.
Nur, was nutzt mir das ganz "Overriden", wenn ich am Ende wieder nur eine einzige Variante für einen Artikel/ein Blog/eine Liste habe. Sinnvoll wäre doch ein Layout für die Blog-Ansicht von Kategorie "A"... und eine andere Blog-Ansicht für Kategorie "B"... usw. Das gleiche gilt für die Artikel. Schließlich haben wir in Joomla keine variablen Inhaltstypen, die die Angelegenheit noch verkomplizieren.

Vergleich: K2
Letztendlich ist es com_content sehr ähnlich und trotzdem kann man dort verschiedene "layouts", sprich overrides zuordnen.

report abuse
vote down
vote up
Sago
Mai 11, 2010
Stimmen: +1

Super Tutorial, ich werde wahrscheinlich Wochen brauchen um das richtig umzusetzen :-).

Kleine Anmerkung: Im Downloadarchiv von Step 10 fehlt das"template_thumbnail.png".

Gruß S.

report abuse
vote down
vote up
Tom
Mai 12, 2010
Stimmen: +0

@maik
Natürlich sind CCK Lösungen wie ZOO (meinetwegen auch K2) flexibler als die Joomla Standard Artikelverwaltung. Dafür wurden sie schließlich entwickelt. Allerdings sollte es mit Teil 5 des Tutorials ein leichtes sein Overrides Kategorien-, Navigationspunkt-, Bereichs- oder auch User- bzw- Usergruppenbasiert auszuwählen. Man muss nur den entsprechenden Wert ermitteln und dann ein passendes Subtemplate laden. Ziemlich simpel eigentlich.

@Sago
Danke für den Hinweis. Ich habe das Thumbnail nun in das Archiv gelegt.

report abuse
vote down
vote up
Maik
Mai 12, 2010
Stimmen: +0

@Tom
"...Wert ermitteln und SubTemplate..."
hört sich sehr interessant an, da hört meine Kompetenz allerdings auf ;-) Kannst du das Thema evt. in einem Teil 6 behandeln!?!?

report abuse
vote down
vote up
Tom
Mai 12, 2010
Stimmen: +0

@Maik
Das würde für dieses Tutorial zu weit vom Thema abweichen denke ich. Allerdings sollte es wirklich nicht schwer sein das selbst zu bewerstelligen. Als einfaches Beispiel ein Nutzergruppen bezogenes Override:

$user =& JFactory::getUser();
echo $this->loadTemplate('usergroup_'.$user->gid);
?>

So einfach geht das weiter...

report abuse
vote down
vote up
Maik
Mai 13, 2010
Stimmen: +1

@Tom
Kein Problem! Deine anderen Ausführungen sind schon "ihr Geld" Wert. Herzlichen Dank nochmal für die ganze Serie. Wenn nur alle Tutorials deine Sprache hätten, dann wäre es nicht so einschläfernd. ;-)

Meine letzte Frage!
Wie würde man z.B. auf die Kategorie oder ein MenuItem kommen? Sind diese Infos auch in Parametern abgreifbar... nur in der URL?... oder funktioniert es wie im Code eines Moduls?

report abuse
vote down
vote up
Tom
Mai 13, 2010
Stimmen: +1

@Maik
Sorry, aber dafür wurden Kommentare leider nicht geschaffen. Vielleicht in einem anderen Tut.

report abuse
vote down
vote up
Lars
August 11, 2010
Stimmen: +0

Hallo!
Verfolge mit Begeisterung auch schon die bisherigen Teile des Tutorials. Ist denn schon absehbar, wann der nächste Teil veröffentlicht wird?

Danke und Gruß

report abuse
vote down
vote up
Tom
August 11, 2010
Stimmen: +0

Hallo Lars,
freut mich zu hören. Wir sind momentan leider sehr mit Kunden- und eigenen Projekten beschäftig. Dort kommt übrigens auch die Flows Basis zum einsatz. Siehe www.prime-real.de oder demo.prime-real.de.
Mit dem letzten Teil des Tutorials muss natürlich auch Flows produktiv einsetzbar sein, was noch ein wenig Arbeit macht.
Ich hoffe, dass ich den letzte Teil sehr bald fertig habe.

report abuse
vote down
vote up
Dan
September 02, 2010
Stimmen: +0

Uff, sehr gut beschrieben, für mich sind aber die fehlenden Informationen nicht so gut nachvollziehbar. Bin noch Anfänger, habe deshalb nur ein kleines Wissen auf dem Gebiet von Html und CSS - PHP leider gar keines. Vielleicht habe ich ja irgendwann einmal Zeit das Ganze etwas besser zu verstehen…

Ich merke aber, dass hier auch einiges in Sachen Sicherheit vermittelt wird. Dieser Punkt ist in so manch anderem Tut noch nicht einmal ansatzweise zu finden…
Im großen und ganzen sieht das Ergebnis bisher sehr solide aus.
Der Text ist auch sehr locker und informativ geschrieben. Menschen mit einer gewissen Vorkenntnis haben sicher ihre reinste Freunde.
Ich werde das ganze weiter beobachten und meine Kenntnisse, wenn es die Zeit zulässt, stätig erweitern.

report abuse
vote down
vote up
Ralf
Oktober 30, 2010
Stimmen: +0

Vielen Dank für das tolle Tutorial. Sehr gut beschrieben und nachvollziehbar. Wann geht es denn weiter?

report abuse
vote down
vote up
Andreas
November 27, 2010
Stimmen: +3

Also ich muss das Thema von Maik leider nochmal aufgreifen. Ich bin nämlich der selben Meinung.

Es wäre super praktisch, wenn ich verschiedenen Kategorien verschiedene Darstellungsmethoden geben könnte. Dies ist aber meines Wissens nicht so einfach möglich, oder irre ich mich da? Auf die Schnelle kommt mir da nur der Gedanke, die URL abzufragen, und im content-override darauf zu reagieren...

report abuse
vote down
vote up
Rolf
Februar 25, 2011
Stimmen: +0

Prima - Jetzt noch die Mehrfachdeklaration der

vermeiden um validen Code zu erhalten-

report abuse
vote down
vote up
Silas
Januar 09, 2012
Stimmen: +0

Hey echt gut gemacht, habe kein anderes so gut beschriebenes Tut gefunden! Gibt es noch einen Teil 6 oder bin ich einfach zu blöd den zu finden?

LG Silas

report abuse
vote down
vote up

Kommentar schreiben
 
  kleiner | groesser
 

security image
Bitte den folgenden Code eintragen


busy
 

B01 realisiert zeitgenössische Online-Kommunikationsmittel.
Wir sind spezialisiert auf OSCMS und unterstützen unsere Kunden vom Konzept bis zum Launch mit Erfahrung und exklusiven Komponenten zur Umsetzung von Communitys, Shops, Portalen und Webseiten.

B01 Kunden

Unsere Ideen, unsere Produkte, unsere Kunden.

B01 empfiehlt:

ZOO Content Construktion Kit

ZOO CCK

Virtuemart Shopsystem

E-Commerce

Joomla SEO

SEO

Joomla Content Editor

Content Editor

Joomla Social Networking

JomSocial