Tutorial: Verschachtelte WordPress Widget-Areas

18. September 2009 - Tutorials, WordPress Funktionen - 16 Kommentare

Tutorial: Verschachtelte WordPress Widget-Areas

Um mit WordPress einen weiteren Schritt in Richtung CMS zu machen, kann man die Widgets der Sidebar oder jeder anderen Widget-Area in einem WordPress-Theme abhängig vom Inhalt anzeigen lassen. Im folgenden Beispiel unterscheide ich zwischen Sidebars für Startseite, Seiten, Artikeleinzelansichten und Kategorien.

Warum verschachtelte Widget-Areas?

Verschachtelte Widget-Areas bieten eine große Flexibilität. Man hat damit die Möglichkeit bspw. verschiedene Sidebars abhängig davon anzuzeigen, wo der Benutzer sich auf der Website befindet.

In meinem Beispiel werde ich abfragen, ob sich der User auf der Startseite, auf einer Seite, in einer Artikeleinzelansicht oder in einer Kategorie befindet. Um nicht obligatorisch für alle Fälle eine eigene Sidebar anlegen zu müssen, erstelle ich außerdem eine allgemeine Sidebar, die immer dann angezeigt wird, wenn für den jeweiligen Unterbereich keine Widgets definiert wurden.

Sprungmarken

Erstellen einer Widget-Area

Zum Definieren der Widget-Area benötige ich die Funktion register_sidebar() (s.a. WordPress Codex). Der Funktionsname ist dabei ein wenig irreführend, da man damit nicht nur Widget-Areas in Sidebars, sondern natürlich auch im Footer oder sonstwo in den Theme-Dateien erstellen kann.

Allgemeine Widget-Sidebar

Folgenden Code trage ich in die functions.php im Theme-Ordner ein, um zunächst die allgemeine Sidebar namens Sidebar zu erstellen.

Code für functions.php

<?php
register_sidebar(array(
'name' => 'Sidebar',
'before_widget' => '<div id='%1$s' class='%2$s'>',
'after_widget' => '</div>',
'before_title' => '<h3>',
'after_title' => '</h3>'));
?>

Bemerkung:
Das Format für die Widgets ist somit festgelegt. Die Widget-Sidebar wird nun im WordPress-Admin bereits (wie oben im Bild zu sehen) angezeigt.

Ausgabe der Widgets im Theme

Jetzt muss dem WordPress-Theme noch gesagt, werden wo diese Widget-Area, wenn sie Widgets enthält (aktiv ist), angezeigt werden soll (s.a. Widgetizing Themes von Automattic).

Für den Aufruf der Widget-Area im Theme (in meinem Beispiel in der sidebar.php) wird die Funktion dynamic_sidebar() (s.a. WordPress Codex) verwendet.

Code für sidebar.php

<div id='sidebar'>
<?php if ( !dynamic_sidebar() ) : ?>
    <!-- hier werden die Widgets angezeigt -->
    <p>Inhalt der Sidebar, wenn keine Widgets aktiv sind.</p>
<?php endif; // endif dynamic sidebar ?>
</div><!-- end sidebar -->

Bemerkung:
In diesem Code liegt meine Sidebar in einem div mit der ID sidebar. Wenn mindestens ein Widget aktiv ist, wird dieses innerhalb der if-Abfrage angezeigt.

Erstellen mehrerer Widget-Areas

In der functions.php lege ich nun auch die übrigen Widget-Areas an, die wir dann später in der Sidebar verschachteln wollen.

Allgemeine Sidebar & Unter-Sidebars

Wie schon angesprochen möchte ich eine allgemeine Sidebar erstellen, die immer dann angezeigt wird, wenn für den jeweiligen Unterbereich kein Widget aktiv ist. Außerdem definiere ich die extra Widget-Areas für Startseite, Seite, Artikeleinzelansicht und Kategorie.

Code für functions.php

<?php
// Sidebar Nr. 1 - Allgemein
register_sidebar(array(
'name' => 'Sidebar',
'before_widget' => '<div id='%1$s' class='%2$s'>',
'after_widget' => '</div>',
'before_title' => '<h3>',
'after_title' => '</h3>'));
// Sidebar Nr. 2 - Startseite
register_sidebar(array(
'name' => 'Sidebar-Home',
'before_widget' => '<div id='%1$s' class='%2$s'>',
'after_widget' => '</div>',
'before_title' => '<h3>',
'after_title' => '</h3>'));
// Sidebar Nr. 3 - Seite
register_sidebar(array(
'name' => 'Sidebar-Page',
'before_widget' => '<div id='%1$s' class='%2$s'>',
'after_widget' => '</div>',
'before_title' => '<h3>',
'after_title' => '</h3>'));
// Sidebar Nr. 4 - Artikeleinzelansicht
register_sidebar(array(
'name' => 'Sidebar-Post',
'before_widget' => '<div id='%1$s' class='%2$s'>',
'after_widget' => '</div>',
'before_title' => '<h3>',
'after_title' => '</h3>'));
// Sidebar Nr. 5 - Kategorie
register_sidebar(array(
'name' => 'Sidebar-Category',
'before_widget' => '<div id='%1$s' class='%2$s'>',
'after_widget' => '</div>',
'before_title' => '<h3>',
'after_title' => '</h3>'));
?>

