Joomla Modul mit SQL-Formfield

Da ich keinen vorgefertigten Formularfeldtyp gefunden habe, der mir die Tags (Schlagwörter) ausgibt, hab ichs mal über den Typ SQL form field type probiert, mal sehen wie weit wir damit kommen. Aber erst noch mal ein paar Gedanken zu den Anforderungen:

Ich schraubs mal ein bisschen runter

Im vorigen Artikel hatte ich ja für den Anwender die Möglichkeit geschaffen, eine bestimmte Beitragskategorie auszuwählen. Das hat ganz hübsch funktioniert, aber eigentlich ist es für meinen Zweck nicht ganz das Richtige. Ich brauche ja auch noch mein zweites Auswahlkriterium, nämlich die Tags=Schlagwörter. Kurze Erinnerung, was ausgegeben werden soll:

X Rezepte insgesamt

davon Y mit dem Tag Z

Ich habe aber in meinem Joomla-Kochbuch die Einschränkung gemacht, dass Tags nur für die Kategeorie Rezepte verwendet werden, in den anderen Kategorien (Kochbücher etc.) hab ich sie schlicht und ergreifend nicht eingesetzt. Das heisst aber, unsere Tagauswahl macht nur Sinn, wenn die Beitragskategorie 8 für Rezept ist, und dann kann ich es auch gleich fest verdrahten. Sonst dürfte ich die Tag-Auswahl nur anzeigen, wenn der Anwender die Kategorie Rezepte gewählt hat, und das geht mir dann doch ein bisschen zu weit.

Der Formularfeldtyp SQL

Ist wahrscheinlich am leichtesten zu verstehen, wenn man es am konkreten Beispiel sieht. Die Felddefinition in meiner XML-Datei sieht so aus:

<field
            name="title"
            type="sql"
            default="10"
            label="Einen Tag auswählen"
            query="SELECT id AS value, title FROM #__tags where title not like 'ROOT'"
            />

Dabei ist der Alias „AS value“ wichtig, da über diesen der Rückgabewert des Feldes definiert wird. Den Select hab ich gleich ein bisschen angepasst, wir gehen in die tabelle #_tags und schliessen hier den Systemeintrag ROOT aus, weil der in der Auswahlliste gar nicht auftauchen darf.

Zum Aufbau der Query zitiere ich mal die Joomla-Doku:

  • query (mandatory if not using the sql_* attributes) is the SQL query which will provide the data for the drop-down list. The query must return two columns; one called ‚value‘ (unless overridden by the key_field attribute) which will hold the values of the list items; the other called the same as the value of the name attribute (unless overridden by the value_field attribute) containing the text to be shown in the drop-down list.

Also, mal ganz langsam.

  • die query liefert die Daten für unser Dropdown-Feld
  • die query muss zwei Spalten zurückgeben
  • die erste Spalte der Rückgabe muss value heissen, das passiert hier mit dem Alias, und liefert die Rückgabewerte für das Formularfeld (in unserem Fall die numerische ID des Tags)
  • die zweite Spalte muss genauso heissen wie das Feld in der XML-Datei, ich bin hier bei title geblieben. Die zweite Spalte liefert die Einträge für das Dropdown-Feld.

Alles klar? Jedenfalls funktionierts, und mein Dropdownfeld sieht schon mal ganz gut aus:

dropdown_tags

dropdown_tags

Den Wert, den der Benutzer ausgewählt hat, holen wir uns in der mod_helloworld.php wie gehabt über den Namen des Feldes:

$titel = $params->get('title');

Wir erweitern unser Standardobjekt für die Parameterübergabe an die Helper-Klasse entsprechend:

$data = new stdClass();
//Objekt füllen
$data->kat = $kat;
$data->variable = $variable;
$data->titel = $titel;

Und können jetzt in der helper.php damit weiterarbeiten, da haben wir jetzt die numerische ID des gewählten Tags auf der Variablen $params->titel.

Jetzt müssen wir nur noch zählen, wieviele Rezepte dem gewählten Tag zugeordnet sind, und dafür brauchen wir die Tabelle #__content_item_tag_map, da schauen wir einfach nach, wie oft die aktuelle Tag-ID auftaucht.

//Anzahl der Tags zur TagID holen
        $db = JFactory::getDbo();
        $db->setQuery("SELECT * FROM #__contentitem_tag_map WHERE tag_id = ".$params->titel.""); 
        $db->execute();
        $my_count = $db->getNumRows();
        echo $my_count;

Schlußendlich fehlt uns noch der Name des Tags für die Ausgabe, den holen wir uns mit der ID aus der Tabelle #__tags:

//Name des Tags zur Tag-ID holen
        $db = JFactory::getDBO();
        $db->setQuery("SELECT title FROM #__tags WHERE id=".$params->titel);
        $db->execute();
        $tagName = $db->loadResult();

Das wars, fehlt nur noch die Ausgabe:

echo $my_count." davon zum Thema ".$tagName;

 Bingo, das hat hingehauen! Meine Ausgabe sieht so aus:

tag_kat_ausgabe

tag_kat_ausgabe

Passt einwandfrei. Man könnte es jetzt noch perfektionieren und einen Join auf die #__content über die Kategorie-ID einbauen, damit man nur die Tags angezeigt bekommt, die auch zu Rezepten zugeordnet sind, aber ich wills mal nicht übertreiben. Die Vorgabe war ja, dass Tags nur in der Kategorie Rezepte verwendet werden, das muss reichen.

Fazit

Ich finde, die Formularfelddefinition ist über die XML-Datei übersichtlich und komfortabel gelöst, und die vordefinierten Formularfeldtypen nehmen einem in vielen Fällen einen Haufen Arbeit ab. Das macht es wieder wett, dass die Modulerstellung am Anfang ein bisschen schwer zu durchblicken ist, aber wenn man einmal ein Basic Modul geschrieben hat, geht auch das leicht von der Hand. Modulbasteln in Joomla macht Spaß!

Joomla-Modul ein bisschen aufgebohrt – mit Benutzereingaben

Ich hab ja in diesem Artikel ein WordPress-Widget erstellt, das die Gesamtzahl der veröffentlichten Rezepte sowie die Anzahl der Rezepte einer frei wählbaren Kategorie anzeigt. So nach dem Muster:

312 Rezepte insgesamt

46 davon Vegetarisch

Ob das mit unserem Joomla-Modul auch hinzukriegen ist?

Anzahl der Beiträge der Kategorie Rezepte

Meine Rezeptkategorie hat die ID 8, das kann man in der Tabelle #__categories nachschauen. Dazu hab ich folgendes Code Snippet gefunden:

$model = JModelLegacy::getInstance('Articles', 'ContentModel');
        $model->setState('filter.category_id', 8); // Set category ID here
        $articles = $model->getItems();

        $num_articles = count($articles); // Returns the number of articles in category

Kommt mir ein bisschen arg umständlich vor, aber wenns funktioniert…

Ich möchte jetzt aber natürlich auswählen können, zu welcher Kategorie die Gesamtzahl der Beiträge ausgegeben werden soll, weil ich in Joomla so schöne Möglichkeiten habe, über die Kategorisierung meine Ausgabe auf der Webseite zu strukturieren. Das heißt aber, wir brauchen ein Eingabefeld (Dropdown), in dem der Benutzer anwählen kann, welche Kategorie ausgegeben werden soll.

