WordPress-MultiSite: Ein Theme für mehrere Blogs einsetzen

Diese und alle anderen freudendahl.net-Seiten sind mit einer WordPress-MultiSite-Installation umgesetzt. Das bedeutet, dass ich mehrere voneinander getrennte Webseiten/Blogs mit der gleichen WP-Installation betreibe, was eine tolle Sache ist und viel Arbeit spart. Im folgenden will ich kurz erklären, wie man ein Theme für mehrere Blogs einsetzt und wie man es trotzdem für einzelne Blogs individuell anpassen kann.

Natürlich kann jedes Blog auf einer MultiSite-Installation ein eigenes Theme kriegen. Es kann sich aber durchaus auch lohnen, alle oder zumindest mehrere Blogs mit dem gleichen Theme zu betreiben. Anpassungen an dem Theme stehen so z.B. gleich auf allen Seiten zur Verfügung, und oft sind die Unterschiede zwischen den Blogs sowieso gering und Einstellungssache (Headerbild, Position der Sidebar). Um das Theme für einzelne Blogs anzupassen, gibt es prinzipiell zwei Wege: Per Stylesheet (CSS) oder in den Themedateien (PHP). In beiden Fällen müssen wir bei einem Aufruf der Seite zuerst ermitteln, zu welchem Blog der aktuelle Aufruf gehört.

Anpassungen in Themedateien

Anpassungen in Themedateien können z.B. das Ausblenden oder Verschieben von Metainformationen oder das Hinzufügen von Widget-Bereichen (Sidebars) sein. In jedem Fall muss in der Themedatei bekannt sein, um welches Blog es gerade geht. Dafür kann man auf die Informationen aus der wp_blogs-Tabelle zugreifen. Darin steht pro Blog eine Domain und eine Pfad-Angabe. Wenn ihr MultiSite mit Domains oder Subdomains verwendet, dann könnt ihr die folgenden Beispiele so übernehmen. Für Unterordner-Installationen solltet ihr die Beispiele von domain zu path ändern. Alle folgenden Code-Beispiele können in die functions.php eures Themes.

/**
 * Checks whether the current blog is the code blog.
 * 
 * @return bool True if the current blog is the code blog site, false
 * otherwise.
 */
function abc_is_code_blog() {
  global $blog_id;
  $blog_details = get_blog_details($blog_id, false);
  return (strpos($blog_details->domain, 'code.example') === 0);
}

Da ich eine sehr geringe Anzahl Blogs betreibe habe ich mir pro Blog eine Funktion wie die obige angelegt. Also abc_is_code_blog(), abc_is_main_blog()… Damit kann ich dann ganz simpel in Themedateien Änderungen per if (…) bzw. if (!…) nur für einzelne Blogs durchführen bzw. nicht durchführen. In der Funktion müsst ihr „code.example“ durch eure Subdomain ersetzen! Der Positions-Vergleich anstatt eines direkten String-Vergleichs findet übrigens statt, da ich eine Entwicklungskopie der Blogs lokal als „freudendahl.loc“ betreibe und der gleiche Test da natürlich auch funktionieren soll.

Anpassungen im Stylesheet

Die Styles pro Blog abzuändern ist keine große Kunst – wenn man eine Klasse hat, an der an diese Änderungen aufhängen kann. Um alle Seitenbereiche erfassen zu können, muss diese Klasse sinnvollerweise am body-Tag hängen. Manch ein Theme mag das schon von sich aus ergänzen (nachschauen schadet nicht), aber Twenty Eleven, was hier modifiziert als Child-Theme zum Einsatz kommt, bietet das leider nicht an.

Screenshot body-Tag

Die im Screenshot zu sehende Klasse können wir wie folgt ganz leicht ergänzen:

/**
 * Adds a site-specific CSS class to the list of body classes.
 * 
 * @param array $classes An array of body class names.
 * @return array The modified body class name array.
 */
function abc_body_class($classes) {
  global $blog_id;
  
  $blog_details = get_blog_details($blog_id, false);
  $domain = str_replace('.', '-', $blog_details->domain);
  $classes[] = 'blogclass-' . $domain;
  return $classes;
}

add_filter('body_class', 'abc_body_class');

Die Methode „abc_body_class“ wird über den „body_class“-Filter aufgerufen. Dieser Filter ist schon ein Weilchen Teil von WordPress, aber nicht jedes Theme unterstützt ihn. Wenn das wie oben nicht klappt, schaut mal in die header.php eures Themes. Das sollte dort so aussehen:

<body <?php body_class(); ?>>

Damit sollte am body-Tag dann eine Klasse wie „blogclass-example-org“ zur Verfügung stehen (in meinem Fall „blogclass-freudendahl-net“, „blogclass-code-freudendahl-net“ und „blogclass-johannes-freudendahl-net“). Mit dieser Klasse sollte man ohne Probleme Definitionen im Stylesheet nur für bestimmte Blogs treffen können:

a {
  color: red;
}

#blogclass-example-org a {
  color: blue;
}

Immer unter der allgemeingültigen Definition (diese soll ja überschrieben werden) oder vielleicht auch gesammelt ganz am Ende des Stylesheets.