Bemerkung:
Alle für mein Beispiel benötigten Widget-Sidebars sind nun angelegt. Um das Ganze übersichtlich zu halten, habe ich sinnvolle Namen vergeben und die Sidebars zur Übersicht nummeriert (das brauchen wir später noch).

Verschachteln der Widget-Areas

Nochmal zur Verdeutlichung: Es soll erreicht werden, dass, wenn wir uns bspw. in einer Artikeleinzelansicht (Post) befinden, abgefragt wird, ob für diesen Unterbereich Widgets aktiv sind. Wenn das der Fall ist, werden diese in der Sidebar ausgegeben, wenn nicht, wird die allgemeine Startseite angezeigt. Die gleiche Abfrage soll für die Unterbereiche Startseite, Seite und Kategorie gemacht werden.

Wo sich der Benutzer auf der Website befindet, kann ich mit folgenden Conditional Tags (s. a. WordPress Codex) abfragen:

  • is_front_page()
  • is_page()
  • is_single()
  • is_archive()

Parallel dazu muss ich herausfinden, ob eine bestimmte Widget-Area aktiv ist, d. h. ob ihr Widgets zugewiesen wurden. Das mache ich mit dem Conditional Tag is_active_sidebar().

Die verschiedenen Sidebars werden durch den Namen, die ID oder der Nummer identifiziert. Ich habe mir für die eindeutige Zuordnung durch die Nummer (Reihenfolge) entschieden.

  • Nr. 1 = Sidebar Allgemein
  • Nr. 2 = Sidebar Startseite
  • Nr. 3 = Sidebar Seite
  • Nr. 4 = Sidebar Artikeleinzelansicht
  • Nr. 5 = Sidebar Kategorie

Code für sidebar.php

<div id='sidebar'>
<?php 
    if(is_front_page() &amp;&amp; is_active_sidebar(2)) : dynamic_sidebar(2);
    elseif(is_page() &amp;&amp; is_active_sidebar(3)) : dynamic_sidebar(3);
    elseif(is_single() &amp;&amp; is_active_sidebar(4)) : dynamic_sidebar(4);
    elseif(is_archive() &amp;&amp; is_active_sidebar(5)) : dynamic_sidebar(5);
    else : 
	
        if (!dynamic_sidebar(1)) : ?>
    
    	<!-- hier werden die Widgets angezeigt -->
    	<p>Inhalt der Sidebar, wenn keine Widgets aktiv sind.</p>
        <?php endif; // endif dynamic sidebar ?>
    	
<?php endif; // endif active sidebars ?>
</div><!-- end sidebar -->

In Worten bedeutet dieser Code:

Wenn der User auf der Startseite ist und die Sidebar Nr. 2 aktiv ist, dann zeige diese an. Wenn sich der User auf einer Seite bewegt und die Sidebar Nr. 3 aktiv ist, dann zeige diese an. Wenn sich der User in einer Artikeleinzelansicht bewegt und die Sidebar Nr. 4 aktiv ist, dann zeige diese an. Wenn eine Kategorie angezeigt wird und die Sidebar Nr. 5 aktiv ist, dann zeige diese an.

Wenn all das nicht der Fall ist, wird abgefragt, ob die allgemeine Sidebar Nr. 1 aktiv ist. Wenn auch das nicht der Fall ist, dann wird der Text Inhalt der Sidebar, wenn keine Widgets aktiv sind. angezeigt.

Verbesserungsvorschläge?

Da es sich meines Erachtens um ein interessantes Feature für WordPress-Themes handelt, würde ich mich über Verbesserungsvorchläge freuen, sollte jemand eine einfachere oder bessere Lösung haben. Da ich kein PHP-Experte bin, kann es sein, dass dieser Code evtl. noch effektiver gestaltet werden kann.

Fazit

Mit verschachtelten Widget-Areas kann man schon ein gutes Stück an Flexibilität in einem WordPress-Theme gewinnen und sich somit weiter in Richtung CMS bewegen. Das Beispiel ist natürlich beliebig erweiterbar, da man alle möglichen Abfragen für die Anzeige verschiedener Widget-Areas verwenden kann. Hier ist Kreativität gefragt.

Relevante Links

Autor