Eingabefelder für eigene Module in Joomla

Sind nicht arg schwer zu realisieren, die Joomla-Doku zu dem Thema ist schon mal recht gut, schaut mal hier rein:

https://docs.joomla.org/J3.x:Creating_a_simple_module/Adding_Form_Fields

Ich machs aber hier nochmal step by step, damit man es auch nachvollziehen kann. Wir setzen auf unser Hallo-Welt Modul aus dem vorigen Beitrag auf und erweitern die mod_helloworld.xml, in der kann man ein einfaches Texteingabefeld so erstellen:

 <config>
    <fields name="params">
        <fieldset name="basic">
            <field name="param1" type="text" default="" label="Bitte Titel eingeben" description=""></field>
           </fieldset>
    </fields>
    </config>

Die Felddefinition muss innerhalb der config-Tags stehen. Wenn man sich jetzt mal das Modul aschaut, müsste das Feld eigentlich schon da sein:

texteingabefeld

texteingabefeld

Wie kommt man jetzt an den Inhalt des Feldes ran, den unser Benutzer eiingegeben hat? Das passiert in der mod_helloworld.php, und zwar so:

$variable = $params->get('param1');

Die $variable kann man jetzt an die helper-Klasse übergeben:

$hello = modHelloWorldHelper::getHello($variable);

Und da kann man dann damit weiterarbeiten. Bevor ich da noch weiter darauf eingehe, erstmal:

Die Anforderungen

Den Titel des Moduls kann der Anwender beim Erstellen unter Erweiterungen->Module->neu->Mein Hallo-Welt Modul selber eingeben, den fragen wir nicht nochmal extra ab. Dafür brauchen wir aber ein Dropdown-Feld, in dem die Kategorie (z.B. „Rezepte“) ausgewählt werden kann, für die die Gesamtzahl der Beiträge ausgegeben soll. Und wir brauchen noch ein zweites Dropdownfeld für das „featured tag“ (z.B. „Vegetarisch“, aber dazu kommen wir später. Jetzt werfen wir erstmal einen Blick auf:

Die vordefinierten Form Field Types

Da bietet Joomla etwas wirklich praktisches an, es gibt eine ganz Latte von vordefinierten Formularfeldern, hier die Doku dazu: https://docs.joomla.org/Standard_form_field_types

Da klemmen wir uns gleich mal den Formularfeldtyp „Kategorie„, der macht nämlich genau das was wir brauchen. In der XML-Datei sieht das so aus:

<field name="mycategory" type="category" extension="com_content" label="Eine Kategorie auswählen" description="" />

In der mod_helloworld.php holen wir uns den Inhalt mit:

$kat = $params->get('mycategory');

Und im Modul-Backend kriegen wir unsere Dropdown-Liste mit den Kategorien:

dropdown_kategorien

dropdown_kategorien

In der übergebenen Variablen steckt übrigens die numerische ID der Kategorie Rezepte, die können wir gleich direkt weiterverwerten, und zwar in der helper.php:

public static function getHello($params)
    {
        $model = JModelLegacy::getInstance('Articles', 'ContentModel');
        $model->setState('filter.category_id', $params); // Set category ID here
        $articles = $model->getItems();

        $num_articles = count($articles); // Returns the number of articles in category
        
        echo "Insgesamt ".$num_articles." Rezepte<br>";    
        
        
        
    }

Voraussetzung dafür ist natürlich, dass wir sie in der mod_helloworld.php auch als Parameter an die Helper-Klasse übergeben haben, aber dazu gleich mehr, zuerst schauen wir uns mal die Ausgabe an:

insgesamt_rezepte

insgesamt_rezepte

Das paßt soweit, jetzt müssen wir nur noch den Ausgabetext dynamisch anpassen, es kann ja auch jemand die Kategorie „Kochbücher“ angewählt haben, dann darf da nicht „Rezepte“ stehen. Das machen wir so:

//Name der Kategorie zur ID holen
        $db = JFactory::getDbo();
        $db->setQuery("SELECT cat.title FROM #__categories cat WHERE cat.id='".$params->kat."'"); 
        $category_title = $db->loadResult();
        
        echo "Insgesamt ".$num_articles." ".$category_title."<br>";

Nicht dran stören dass hier „.$params->kat.“ steht, das kommt daher, dass ich ein Array von Parametern übergeben habe, mehr dazu gleich. Jedenfalls wird jetzt auch der richtige Kategoriename angezeigt:

2kochbuecher

2kochbuecher

Mehr als ein Formularfeld, mehrere Parameter zum Übergeben

Wir brauchen aber noch ein zweites Formularfeld für die Tags, und dazu werfen wir einen kurzen Blick darauf, wie wir mehr als eine Variable an die Helper-Klasse übergeben können. Kurze Erinnerung, wie die zwei Felddefinitionen in der XML-Datei aussehen:

<fields name="params">
        <fieldset name="basic">
            <field name="param1" type="text" default="" label="Bitte Text eingeben" description=""></field>
            
                
            <field name="mycategory" type="category" extension="com_content" label="Eine Kategorie auswählen" description="" />
            
           </fieldset>
    </fields>

Die Inhalte der Felder holen wir uns in der mod_helloworld.php über die Feldnamen:

$kat = $params->get('mycategory');
$variable = $params->get('param1');

Dann packen wir sie in ein Standardobjekt und übergeben dieses an die Helper-Klasse:

$data = new stdClass();
//Objekt füllen
$data->kat = $kat;
$data->variable = $variable;

        
$hello = modHelloWorldHelper::getHello($data);

In der helper.php holen wir uns die übergebenen Variablen, die ja in unserem Objekt stecken, mit ihrem Namen, also z.B. $params->kat. Das $params stammt aus der Funktionsdefinition der public static function getHello($params)) wer da etwas anderes stehen hat, muss das entsprechend anpassen. Hier nochmal die komplette function:

public static function getHello($params)
    {
        //Anzahl der Artikel zur übergebenen Kategorie-ID holen
        $model = JModelLegacy::getInstance('Articles', 'ContentModel');
        $model->setState('filter.category_id', $params->kat); // Set category ID here
        $articles = $model->getItems();

        $num_articles = count($articles); // Returns the number of articles in category
        
        //Name der Kategorie zur ID holen
        $db = JFactory::getDbo();
        $db->setQuery("SELECT cat.title FROM #__categories cat WHERE cat.id='".$params->kat."'"); 
        $category_title = $db->loadResult();
            
        echo "Insgesamt ".$num_articles." ".$category_title."<br>";
        
        
    }

Das sieht jetzt schon ziemlich gut aus. Leider habe ich für die Tags keinen vordefinierten Formularfeldtyp gefunden, da müssen wir was basteln, aber dazu gibt es einen neuen Beitrag.

WordPress, Joomla und Drupal: Theme-Erstellung im Vergleich

Also, ich hab ja kürzlich das Anlegen eigener Templates/Themes in allen drei CMS ein bisschen angerissen und die Basics zusammengeschrieben. Da bietet es sich an ein Resumee zu ziehen, was ich hiermit versuche. Mein völlig subjektiver Winner ist:

Joomla – so einfach kann es sein