7 Gedanken zu „WordPress-MultiSite: Ein Theme für mehrere Blogs einsetzen

  1. Hallo,

    ich bin bisher vor Multisite Installationen zurückgeschreckt. Damals wollte ich wpShopGermany, ein Shop PlugIn über eine MultiSite Installation betreiben. Leider unterstützte das PlugIn MultiSite nicht. Seitdem bin ich vorsichtig geworden. Außerdem lässt sich eine WP-Installation ja auch relativ schnell umsetzen. Nachteil ist halt das Einloggen (wobei hier kann Roboform aushelfen) sowie das mehrfache Aktualisieren der PlugIns.

    Viele Grüße,
    Julian

  2. Also ich bin von MultiSite immer noch begeistert. Schon bei zwei WP-Installationen fand ich das Updaten der Plugins nervig, wobei ich eben auch manche Plugins gepatcht habe und deswegen nicht einfach im Backend auf den Update-Button drücke. Mit MultiSite mache ich das nun nur noch einmal. Ich habe bisher auch kaum Plugins gefunden, die damit nicht funktionieren. Aufpassen muss man vor allem dann, wenn das Plugin DB-Tabellen erstellt, wobei selbst das gehen sollte, wenn es die normale API benutzt.

  3. Ich habe eine Multisite Installation mit Unterordner.
    In der header.php des Templates habe ich folgendes Script:


    SCMMusicPlayer.init("{'skin':'skins/aquaBlue/skin.css','playback':{'autostart':'false','shuffle':'false','volume':'50'},'playlist':'http://www.radiofr.ch/fileadmin/rss/DE/unimix.rss','placement':'top','showplaylist':'false'}");


    Auf dem 2. möchte ich jedoch ein anderes RSS Feed wiedergeben.
    Wie muss ich den PHP Code anpassen, damit es mir jeweils nur das entsprechende Script wiedergibt? Bin leider nicht so der PHP-Hecht. 🙁

  4. Schritt Nummer 1 wäre, die URL des Feeds in eine PHP-Variable auszulagern und diese dann an der entsprechenden Stelle in das Script einzufügen. Und dann ist noch die Frage, wie Du abhängig von der Seite, auf der Du Dich befindest, eine andere URL in die Variable bekommst. Wenn es sich um wenige Seiten handelt, dann mach das doch so wie ich es oben unter „Anpassungen an Themedateien“ beschrieben habe. Mit if else die Seiten durchgehen und für jede die entsprechende URL setzen. Falls Dein Blog-Netzwerk sehr viele Seiten enthält, kannst Du natürlich auch eine Lösung bauen, die die URL zum Beispiel in der Options-Tabelle speichert.

  5. Hi Johannes, vielen Dank für die Anleitung. Leider klappt die erste Variante bei mir nicht. Ich habe zwei Seiten als Multisite eingerichtet (www-unity-yoga.de und http://www.unity-training.de) Jetzt soll im Template oben rechts je nach Seite ein anderer Slogan stehen.

    Dementsprechend habe ich in der Functions.php folgendes angelegt:
    function abc_is_unity_yoga() {
    global $blog_id;
    $blog_details = get_blog_details($blog_id, false);
    return (strpos($blog_details->domain, ‚unity-yoga‘) === 0);
    }

    function abc_is_unity_training() {
    global $blog_id;
    $blog_details = get_blog_details($blog_id, false);
    return (strpos($blog_details->domain, ‚unity-training‘) === 0);
    }

    Und im header.php eine Abfrage erstellt mit

    Hier der Slogan von Unity Yoga

    Hier der Slogan von Unity Training

    Er nimmt allerdings uaf beiden Seiten die ELSE-Variante, d.h. abc_is_unity_yoga() oder auch abc_is_unity_traing() scheint immer false zu sein.

    Hast Du eine Idee? Ach ja , ich nutze WP 3.6

  6. Oh, die header.php Daten sind gelöscht worden – klar ist ja php 😉 Nun also ohne die PHP-Klammern

    if ( abc_is_unity_yoga() ) :
    Hier der Slogan von Unity Yoga
    else:
    Hier der Slogan von Unity Training
    endif;

  7. Wie schon per E-Mail gesagt würde ich vermuten, dass Du in Deinem Check der Domain das „www.“ nicht unterschlagen darfst. Das kannst Du mit einer simplen Ausgabe der $blog_details herausfinden. Und ja, man kann natürlich auch auf die blog_id testen. Wenn man es in gut benannten Funktionen kapselt, mag das gehen. Auf jeden Fall sollte man nicht an zehn Stellen im Code auf blog_id == 4 testen, da weiß man nämlich bald nicht mehr, welche Seite damit gemeint ist.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Bitte beachte die Kommentarregeln: 1) Kein Spam, und bitte höflich bleiben. 2) Ins Namensfeld gehört ein Name. Gerne ein Pseudonym, aber bitte keine Keywords. 3) Keine kommerziellen Links, außer es hat Bezug zum Beitrag. mehr Details...

So, noch mal kurz drüber schauen und dann nichts wie ab damit. Vielen Dank fürs Kommentieren! :-)