Moin, ich bin Simon und ehemaliger Betreiber dieses Blogs.

RSS abonnieren

und so weiter...

Kommentare

  • Chris - am 21. September 2009 - Antworten

    Hi Simon,

    danke für diese Anregung. Ich baue gerade die Sidebar Funktionalität von Thematic so um, dass sich deine verschachtelten Widgets komplett über die functions.php des Child Temes realisieren lassen.

    Viele Grüße,

    Chris

    • Simon [webdemar] - am 21. September 2009 - Antworten

      Moin Chris, das klingt interessant! Das werde ich mir auf jeden Fall ansehen, wenn es fertig ist!

  • Michael Bergen - am 8. November 2009 - Antworten

    Hallo Simon,
    bin nicht ganz sicher aber ich glaube daß Widget Logic plugin ist eine alternative und sehr komfortable Methode um dein Problem zu lösen.
    http://wordpress.org/extend/plugins/widget-logic/faq/

  • Frank - am 25. November 2009 - Antworten

    Es empfiehlt sich in vielen Fällen, nicht mit dem Zähler zu arbeiten, sondern Namen zu vergeben. So ist es einfacher bei Erweiterungen im Nachhinein, da explizit der Name angesprochen wird und nicht der Zähler.
    Für dein Beispiel wäre das so:

    // Sidebar Nr. 5 - Kategorie
    register_sidebar( array(
    	'name' => 'Sidebar-Category',
    	'id' => 'sidebar-category',
    	'before_widget' => '<div id="%1$s" class="%2$s">',
    	'after_widget' => '</div>',
    	'before_title' => '<h3>',
    	'after_title' => '</h3>'
    ) );
    
     
    if ( is_front_page() && is_active_sidebar('sidebar-category') ) : dynamic_sidebar('sidebar-category');
    • Simon [webdemar] - am 25. November 2009 - Antworten

      Moin Frank,
      vielen Dank für den Vorschlag! Du hast Recht, mit der sprechenden ID wird die Zuordnung sicher eindeutiger.

  • Frank - am 25. November 2009 - Antworten

    Eventuell noch der Hinweis, ab WordPress 2.9 kann eine Beschreibung zum Widget-Bereich mitgegeben werden, was die Übersicht und das Verständnis sicher erleichtert. Gerade im Rahmen des Verschachtelns im obigen Artikel ist das sicher hilfreich:

    // Sidebar Nr. 5 - Kategorie
    register_sidebar( array(
    	'name' => 'Sidebar-Category',
    	'id' => 'sidebar-category',
    	'description' => 'Sidebar Nr. 5 - Kategorie und viele weitere Infos passen hier hinein'
    	'before_widget' => '<div id="%1$s" class="%2$s">',
    	'after_widget' => '</div>',
    	'before_title' => '<h3>',
    	'after_title' => '</h3>'
    ) );
     
    if ( is_front_page() && is_active_sidebar('sidebar-category') ) : dynamic_sidebar('sidebar-category');
  • Stefan - am 25. März 2010 - Antworten

    Perfekt, genau die Doku, die mir fehlte.
    Habe die Tipps direkt umgesetzt :-)
    Gruß
    Stefan

  • jens - am 23. August 2010 - Antworten

    wie kann ich sidebar in den footer bringen ??

  • Eric - am 10. September 2010 - Antworten

    Danke für den Tipp. Hatte es auch erst so gemacht. Wurde mir aber dann zu kompliziert. Hab in meinem neuen Blog auch gleich mal was dazu geschrieben.

  • kai - am 11. März 2011 - Antworten

    Hab genau das gleiche Prinzip auch eingesetzt auf einer Seite. Nur jetzt wollte ich noch die Abfrage nach einer bestimmten Seite einarbeiten.


    elseif(is_page('kontakt') && is_active_sidebar('sidebar-contact')) : dynamic_sidebar('sidebar-contact');

    Die Sidebar ist registriert mit der ID: sidebar-contact – ist also ansteuerbar.
    Aber irgendwie bekomm will das nicht so recht und er gibt mir immer nur die “normale” is_page() aus.
    Also keine gezielte Ansteuerung von einzelnen Seiten. Dabei sollte das doch gehen *grübel*

    Auch mit der Post-ID statt dem Namen klappt es nicht.

    Hat jemand ne Idee?

    • kai - am 11. März 2011 - Antworten

      so einfach kann es gehen… die Reihenfolge macht den Unterschied.

      Nicht funktioniert:

      elseif(is_page() ...
      elseif(is_page('kontakt') ...

      Wenn allerdings die “allgemeine Sidebar am Schluss angegeben wird geht es:

      elseif(is_page('kontakt') ...
      elseif(is_page() ...

      Hoffe das hilf euch

Trackbacks

Deine Meinung