Sobald man den Zusammenhang der definierenden XML-Datei templateDetails.xml und den Modulpositionen in der index.php überrissen hat, kann man schon richtig loslegen. Kein Gewühle in unverständlichem PHP-Code, kein umständliches Einbinden externer Skripte. Dadurch, dass man in Joomla über die Kategorien und Module im Backend nahezu unendliche Konfigurationsmöglichkeiten hat, ist es gar nicht notwendig tiefer in die Template-Logik einzusteigen, man kann fast alles über die Administrationsoberfläche einstellen. Dabei kann man sich allerdings auch ganz schön verzetteln – eine gute Doku ist hier wirklich unabdingbar, sonst kann man nie nachvollziehen warum, wie und weshalb wer an welchen Schräubchen gedreht hat.

Was ein bisschen übersichtlicher sein könnte: die Modulzuordnung in der Admin-Oberfläche. Da fehlt eine Möglichkeit, sich nur die Modulpositionen eines bestimmten Templates anzeigen zu lassen (oder ich hab sie nicht gefunden). So wie es ist muss man sich bei der Modulpositionierung durch eine fusselige Liste aller Templates mit allen Modulpositionen durchscrollen, da sind Fehlklicks vorprogrammiert.

Das wird allerdings beinahe ausgeglichen durch die hervorragende Möglichkeit, sich die Modulpositionen auf der Webseite anzeigen zu lassen. Das geht, indem man im Browser an die URL den Parameter ?tp=1 anhängt, das sieht dann z. B. so aus: http://localhost/jsite/?tp=1, damit kriegt man einen anschaulichen Überblick, wo man auch gleich erkennt wenn am css noch was nicht stimmt.

joomla_tp

joomla_tp

Alles in allem ist die Erstellung eines eigenen Templates in Joomla ein recht vergnüglicher Prozess, das Positionieren der benötigten Module geht recht flott von der Hand und die Feineinstellungsmöglichkeiten über die Adminoberfläche sind sehr weitreichend, ohne dass man in den Templatecode eingreifen muss. Ich kann auch jedem die kurze und knackige Joomla-Dokumentation zum Thema ein einfaches Template erstellen empfehlen, damit geht echt ein Schnellstart!

Ein guter zweiter Platz: Drupal mit Views

Ohne Views geht nämlich nahezu gar nichts, wenn man seine Inhalte auch übersichtlich ausgeben möchte. A propos Inhalte: die selbstdefinierten Inhaltstypen sind eine der grossen Stärken von Drupal, wenn man die vernünftig nutzt spart man sich einen Haufen Template-Gefiddel. Ein eigenes Template anzulegen ist jetzt eigentlich auch nicht weiter schwierig, wenn man als Vorlage die generische page.tpl.php nutzt und keine Scheu davor hat, darin Elemente herumzuschubsen und umzugruppieren. Auch in Drupal kommt einem eine Vorschau der Template-Elemente zu Hilfe, unter Struktur->Blöcke->Blockregionen veranschaulichen kann man schnell überprüfen ob das Layout passt:

blockregionen

blockregionen

Da man alle Views auch als Blöcke definieren und ins Layout einpassen kann, ist man in der Ausgabe der gewünschten Daten nahezu unendlich flexibel, da bleibt so gut wie kein Wunsch offen. Besonders die Multiblog-Funktionalität über die unterschiedlichen Inhaltstypen und Taxonomien ist easy in der Realisierung und macht es einem leicht, die Seite sauber zu strukturieren.

Ich hätte mir höchstens eine einfachere Möglichkeit des Seitendesigns gewünscht als die page.tpl.php anzupassen, die ist doch ein bisschen unübersichtlich und tendiert zum div-Wildwuchs. Und noch etwas, was wirklich nervt: man kommt bei der Template-Entwicklung nicht darum herum, ständig den Cache zu leeren, weil man seine Änderungen sonst im Zweifelsfall erstmal nicht sieht. Das kostet Zeit und nervt, da wäre es wünschenswert, wenn man eine Möglichkeit hätte so etwas wie einen Entwicklermodus einzuschalten, in dem das Caching abgeschaltet werden kann.

Das gute alte WordPress auf Rang drei

Da merkt man halt schon, dass die Software etwas in die Jahre gekommen ist. Mit einem einfachen Seitenaufbau mit einem Kopfbereich, einer Inhaltszone mit ein paar statischen Seiten, einem Blog und einer Sidebar ist man recht schnell dabei, aber wenn man mehr will, gehts gleich ans Eingemachte. Entweder man arbeitet sich selber in die WordPress-API ein (und die ist eine Wissenschaft für sich) oder man verläßt sich auf die Funktionalitäten zusätzlicher Plugins. Von denen gibt es zwar unzählige für jeden Zweck und Geschmack, aber ich kauf nicht so gern die Katze im Sack, und die meisten Plugins sind grottenschlecht bis gar nicht dokumentiert. Da hat man leicht mal eins installiert, das einem die ganze Site lahmlegt oder unerklärliche Fehlfunktionen auslöst, und dann hat man das Gfrett herauszufinden wer denn jetzt wirklich der schwarze Peter war.

Auch eine komfortable Datenbank-Abfragemöglichkeit wie Drupals Views oder eine fein differenzierte Einstellmöglichkeit nahezu aller Parameter für die Anzeige wie in Joomla sucht man vergebens, man muss sich im Zweifelsfall selber in die vorhandenen Theme-Dateien einarbeiten und sie nach eigenem Bedarf anpassen, und eigene Plugins und Widgets entwickeln. Das war vor ein paar Jahren noch akzeptabel, jetzt aber laufen die beiden jüngeren CMS dem alten WordPress da um Längen den Rang ab.

Nur einen nicht so leicht zu schlagenden Vorteil hat WordPress: für kleinere, einfachere Webseiten ist es immer noch das Anwenderfreundlichste, am Leichtesten zu bedienende CMS auf dem Markt. Start Blogging – das ist kein leerer Werbespruch, das ist nach wie vor WordPress‘ grosse Stärke! Für den Einzelunternehmer, Handwerker, Arzt oder Anwalt, der seine Firma mit einer Visitenkarte im Web vorstellen möchte, ist WordPress nach wie vor die ideale Lösung. Auch für mittlere Benutzergruppen wie Vereine, kleinere Behörden und soziale Dienstleister ist es ideal, weil kostengünstig in der Realisierung und leicht zu pflegen. Der Markt für WordPress als „kleine“ Lösung für den Webauftritt ist riesengross und wird es aller Voraussicht nach noch lange bleiben.

Noch mehr Widget-Bastelei: ein eigenes Dropdown-Feld

Ich hab im vorigen Artikel etwas geschummelt und mir ein fertiges Konstrukt für das Dropdown-Feld mit den Kategorien ergooglet, das ging so:

<p>
    <label for="<?php echo $this->get_field_id( 'select' ); ?>">Kategorie auswählen:</label>
    <?php wp_dropdown_categories( array( 'show_option_none' =>' ','name' => $this->get_field_name( 'select' ), 'selected' => $select ) ); ?>
  </p>

Wer unbedingt genaueres dazu wissen möchte, kanns im Codex bei wp_dropdown_categories nachschauen, ich spar mir das, weil es der volle Overkill mit ungefähr 20 Parametern ist, und die Source-Beispiele auch nicht gerade zur Erhellung beitragen.

