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.

Von Joomla nach WordPress umziehen – der Vollständigkeit halber

Ich habe drüben im Drupal-Blog ausführlich beschrieben, wie man Inhalte aus Drupal in WordPress-Beiträge überführt, nachzulesen hier. Das selbe machen wir jetzt noch mit Joomla, und zwar möchte ich die Beiträge aus einer bestimmten Kategorie nach WordPress exportieren. Meine ausgewählte Kategorie sind natürlich die Rezepte, mit der Kategorie-ID 8 (im Zweifelsfall nachschlagen in der Tabelle #__categories).

Wie kommen wir an Titel und Inhalt der Rezepte?

Aus der Tabelle #__content. Die holen wir uns nach Access rüber und schauen sie mal näher an.

content

content

Die id und den title nehmen wir mit, den alias lassen wir aus. Dann brauchen wir noch den introtext und den fulltext (beide!), weil Joomla den Beitragstext in diese beiden Felder aufteilt, sobald man einen Weiterlesen-Tag eingefügt hat. Das sieht man hier im Screenshot oben bei den ids 4 bis 8, so sieht das dann aus.

Den state müssen wir filtern, -2 bedeutet „marked for deletion“, 1 ist veröffentlicht, wir nehmen nur die 1er. Und die catid filtern wir auch, auf die 8 für Rezepte. (Bei mir ist noch ein Haufen Schrott vom Testen mit drin, ich nehm mal noch die Datensätze 9-47 raus). Übrig bleibt die folgende Tabelle:

content_gefiltert

content_gefiltert

Die specken wir noch ab, die Felder introtext und fulltext werden zu einem Feld namens bodytext zusammengefügt, die catid und der state fliegen raus.

Jetzt fehlen noch die Tags für die Kategorien

Kleine Erinnerung: ich hatte die Rezeptkategorien aus WordPress auf Joomla-Tags ohne Schachtelung abgebildet. Die holen wir uns jetzt wieder zurück, und zwar aus der Tabelle #__tags.

tags

tags

Der erste Eintrag für root fliegt raus, vom Rest übernehmen wir id und title. Parent_id ist überall leer, weil nicht geschachtelt, published = 1 passt auch. Um jetzt die Tags den Rezepten (hier in der Tabelle id_title_bodytext) zuzuordnen, verknüpfen wir über die Tabelle contentitem_tag_map. Beim Importieren nach Access darauf achten, dass content_item_id und tag_id als Integer rüberkommen! Das sieht dann so aus:

tags_beziehungen

tags_beziehungen

Darüber basteln wir uns eine Abfrage, in der zunächst mal jedes Rezept so oft vorkommt, wie es Tags zugeordnet hat:

abfrage_tags

abfrage_tags

Kurzer Blick über die Tabelle: ich habe zu keinem Rezept mehr als 2 Tags zugeordnet, aber das passt schon, ist korrekt.

Zuordnen der Tags zu WordPress-Kategorien

Dafür zieht man sich alle gültigen Tags aus der #–tags ab und importiert sie als Kategorien nach WordPress, wie das geht habe ich in diesem Artikel unter Schritt 1: Anlegen der Kategorien in WordPress im Drupal-Blog ausführlich beschrieben.

Dann habe ich mir die entstandene Tabelle wp_terms nach Access rübergeholt:

wp_terms

wp_terms

Hier kann ich jetzt über den name des Terms auf den title des tags verknüpfen, weil die Schreibweise identisch ist:

join_term_name

join_term_name

Damit bekomme ich die WordPress-Kategorie-IDs zu den Rezepten.

term_id

term_id

Das hatten wir so ähnlich schonmal, jedes Rezept taucht jetzt so oft auf, wie es Kategorien/Tags hat. Jetzt Gruppieren wir noch, und nehmen den ersten und letzten Wert der Term-ID. Diese sind bei den Datensätzen gleich, die nur eine Kategorie zugeordnet haben, das ist schon richtig so.

ersterwert_letzterwert

ersterwert_letzterwert

So, das wars. Diese Tabelle kann man nach WordPress importieren, und zwar genau so wie ich es in diesem Artikel beschrieben habe:

DRUPAL NACH WORDPRESS: BEITRÄGE MIT KATEGORIEN ERZEUGEN

Dabei muss man wahrscheinlich noch eine kleine Abfrage einbauen, was passieren soll wenn erster und letzte Wert der term_id gleich sind, aber prinzipiell funktioniert die Sache so einwandfrei, die Beiträge werden in WordPress angelegt und mit Kategorien versehen.

Weiter gehts mit Drupal für alte Programmierer – aber im neuen Blog!

Meine nicht so kleine Serie über Joomla für alte Programmierer ist vorläufig beendet, ich hoffe es hat euch genausoviel Spaß gemacht wie mir. Aber die vielen Artikel und die notwendigen Kategorien haben den Blog zum Schwarzen Pinguin doch etwas unübersichtlich gemacht – jetzt wäre eine Multiblog-Seite schick! Vor allem, weil ich jetzt schonmal die Nase beim nächsten CMS reingesteckt habe, nämlich bei Drupal, und auch darüber eine Serie verfassen werde. Drupal macht nämlich echt Laune für alte Datenbanker!

Follow me – ich habe für den Drupal-Blog eine eigene Seite eingerichtet:

Drupal für alte Programmierer

Wir sehen uns drüben im neuen Blog!

Nachtrag: mehr als 2 Kategorien in der Export-Datei

Ich hab ja ganz lässig behauptet, wenn man mehr als zwei Kategorien pro Rezept  in die Export-Datei schreiben will, braucht man in Access eine Kreuztabelle. Jetzt bin ich gefragt worden, wie man das anstellt, und ich muss zugeben die ist sehr, sehr haarig zu konfigurieren. Ich hab da mal den „kleinen Dienstweg“ über ein Excel-Makro genommen, funktioniert auch und ist wesentlich leichter nachzuvollziehen.

Die Ausgangsbasis

Wir schubsen unsere Ausgangstabelle in Excel rein, die dürfte ja inzwischen bekannt sein. Jeder Datensatz taucht so oft auf, wie er Kategorien hat, und wir haben die Joomla-ID dazugemappt:

excel_startdaten

excel_startdaten

Post_id, post_title, term_id und name kommen aus WordPress, das was hier joomla_map.id heißt ist die Joomla-Tag-ID aus unserer mapping-Tabelle.

So soll es dann aussehen

Das Arbeitsblatt mit den Ausgangsdaten habe ich „start“ genannt, das Output-Arbeitsblatt heisst „ziel“ und sieht in leerem Zustand so aus:

excel_ziel_leer

excel_ziel_leer

Wir übernehmen nur die id und den titel, und verteilen die Tags auf die entsprechenden Felder tag1…tagn. Der Clou dabei ist, dass man unbegrenzt viele Tags pro Datensatz übernehmen und einsortieren kann. Den Content hab ich mir hier gespart, kann man sich später über die id wieder dazumappen.

So wirds gemacht

Der VBA-Code dazu sieht so aus:

Sheets("start").Select
        
    i = 2
    j = 2
    k = 0
    akt_id = Cells(2, 1).Value
        
    While akt_id <> ""
        
                Sheets("start").Select
                akt_id = Cells(i, 1).Value
                akt_titel = Cells(i, 2).Value
                akt_kat = Cells(i, 4).Value
                akt_tag = Cells(i, 5).Value
                    
                    
                Sheets("ziel").Select
                Cells(j, 1).Value = akt_id
                Cells(j, 2).Value = akt_titel
                Cells(j, 3 + k).Value = akt_tag
                
                
                i = i + 1
                If Worksheets("start").Cells(i, 1) <> akt_id Then
                    j = j + 1
                    k = 0
                Else
                k = k + 1
                End If
        Wend

Was hab ich gemacht? Ich steppe mit dem i durch die start-Tabelle und schreibe so lange in die selbe Zeile j der ziel-Tabelle, wie ich in start auf die selbe id treffe. Das k zählt die Spalte für das tag1..n hoch. Treffe ich auf eine neue id in der Zieltabelle, wird j um 1 erhöht und k wieder auf 0 gesetzt, und das ganze so lange bis ich auf das erste leere Feld id in der start-Tabelle treffe.

Das Ergebnis sieht dann so aus:

excel_zieldaten

excel_zieldaten

In der Praxis wird man sicher die Anzahl der zu importierenden tags auf ein handliches Mass  beschränken, das muss sich jeder selber überlegen, was da bei seinen Bestandsdaten Sinn macht. Aber so bekommt man alle Kategorien aus WordPress auf Joomla-Tags gemappt, mit dieser Export-Tabelle kann man weiterarbeiten.