Dropdown-Felder in Widgets braucht man aber immer wieder, und ich stelle hier eine realtiv einfache Methode vor, wie man sie sich selbst zusammenbastelt.

Das Anwendungsbeispiel

Ich möchte im Widget ein Dropdown-Feld haben, in dem man einen Post Type wählen kann, die Optionen sollen Post, Page und Custom Type heissen. Dazu erweitern wir den Widget-Code aus dem vorigen Artikel um ein Feld namens „posttype“, ich markiere hier mal in rot wo man da überall eingreifen muss:

    function form($instance)
  {
    $instance = wp_parse_args( (array) $instance, array( 'title' => '' ) );
    $title = $instance['title'];
    
    $instance = wp_parse_args( (array) $instance, array( 'posttype' => '' ) );
    $select = $instance['posttype'];
?>
  <p><label for="<?php echo $this->get_field_id('title'); ?>">Titel: <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo attribute_escape($title); ?>" /></label></p>
  
   <--! HIER KOMMT DAS DROPDOWN HIN-->
   
       
<?php
  }
 function update($new_instance, $old_instance)
  {
    $instance = $old_instance;
    
    $instance['title'] = $new_instance['title'];
    $instance['posttype'] = $new_instance['posttype'];
    
    return $instance;
  }

Dann kommt in die function form() folgende Konstruktion für das Dropdown-Feld, ich markiere grün wo man da eigene Werte einträgt:

<p>Post Type auswählen
   <select id="<?php echo $this->get_field_id('posttype'); ?>" name="<?php echo $this->get_field_name('posttype'); ?>" class="widefat" style="width:100%;">
    <option <?php selected( $instance['posttype'], 'Post'); ?> value="Post">Post</option>
    <option <?php selected( $instance['posttype'], 'Page'); ?> value="Page">Page</option> 
    <option <?php selected( $instance['posttype'], 'Custom Type'); ?> value="Custom Type">Custom Type</option>   
    </select>
   </p>

Das erzeugt uns im Widget das Dropdown-Feld mit den drei möglichen Werten:

dropdown_drei_werte

dropdown_drei_werte

Für die Ausgabe modifizieren wir jetzt nur noch die function widget() ein bisschen:

 function widget($args, $instance)
  {
    extract($args, EXTR_SKIP);
 
    echo $before_widget;
    
    $title = $instance['title'];
    $posttype = $instance['posttype'];
     
    // WIDGET CODE KOMMT HIERHIN
    echo "<h3>".$title."</h3>";
    
    echo "Post Type= ".$posttype."<br>";
    
    echo $after_widget;
  }

Fertig! Ausgabe:

posttype_ausgabe

posttype_ausgabe

Nicht besonders spektakulär, aber ausbaufähig. Ich denke, das kann man immer wieder mal brauchen, wenn der User aus einer vorgegebenen Liste eine Auswahl treffen soll.

Kleine Ergänzung: ein numerisches Feld geht auch

Das geht ganz einfach, indem man den type des Textinput-Felds auf number stellt, der Rest bleibt wie vorher:

<p><label for="<?php echo $this->get_field_id('anzahl'); ?>">Anzahl: <input id="<?php echo $this->get_field_id('anzahl'); ?>" 
name="<?php echo $this->get_field_name('anzahl'); ?>" type="number" value="<?php echo attribute_escape($anzahl); ?>" /></label></p>

Schon klappts:

numerisch

numerisch

 

Widget-Basteln macht Spaß: ein Widget mit Benutzereingaben

Das, so gebe ich ehrlich zu, ist zusammengeklaut und abgekupfert und herausgegooglet. Da aber das Widgetbasteln in WordPress erstens Spaß macht und zweitens vielfältige Einsatzmöglichkeiten bietet, beschreibe ich hier doch mal recht ausführlich meinen Weg zum eigenen Widget mit Benutzereingaben. Das Meiste hab ich aus dieser Anleitung hier bei makuseof.com gelernt, da wird einem das funktionale Gerippe eines WordPress-Widgets vorgelegt. Ebenfalls sehr aufschlussreich ist diese Anleitung hier bei wpmudev.

Die Vorgabe: ein Featured Category Widget

Ich hab mir eine relativ einfach Aufgabe gestellt. Mein Widget soll ausgeben, wieviele Rezepte bisher veröffentlich wurden, und dann soll man noch eine Featured Category anwählen können, für die dann ebenfalls die Anzahl der Rezepte ausgegeben wird, also so in der Art:

Rezepte insgesamt 317

56 davon Vegetarisch

Dann hätte ich noch gern einen frei wählbaren Titel für das Widget. Das hört sich simpel an, war aber in der Realisieung nicht ohne, nicht zuletzt weil der Codex zu den Widget-Funktionalitäten sehr lückenhaft und umständlich ist. Aber wir fangen mal ganz vorne an, und sehen wie weit wir kommen.

Anlegen der Widget-Datei

Man erzeugt im Plugins-Verzeichnis seiner WordPress-Installation ein neues php-File mit dem Namen des Widgets, z. B. mein-tolles-widget.php. Die kriegt jetzt erstmal den klassischen Plugin-Header:

/*
Plugin Name: Top Category Widget
Plugin URI: http://evileu.de/wordpress
Description: Gibt die Gesamtzahl der veröffentlichten Rezepte und die Anzahl der Beiträge einer frei wählbaren Kategorie an
Author: Evi Leu
Version: 1.0
Author URI: http://evileu.de
*/

Dann passiert Folgendes:

class FeaturedCategoryWidget extends WP_Widget
{
  function FeaturedCategoryWidget()
  {
    $widget_ops = array('classname' => 'FeaturedCategoryWidget', 'description' => 'Zeigt die Anzahl der Rezepte einer frei wählbaren Kategorie an' );
    $this->WP_Widget('FeaturedCategoryWidget', 'Featured Kategorie', $widget_ops);
  }

Eine neue Instanz der Klasse WP_Widget wird angelegt und mit unseren eigenen Benennungen versehen, ich hab die mal fett und rot markiert. Dann kommt noch etliches andere, was später erklärt wird, und am Ende der Datei wird noch per add_action das Widget aktiviert:

add_action( 'widgets_init', create_function('', 'return register_widget("FeaturedCategoryWidget");') );?>

Das reicht aus, damit das Testwidget in den zur Verfügung stehenden Plugins angezeigt wird und aktiviert werden kann. Macht aber noch keinen Sinn, es tut ja noch nichts.

Das Formular für die Benutzereingaben

Dafür brauchts eine Funktion namens form($instance), die sieht so aus, meine Ergänzungen in rot:

 function form($instance)
  {
    $instance = wp_parse_args( (array) $instance, array( 'title' => '' ) );
    $title = $instance['title'];
    
    $instance = wp_parse_args( (array) $instance, array( 'select' => '' ) );
    $select = $instance['select'];
    
    
?>
  <p><label for="<?php echo $this->get_field_id('title'); ?>">Titel: <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo attribute_escape($title); ?>" /></label></p>
  
   <p>
    <label for="<?php echo $this->get_field_id( 'select' ); ?>"><?php _e( 'Select category', 'textdomain' ); ?>:</label>
    <?php wp_dropdown_categories( array( 'show_option_none' =>' ','name' => $this->get_field_name( 'select' ), 'selected' => $select ) ); ?>
  </p>

Damit werden zwei Felder für die Benutzereingaben angelegt. Das erste für den Titel hab ich aus dem Beispiel von makuseof.com übernommen. Das zweite Feld für das Auswahlfeld hab ich mir zusammengegooglet, das stellt eine Dropdown-Liste aller Kategorien zur Verfügung und belegt die Variable $select mit der ID (numerisch) der gewählten Kategorie.

Jetzt kommt noch eine Funktion, die uns die vorher gewählten Werte aus dem Formular zur Verfügung stellt, auch die hab ich einfach übernommen:

function update($new_instance, $old_instance)
  {
    $instance = $old_instance;
    $instance['title'] = $new_instance['title'];
    $instance['select'] = $new_instance['select'];
    return $instance;
  }

Und jetzt kommt endlich die tatsächliche Funktionalität des Widgets. Da werden zuerst noch die beiden Variablen $title und $select gesäubert, aber dann kanns losgehen

function widget($args, $instance)
  {
    extract($args, EXTR_SKIP);
 
    echo $before_widget;
    
    $title = empty($instance['title']) ? ' ' : apply_filters('widget_title', $instance['title']);
    $select    = empty( $instance['select'] ) ? '' : esc_attr( $instance['select'] );
    
   
    // WIDGET CODE KOMMT HIER
    
    
    echo $after_widget;
  }

Der tatsächliche OpCode des Widgets ist sehr straightforward:

echo "<h3>".$title."</h3>";
    echo "Rezepte insgesamt: ".wp_count_posts()->publish."<br>";
    
    global $wpdb;
    $alleposts = $wpdb->get_results( "SELECT * from ".$wpdb->prefix."term_taxonomy where term_id = ".$select."");
    
    foreach($alleposts as $einpost){
        
        echo $einpost->count;
    }
    
    echo " davon ".get_the_category_by_ID($select);

Ich geb erstmal den vom Benutzer eingegebenen Titel als h3 aus, danach die Gesamtzahl der veröffentlichten Posts=Rezepte. Dann kommt eine kleine Datenbankabfrage, ich hol mir aus der wp_term_taxonomy die Anzahl der zur aktuellen Kategorie (ID liegt auf der Variablen $select) vorhandenen Beiträge, die steht da nämlich praktischerweise drin, da muss man nicht lang rummachen. Das wars! Unser Widget hat jetzt ein Eingabefeld für den Titel und eine Dropdownliste zur Auswahl der Kategorie:

widget_mit_dropdown

widget_mit_dropdown

Der Output ist unspektakulär, aber es funktioniert wie geplant:

widget_output

widget_output

Kurzer Blick auf die Datenbank

Wer übrigens wissen möchte, wo die Benutzereingaben gespeichert werden, das ist ein bisschen frustelig. Die werden nämlich serialized abgespeichert, in der wp_options. Sucht da nach einem Eintrag mit dem Namen widget_[name eures widgets]. Im Feld option_value steht dann sowas:

a:2:{i:2;a:2:{s:5:“title“;s:12:“Alle Rezepte“;s:6:“select“;s:2:“29″;}s:12:“_multiwidget“;i:1;}

Der gesamte Code als ZIP

Weil die Schachtelung doch ein wenig kompliziert ist, kommt hier noch der gesamte Code des Widgets als ZIP-Archiv: category-widget

Ein eigenes WordPress-Theme 2: Widget-fähige zweite Sidebar einbinden

Also, das war jetzt einfacher als ich dachte, deswegen kommts hier heute noch rein. Ich hatte ja in meinem dreispaltigen Template ursprünglich eine statische linke Seitenleiste definiert, und mit einer eigenen kleinen Funktion zur Anzeige der 10 neuesten Rezepte gefüllt, das sah in der index.php so aus:

<div id = "sidebar-left">
    
    <h2>Die neuesten Rezepte</h2>
        <ul>
            <?php $liste = wp_get_recent_posts();
            
            foreach($liste as $item){
                echo '<li><a href="' . get_permalink($item["ID"]) . '">' . $item["post_title"].'</a> </li>';
            }    
            ?>
        </ul> 
 
  </div> <!-- sidebar-left-->

Natürlich gibts aber das Widget „Neueste Beiträge“ schon, und das wollen wir auch nutzen, indem wir die linke Sidebar widgetfähig machen.

Eine neue Datei für die linke Sidebar anlegen

Die heißt sidebar-links.php (oder sidebar-xy.php) und enthält folgenden Code:

<div id="sidebar" class="widget-area">
<?php dynamic_sidebar( 'sidebar-2' ); ?>

</div><!-- #sidebar .widget-area -->

Damit WordPress nun auch eine dynamische Sidebar namens sidebar-2 kennt, kommt folgender Eintrag in die functions.php, dabei passt man den name, die id und die description an:

register_sidebar( array (
        'name' => __( 'Linke Sidebar'),
        'id' => 'sidebar-2',
        'description' => __( 'Widgets in der linken Sidebar anordnen.'),
        'before_widget' => '<aside id="%1$s" class="widget %2$s">',
        'after_widget' => "</aside>",
        'before_title' => '<h3 class="widget-title">',
        'after_title' => '</h3>',
    ) );

In der index.php ersetzt man nun den gesamten Code der statischen Sidebar durch den Aufruf:

<div id = "sidebar-left">
    
    <?php get_sidebar('links'); ?>
 
  </div> <!-- sidebar-left-->

Tückisch ist hier das kleine Wörtchen „links“, das muss genauso heissen wie man es oben im Namen der sidebar-links.php (oder sidebar-xy.php) definiert hat.

Das wars aber auch schon, unsere linke Sidebar taucht jetzt in der Widget-Verwaltung auf und kann bestückt werden:

widgets_linke_sidebar

widgets_linke_sidebar

Ein eigenes Widget erstellen: kurz und knackig

Ich habe hier bei blog.unkonsorten.com die ultimative Kurzanleitung zum Erstellen eines eigenen Widgets gefunden, die möchte ich euch nicht vorenthalten( Beim Code kopieren auf die „“ und “ aufpassen, die muss man korrigieren).

Damit es etwas Interessanteres ausgibt als „Hallo Welt“ habe ich mal die Anzahl der veröffentlichten Rezepte eingebaut, die kriegt man so :

function widget_sidebar() {
// Hier kann man eigenen Code einfuegen
echo "<h3>Rezepte insgesamt: ".wp_count_posts()->publish."</h3>";
}

Das wars auch schon – Have fun with Widgets!

Sag niemals nie: ein einfaches WordPress-Theme erstellen

Ich hab ja am Anfang dieses Blogs steif und fest behauptet, ich werd hier nie nix zur Erstellung eines eigenen Themes erzählen, weil es a) Zillionen von Themes für jeden Zweck und Geschmack schon gibt und b) Hunderte von hervorragenden Tutorials zum Thema bereits existieren. Aber wenn ich schon die Theme-Erstellung für Drupal und Joomla behandelt habe, darf WordPress eigentlich nicht fehlen, schon aus Gründen der Vergleichbarkeit.

Das tolle Tutorial von Christian Strang

Mit eins der besten Tutorials zur Erstellung eines eigenen WordPress-Themes ist das von Christian Strang auf Lernen hoch 2, und statt bei ihm abzuschreiben kann ich nur jedem ans Herz legen, es durchzuarbeiten und selber zu sehen und zu staunen, wie ausführlich er alles erklärt und wie hervorragend nachvollziehbar die ganze Sache ist. Ich gehe mal davon aus, dass jeder ein eigenes Theme nach Christians Anleitung hinkriegt, und setze nur noch ein paar Kleinigkeiten obendrauf.

Die Vorlage: dreispaltig (wenns geht) mit grossem Headerbild

Das Theme-Layout soll ganz schlicht werden, mal sehen wie weit wir damit kommen:

scribble

scribble

Wenn man sich durch Christians Tutorial durchgearbeitet hat, sollte man jetzt ungefähr dieses Layout erreicht haben:

tutorial_layout

tutorial_layout

Hier wird nur eine (die rechte) Sidebar genutzt, und die ist auch nach Christians Vorlage Widget-fähig, das ist die WordPress-Vorgabe und am einfachsten zu realisieren.

Eine zweite Sidebar

Ich hätte aber gern auch noch eine linke Sidebar, in die sollen meine neuesten Rezepte rein. Das geht nicht weiter kompliziert und auch ohne Widget. Ich füge in der index.php vor die div für den content noch eine div sidebar-left ein und nutze die WordPress-Funktion wp_get_recent_posts(), um mir die neuesten Beiträge ausgeben zu lassen. Das machen wir gleich mit Link zum Beitrag, dafür gibts den get_permalink():

 <div id = "sidebar-left">
    
    <h2>Die neuesten Rezepte<7h2>
        <ul>
            <?php $liste = wp_get_recent_posts();
            
            foreach($liste as $item){
                echo '<li><a href="' . get_permalink($item["ID"]) . '">' . $item["post_title"].'</a> </li>';
            }    
            ?>
        </ul> 
 
  </div> <!-- sidebar-left-->

In der style.css habe ich die divs für sidebar-left, main und sidebar-right nebeneinander positioniert:

#main       {width: 600px; padding: 20px; float: left;}

#sidebar-left   {width: 200px; padding: 10px;float: left;}

#sidebar-right   {width: 200px; padding: 10px;float: left;}

Die Ausgabe ist schon ganz passabel:

die_neuesten_rezepte

die_neuesten_rezepte

Ein Header-Bild wär jetzt noch schön

Dafür gibt es die sehr komfortable Funktionalität

add_theme_support( 'custom-header' );

Diese Zeile kommt in die functions.php

Dann gibt man ihr noch ein paar Argumente mit:

$args = array(
 'width'         => 1260,
 'height'        => 350,
 'default-image' => get_template_directory_uri() . '/images/header.jpg',
 'uploads'       => true,
 );
 add_theme_support( 'custom-header', $args );

Die width und heigth Angaben tauchen dann im Customizer als empfohlene Größe auf, das kann sich jeder selbst einstellen wie es zu seinem Layout paßt. In der header.php wird jetzt folgender Code an oberster Stelle nach der öffnenden div für den wrapper folgender Code eingesetzt:

<img src="<?php header_image(); ?>" 
    height="<?php echo get_custom_header()->height; ?>" width="<?php echo get_custom_header()->width; ?>" alt="" />

Jetzt noch das Header-Bild hochladen und ggf. zuschneiden, dann sollte es auch schon sichtbar sein:

headerbild

headerbild

Ich hab mir gleich noch das Blau des Himmels rausgemessen und in der style.css als background-color für die div header gesetzt, damit das schön zusammenpasst.

Jetzt fehlen mir eigentlich nur noch ein paar Schriftformatierungen, die mach ich in einem Rutsch:

#navlist li
{
font-family:    Times;
font-variant:small-caps;
font-size:      25px;
display: inline;
list-style-type: none;
padding-right: 20px;

}

body {
  margin: 0;
  padding: 0;
  font-family: Helvetica;
  font-size: 14px;    
  font-weight: normal;
  line-height: 24px;
  color: #43473b;
}


h1, h2, h3, h4, h5, h6 {
  font-family: Times;
  font-weight: normal;
  color: #43473b;
}

h1 { font-size: 45px; font-variant:small-caps;}
h2 { font-size: 30px; font-variant:small-caps;}
h3 { font-size: 22px; font-variant:small-caps;}

a { color: #43473b; 
    text-decoration: none;
}
a:hover { color: #fc737b; 
        }

Fertig ist mein Übungsstheme!

finish

finish

Jetzt wärs natürlich schick, wenn die linke sidebar auch Widgetfähig wäre, aber man kanns auch übertreiben… ich geh mal gucken, vielleicht finde ich da noch was dazu.

 

 

Joomla-Template 3: das Styling

Wir arbeiten jetzt mit unserer formate.css, die steckt im durch die erfolgreiche Template-Installation neu angelegten Verzeichnis [joomlainstallation]->templates->evis2014 im Unterverzeichnis css.

Damit das Ganze jetzt dem Vorbild TwentyFourteeen etwas ähnlicher sieht, habe ich zunächst einmal die Schriftarten angepasst und die Überschriften h1 bis h3 auf Kapitälchen gesetzt:

body {
  margin: 0;
  padding: 0;
  font-family: Helvetica;
  font-size: 14px;    
  font-weight: normal;
  line-height: 24px;
  color: #43473b;
}

h1, h2, h3, h4, h5, h6 {
  font-family: Times;
  font-weight: normal;
  color: #43473b;;
}

h1 { font-size: 45px; font-variant:small-caps;}
h2 { font-size: 30px; font-variant:small-caps;}
h3 { font-size: 22px; font-variant:small-caps;}


a { color: #43473b; }
a:hover { color: #fc737b;     }

Da ist weiter nichts dabei, das kann sich jeder selber einrichten wie er es gern hätte. Jetzt kommen unsere Inhalts-Divs dran, damit die auch schön nach unserem dreispaltigen Raster ausgerichtet werden:

#wrap {
width: 1260px;
}
    
#sidebarLeft {
padding: 20px;
float: left;
width: 200px;
}

#content {
float:left;
width:600px;
padding:20px;
}

#sidebarRight {

float: left;
width: 200px;
padding: 20px;
}

Das float: left richtet sidebarLeft, content und sidebarRight innerhalb der wrap nebeneinander aus.

Als nächstes nehme ich mir den Seitenkopf vor, da hätte ich gern unmittelbar unter dem Headerbild den Namen meiner Seite angezeigt. Das sieht in der index.php so aus:

<div id="kopf">
        <div id = "seitentitel" name ="titel">
        <?php $config = JFactory::getConfig();
        echo '<h1>'.$config->get( 'sitename' ).'</h1>';?>
        </div>

        <div id = "oben">
        <jdoc:include type="modules" name="oben" style="xhtml" />
        </div>
</div>

Ich habe das Ganze in eine eigene div namens kopf gepackt, weil es so einfacher war den farbigen Hintergrund ohne Lücken zu stylen. In der div seitentitel steckt eine Joomla-Variable, die uns den Seitentitel als h1 formatiert ausgibt, das mache ich mit der Anweisung:

<?php $config = JFactory::getConfig();
        echo '<h1>'.$config->get( 'sitename' ).'</h1>';?>

Gestylt wird die Ausgabe des Titels einfach so:

#seitentitel{
    display: inline-block;
    width: 1260px;
    height: auto;    
    }

In der div oben hatte ich im Modulmanager mein Main Menu positioniert. Damit es jetzt nicht mehr als Liste untereinander, sondern als horizontales Menü erscheint, musste ich etwas tüfteln. Ich habs schließlich so hingekriegt:

#oben ul li{
    display:inline;
    white-space: normal;
    }

Das klebte jetzt erstmal zusammen und war auch noch nicht schön formatiert, aber immerhin schon mal horizontal:

nebeneinander

nebeneinander

Das liess sich aber schön nachbessern, mit diesen Anweisungen:

#oben ul li a
{
font-family: Times;
font-style: normal;
font-variant:small-caps;
font-size: 24px;
text-decoration: none;
padding: .2em 1em;
color: #fff;
background-color: #89a7cb;
line-height: 2
}

kam Abstand (padding) zwischen die einzelnen Menüeinträge, und die Schrift wurde schöner formatiert.

Jetzt fehlte nur noch ein einheitlicher Hintergrund:

hintergrund_unschoen

hintergrund_unschoen

Deswegen hatte ich ja die umhüllende div kopf:

#kopf{background-color: #89a7cb}

Bingo! Fertig ist das horizontale Menü.

horizontales_menu

horizontales_menu

Und auch unsere dreiteilige Seite sieht gut aus:

fertig_gestylt

fertig_gestylt

Den Footer hab ich jetzt unterschlagen, aber den brauche ich auch nicht wirklich. Ich hab noch ein bisschen an den Feineinstellunggen geschraubt, die Autor-Info aus den Beiträgen rausgenommen und die Print- und Email-Icons verborgen, aber das wars dann auch schon. Das cleane Layout sieht dem Vorbild TwentyFourteen für meine Zwecke ähnlich genug, ich lass es jetzt mal gut sein. Besonders dank des hervorragenden Tutorials von http://joomla-templates-erstellen.de war das jetzt lang nicht so schwierig, wie es sich anfangs anliess, und hat richtig Spaß gemacht.

Nachtrag zum Footer

Der hat in der index.php eine eigene div gekriegt, nach den anderen Elementen und vor dem schliessenden Tag der div wrap:

    <div id="footer">
    Ich bin dein Footer.
    <jdoc:include type="modules" name="footer" style="xhtml" />
    <!-- end #footer --></div>

<!-- end #wrap --></div>

Damit er jetzt wirklich unten erscheint und nicht auf der Seite klebt, ergänzen wir die formate.css um folgenden Eintrag:

#footer {
padding: 10px 0;
clear: both; 
background-color:#89a7cb;

}

Das clear: both macht den Unterschied! Damit werden die floatenden Elemente beendet, es erscheint der Footer dann auch wirklich erst unterhalb der anderen Inhalts-divs. Eine anschauliche Erklärung  dazu findet man bei mediaevent.de.

Joomla-Template 2: die index.php

Das Grundgerüst für den Seitenaufbau: die index.php

Diese kann man sich bei einem anderen Template mopsen, oder eine der vielen Online-Vorlagen kopieren und modifizieren, z.B. bei joomla templates erstellen (Template-Installation) als zip-Datei herunterladen oder in der Joomla-Doku nachlesen. Meine index.php ist ein kleiner Bastard, den ich aus mehreren Vorlagen zusammenkopiert habe. Der Dateiheader sieht folgendermassen aus:

<?php

defined('_JEXEC') or die;


/* The following line gets the application object for things like displaying the site name */
$app = JFactory::getApplication();
?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<jdoc:include type="head" />
<link rel="stylesheet" href="<?php echo $this->baseurl ?>/templates/<?php echo $this->template ?>/css/formate.css" type="text/css" />

Im einleitenden PHP-Teil wird das Joomla-Applicationobject geladen, damit wir auf Systemvariable wie z.B. den Namen der Website zugreifen können. Dann folgt ein HTML-Header (hab ich auch so aus der Joomla-Doku kopiert) mit Einbindung unseres Stylesheets. Die Zeile:

<jdoc:include type="head" />

erzeugt einen kompletten Header, das kann man sich im Seitenquelltext anschauen, hier mal ein Ausschnitt:

head

head

Jetzt wirds dann aber interessant, denn jetzt kommen die Inhalte. In der Joomla-Doku ist ein sehr basic gehaltenes Beispiel gezeigt:

<body>
<jdoc:include type="modules" name="top" /> 
<jdoc:include type="component" />
<jdoc:include type="modules" name="bottom" />
</body>

Erstaunlich, aber das reicht für den Anfang.

  • In der zweiten Zeile wird eine Modulposition namens „top“ erzeugt und Joomla mitgeteilt, dass es hier Module laden kann.
  • In der dritten Zeile wird die Component geladen, das ist der Kern der Seite und enthält den relevanten Beitrag.
  • In der vierten Zeile wird eine zweite Modulposition namens Bottom erzeugt.

Das Ganze passiert innerhalb des body-tags und reicht schon aus, um eine simple Seite anzuzeigen. Das ganze müssen wir jetzt auf die Modulpositionen anpassen, die wir in unserer templateDetails.xml definiert haben. Kurz zur Erinnerung, das sah im ersten Ansatz so aus:

<positions>
 <position>oben</position>
 <position>left</position>
 <position>breadcrumb</position>
 <position>search</position>
 <position>right</position>
 </positions>

Wir packen das Ganze noch in einen div namens wrap, der hat nichts anderes zu tun als die Breite auf 1260px zu setzen, und dann sieht unser body erstmal so aus:

<div id="wrap">
<div id="header">
<a href="<?php echo $this->baseurl ?>"><img src="<?php echo $this->baseurl ?>/templates/<?php echo $this->template ?>/images/logo.jpg" alt="Logo" /></a>
<!-- end #header -->
</div>

    <div id = "oben">
    <jdoc:include type="modules" name="oben" style="xhtml" />
    </div>


    <div id="sidebarLeft">
    <jdoc:include type="modules" name="left" style="xhtml" />
    <!-- end #sidebarLeft --></div>

    <div id="content">
    <jdoc:include type="component" />
    <jdoc:include type="message" />
    <jdoc:include type="modules" name="debug" />
    <!-- end #content --></div>
    
    <div id="sidebarRight">
    <jdoc:include type="module" name="search" style="xhtml" />
    <jdoc:include type="modules" name="right" style="xhtml" />
    <!-- end #sidebar2 --></div>

<!-- end #wrap --></div>

Nicht irritieren lassen, ich hab die breadcrumbs und den footer einfach weggelassen.

Aber ansonsten ist der Aufbau eigentlich eher einfach. Erst definiere ich mir eine header-div, die tut nichts anderes als mein Headerbild aufnehmen und einen Link auf die Startseite setzen, das passiert mit der Zeile:

<a href=“<?php echo $this->baseurl ?>“><img src=“<?php echo $this->baseurl ?>/templates/<?php echo $this->template ?>/images/logo.jpg“ alt=“Logo“ /></a>

Hab ich aus der Joomla-Doku so kopiert und nur Pfad und Namen zur Bilddatei angepasst.

Dann gibt für jede Modulposition eine div, und der wird mitgeteilt wie sie heisst und was sie zu tun hat. Wir fangen oben an:

<div id = "oben">
    <jdoc:include type="modules" name="oben" style="xhtml" />
    </div>

Hier setze ich später mein Modul für das Hauptmenü rein, darüber nachher mehr.

Die linke Seitenleiste kriegt den Platz für meine neuesten Beiträge reserviert, das ist ebenfalls ein Modul.

<div id="sidebarLeft">
    <jdoc:include type="modules" name="left" style="xhtml" />
    <!-- end #sidebarLeft --></div>

In der Mitte ist Platz für unseren Seiteninhalt, die überaus wichtige Component, und für Fehlermeldungen:

<div id="content">
    <jdoc:include type="component" />
    <jdoc:include type="message" />
    <jdoc:include type="modules" name="debug" />
    <!-- end #content --></div>

In der rechten Seitenleiste platzieren wir das Suchformular und eine weiter Modulposition, in die kommt nachher meine Liste mit den Rezeptkategorien.

<div id="sidebarRight">
 <jdoc:include type="module" name="search" style="xhtml" />
 <jdoc:include type="modules" name="right" style="xhtml" />
 <!-- end #sidebar2 --></div>

Das wars auch schon. Jetzt könnten wir unser (noch komplett ungestyltes) Template schon mal anschauen.

Die Installation

Wir packen jetzt den gesamten Inhalt unseres Arbeitsordners in eine ZIP-Archiv:

zip-datei-erzeugen

zip-datei-erzeugen

Dann gehen wir im Kontrollzentrum unter Erweiterungen->Verwalten->Installieren->Paketdatei hochladen und laden unser ZIP-Archiv. Ich hatte beim ersten Versuch einen Fehler, weil in der templateDetails.xml eine falsche Dateieendung für das Logo angegeben war, bitte gegebenenfalls korrigieren:

<filename>images/logo.jpg</filename>

Das sollte es aber gewesen sein, unter Erweiterungen->Templates->Stile sollte jetzt unser neues Template auftauchen, und wir können es als Standard setzen.

standard-setzen

standard-setzen

Wenn wir jetzt unsere Webseite anschauen, kommt das natürlich noch sehr traurig weil komplett ungestylt daher:

ungestylt

ungestylt

Aber darum kümmern wir uns gleich. Zuerst schauen wir uns mal an, was wir auf welche Modulposition geladen haben, das ist nämlich gar nicht viel:

modulpositionen

modulpositionen

Auf left sitzen die neuesten Beiträge, auf oben das Main Menü, und auf right die Rezeptkategorien. Die Suche ist hier leider nicht mit im Bild, die sitzt auf Position search. Das wars auch schon!

Jetzt gehen wir dran, unseren Seitenaufbau zu stylen. Was jetzt noch kommt ist fast reines CSS , und dafür gibt es einen neuen Beitrag.

Ein einfaches Joomla-Template erstellen

Eine hervorragende Anleitung zum Erstellen eines einfachen Joomla-Templates findet man hier bei http://joomla-templates-erstellen.de, und auch die Joomla-Doku gibt einiges her zm Thema Understanding Joomla Templates. Ich versuche hier trotzdem einmal eine Zusammenfassung der absoluten Basics, damit man mal einen kurzen Überblick bekommt.

Die Vorlage: ein TwentyFourteen-Scribble

Mein Template soll am Ende so aussehen wie mein geliebtes WordPress-Theme Twenty-Fourteen, das ist schön schlicht und ohne Schnickschnack. Das Layout ist simpel:

scribble

scribble

Die Inhalte leihe ich mir mal beim Inselfisch-Kochbuch. Das Logo = Headerbild soll die gesamte Breite von 1260 px einnehmen, darunter kommt der Titel der Seite, evtl. auch der Untertitel = Slogan. Ich habe nur ein einfaches lineares Menü ohne Untermenüs. In die rechte Seitenleiste sollen die neuesten Beiträge, in die linke Seitenleiste meine Rezeptkategorien. In die Mitte kommt der jeweilige Content, der Footer schliesst die Sache nach unten ab. Das war schon alles, auf wieterführende Features wie Breadcrumb Navi oder sekundäres Menü verzichte ich großzügig, der Übersicht halber.

Schritt 1: Die Verzeichnisstruktur erstellen

Zunächst geht das erstmal im Trockenkurs, es gibt einiges an Vorarbeit zu erledigen, ehe man sich die Ergebnisse auch wirklich in Joomla anschauen kann. Wir fangen mal mit dem leichten Teil an: zwei Screenshots von unserem Templateentwurf für die Vorschau im Template-Manager. Einen nenne ich template_preview.png, 400x300px, den zweiten template_thumbnail.png, 200×50 px. Beide kommen in mein Template-Verzeichnis, das hat den Arbeitstitel Evis2014.

template_preview

template_preview

Dann lege ich noch einen Unterordner namens css und einen zweiten namens images an. Das wäre schonmal die komplette Verzeichnisstruktur.

verzeichnisstruktur

verzeichnisstruktur

Die erste Template-Datei: templateDetails.xml

Dreh- und Angelpunkt unseres neuen Templates ist die definierende xml-Datei. Wie die für die einzelnen Joomla-Versionen aussehen sollte, ist hier bei joomla-templates hervorragend dokumentiert, dort ist vor allem auch erklärt welche Komponenten Pflicht sind und welche nur kann.

Meine templateDetails.xml ist sehr schlicht gehalten, Den Header habe ich mir bei joomla-templates kopiert:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE install PUBLIC "-//Joomla! 1.6//DTD template 1.0//EN" "http://www.joomla.org/xml/dtd/1.6/template-install.dtd">
<extension version="3.0" type="template" client="site">

Darauf folgen die persönlichen Informationen über Templatenamen und Author:

<name>Evis2014</name>
<author>Evi Leu</author>
<creationDate>30. März 2018</creationDate>
<description>Mein Joomla-Nachbau des WordPress-Templates Twenty Fourteen</description>

Jetzt wirds gehaltvoller: man muss Joomla mitteilen, welche Dateien mit im Spiel sind (die Liste werden wir nachher noch abspecken):

<files>
<filename>component.php</filename>
<filename>error.php</filename>
<filename>index.html</filename>
<filename>index.php</filename>
<filename>offline.php</filename>
<filename>template_preview.png</filename>
<filename>template_thumbnail.png</filename>
<filename>templateDetails.xml</filename>

<filename>css/formate.css</filename>
<filename>images/logo.png</filename>

</files>


Die Dateien existieren natürlich noch gar nicht alle, aber wir werden sie jetzt der Reihe nach anlegen.

Der letzte Abschnitt: die Template Positions (eine Arbeitsversion, das wird sich später noch etwas ändern:

<positions>
<position>oben</position>
<position>left</position>
<position>breadcrumb</position>
<position>search</position>
<position>right</position>
<position>footer</position>
</positions>

Fehlt noch das schliessende Tag für die Extension:

</extension>

Das wars erstmal, und jetzt gehen wir dran, unsere Dateien auch anzulegen.

Die weiteren Template-Dateien

  • index.html: eine leere HTML-Seite
  • component.php, error.php, offline.php : kann man sich von einem anderen Joomla-Template kopieren oder auch weglassen (dazu später mehr)
  • css/formate.css legen wir zunächst als leere Datei im Ordner css an
  • images/logo.png wird unser Headerbild, das sollte 1260px breit sein.

Das sollte für den Anfang mal genügen. Für die index.php, das Grundgerüst unserer Seite, gibts einen neuen Beitrag.