So entwickelst du WordPress-Themes, die die User personalisieren können
Über die Funktion „Anpassen“ im Menü „Design“ findet sich der WordPress-Theme-Customizer. WordPress-Nutzer können hier Änderungen am verwendeten Theme vornehmen, zum Beispiel ein Hintergrundbild festlegen. Das Tolle daran ist: Nach dem automatischen Neuladen der Vorschau erscheint das Hintergrundbild direkt – der User bekommt also eine Live-Vorschau geboten.
Der Theme Customizer enthält – abhängig von den vom jeweiligen Theme unterstützten Features – bereits einige Auswahlmöglichkeiten, wie etwa das Anpassen des Titels und Untertitels. Wer seine Themes anderen WordPress-Nutzern zur Verfügung stellen möchten, wie etwa über das WordPress Theme Directory, kann aber noch mehr aus dem Theme Customizer herausholen. Wie ihr weitere und auf euer Theme zugeschnittene Lösungen für den Theme Customizer schreiben könnt, werde ich euch hier an einem Beispiel zeigen.
WordPress-Theme-Customizer: Mehr Freiheiten für Theme-Nutzer
Wir werden den Theme Customizer anhand eines bereits bestehenden Themes von mir durchgehen und dabei zunächst einen Color-Picker einbauen, über den Theme-Nutzer die Farbe des Designs ändern können. Mittels Checkboxen geben wir ihnen danach die Wahl, ob sie Share-Buttons im Blogview und/oder im Singleview anzeigen möchten und ob eine Autoren-Beschreibung unter den Beiträgen erscheinen soll. In einem dritten Schritt ermöglichen wir es, zusätzlich zu der Standard-Funktion, dass ein Header-Bild ausgewählt werden kann, auch die Größe des Bildes festzulegen. Dabei gibt es mit radio-Buttons die Wahl zwischen drei Optionen: Standard, das Bild füllt den ganzen Header aus oder das Bild füllt den Header nur in der Höhe aus. Zuletzt nutzen wir Eingabefelder, um den Copyright-Text des Themes anzupassen, den Button für die Sidebar mit einem eigenen Text zu ersetzen und CSS zu ergänzen.
Damit sollten wir die meisten Input-Typen haben und gehen jetzt in die Programmierung. Es gibt dabei eigentlich nur zwei WordPress-Hooks, die wir nutzen müssen: Das ist einmal customize_register
, der uns erlaubt neue Kategorien, Einstellungen und Bedienelemente zu definieren. Und zweitens müssen wir wp_head
nutzen, um – je nachdem, welche Optionen im Theme Customizer gewählt sind – das passende CSS in den Head-Bereich der Website zu bekommen.
Erstellen wir also zuerst eine Funktion, die wir dann an den Hook customize_register
anhängen:
function t3n_customize_register( $wp_customize ) {
}
add_action( 'customize_register', 't3n_customize_register' );
Und jetzt starten wir einfach mal mit einem Sprung ins kalte Wasser, nämlich mit dem gesamten Code für die Design-Farbe, der in die Funktion t3n_customize_register
gehört:
$wp_customize->add_setting(
'design_color', array(
'default' => '#27ae60'
);
$wp_customize->add_control(
new WP_Customize_Color_Control(
$wp_customize, 'design_color', array(
'label' => __('Main Color of the Design', 't3n'),
'section' => 'colors',
'settings' => 'design_color')
)
);
Das wars auch schon. Wie ihr seht, besteht der Code aus zwei Bereichen: Zuerst muss WordPress mitgeteilt werden, dass es eine neue Einstellung gibt. Dazu nutzen wir die Methode add_setting
, die wir an $wp_customize
übergeben. Innerhalb von add_setting
legen wir zuerst eine id für die Einstellung fest: design_color
. In dem nachfolgenden Array vergeben wir einen Standard-Wert. Genauere Informationen zu add_section
gibt es im WordPress Codex.
Jetzt müssen wir die Einstellung natürlich auch noch erreichbar machen, also eine Interaktions-Möglichkeit für den Nutzer schaffen. Das funktioniert mit der Methode add_control
. Da wir hier mit dem Color-Picker einen Sonderfall haben und nicht die standardmäßig verwendete Klasse WP_Customize_Control
verwenden können, müssen wir eine der anderen bereitgestellten Klassen verwenden. Wir erstellen also nun eine neue Instanz der Klasse WP_Customize_Color_Control
, die für Color-Picker zuständig ist.
Als Argumente übergeben wir zuerst $wp_customize
und anschließend den Namen, den ich hier der Einfachheit halber identisch mit der id der Einstellung gewählt habe. In dem nun folgenden Array vergeben wir eine Beschriftung des Controllers, den Bereich, in dem es erscheinen soll – colors
ist ein von WordPress bereits vorgehaltener Bereich, in dem auch die Farbe für Text und Header erscheint – und den Einstellungs-Wert, in dem es gespeichert werden soll. Das ist die id der Einstellung, hier also design_color
. Damit sollte die Einstellung schon im Theme Customizer angezeigt werden – wie wir die Änderungen dann wirklich ins Theme bringen, dazu kommen wir später.
Widmen wir uns jetzt genau wie eben den Optionen für den Inhalt, also den Teilen-Buttons und der Autoren-Box. Da diese alle gleich aufgebaut sind, und sich nur in dem Standard-Wert und der Beschriftung unterscheiden, wäre es doch schade, wenn wir die Einstellung und die Schaltflächen dreimal mit fast demselben Inhalt definieren müssten. Deshalb nutzen wir hier eine foreach-Schleife in Verbindung mit einem Array, um uns etwas Arbeit zu ersparen:
$contents = array();
$contents[] = array(
'slug'=>'share_btns_blogview',
'default'=>1,
'label' => __( 'Share Buttons in the blog view', 't3n' )
);
$contents[] = array(
'slug'=>'share_btns_singleview',
'default'=>1,
'label' => __( 'Share Buttons in the single view', 't3n' )
);
$contents[] = array(
'slug'=>'author_bio',
'default'=>1,
'label' => __( 'Diplay the Author Bio in the single view also on a single-author blog.', 't3n' )
);
foreach( $contents as $content ) {
$wp_customize->add_setting( $content['slug'], array(
'default' => $content['default'],)
);
$wp_customize->add_control( $content['slug'], array(
'settings' => $content['slug'],
'label' => $content['label'],
'section' => 'content',
'type' => 'checkbox')
);
}
$wp_customize->add_section('content' , array(
'title' => __('Content','t3n'),
'priority' => 1)
);
Zuerst kreieren wir ein Array $contents
, in das wir anschließend alle Werte eintragen, die wir für Einstellung und Schaltfläche benötigen. Das ist der Bezeichner, den wir dann auch als id verwenden werden, der Standard-Wert und die Beschriftung. Anschließend füllen wir add_setting
und add_control
innerhalb der foreach-Schleife, indem wir das Array durchlaufen und die Werte auslesen.
Als Bereich weisen wir in add_control
diesmal content
zu, und als Typ wählen wir checkbox
. Da der Bereich content
nicht – wie etwa colors
und ein paar weitere – von WordPress vorgehalten wird, müssen wir uns diesen schnell selbst erstellen. Das geht mit add_section
, dem die id, in unserem Fall content
, mitgegeben wird, sowie in einem Array mindestens der Titel des Bereichs. Die id muss mit dem Wert übereinstimmen, der bei add_control
als section
-Wert zugewiesen wird. priority
ist eine optionale Angabe – damit könnt ihr die Reihenfolge der Bereiche verändern, in der sie im Theme Customizer angezeigt werden. Je höher der Wert ist, desto tiefer wird der Bereich in der Liste angeordnet.
Verschiedene Darstellungsmöglichkeiten für das Header-Bild
Kümmern wir uns als nächstes um die Einstellungsmöglichkeiten für das Header-Bild, das bei meinem Theme als Hintergrundbild zum Einsatz kommt:
$wp_customize->add_setting(
'background_size', array(
'default' => 'standard')
);
$wp_customize->add_control($background['slug'], array(
'label' => __( 'Change the Size of the Header Background Image', 't3n' ),
'section' => 'header_image',
'settings' => 'background_size',
'type' => 'radio',
'choices' => array(
'standard' => 'Standard',
'cover' => __('The Image fills out the whole header', 't3n'),
'height' => __('100% Height, Auto Width', 't3n'),
),
));
Die einzige Neuerung findet sich hier im add_control
-Part: Die Option wird dem Bereich header_image
zugewiesen, den es bereits von WordPress aus gibt, und der Typ wird auf radio
gestellt. Damit jetzt gewählt werden kann, müssen dem Array-Index choices
mittels eines neuen Arrays die verschiedenen Möglichkeiten übergeben werden. Die Indizes standard
, cover
und height
werden später in dem Theme genutzt, um die gewählten Fälle zu unterscheiden.
Wenden wir uns als nächstes dem Copyright-Text und – da es bei Beidem keine wahnsinnigen Neuerungen mehr für uns gibt – auch gleich dem Sidebar-Button zu, die beide mittels eines normalen input-Feldes geändert werden können:
$wp_customize->add_setting(
'copyright', array(
'default' => '')
);
$wp_customize->add_control(
'copyright', array(
'label' => __('copyright', 't3n'),
'section' => 'content',
'settings' => 'copyright')
);
$wp_customize->add_setting(
'sidebar_btn', array(
'default' => '')
);
$wp_customize->add_control(new t3n_Customize_Input_Control($wp_customize, 'sidebar_btn', array(
'label' => __('Replace the Sidebar Button with your text', 't3n'),
'section' => 'content',
'settings' => 'sidebar_btn')
));
Was habe ich gesagt? Alles kein Problem mehr. Beides wird noch unter dem vorhin erstellten Bereich content
eingeordnet und als Standardwert einfach ein leerer String übergeben. Den Typ des Feldes haben wir nicht explizit angegeben, weil der automatisch genutzte Typ text
genau richtig für uns ist.
Theme-Nutzern CSS-Anpassungen ermöglichen
Jetzt wird es aber doch noch mal etwas interessanter: Wir wollen ja ein Textfeld einbauen, in dem der Nutzer eigenes CSS platzieren kann. Dafür brauchen wir eine Textarea, die aber von WordPress nicht als Typ bereitgestellt wird. Hier müssen wir also selbst Hand anlegen und einen eigenen Typ erstellen, und das sieht im Gesamten so aus:
class t3n_Customize_Textarea_Control extends WP_Customize_Control {
public $type = 'textarea';
public function render_content() {
?>
<label>
<textarea style="width: 100%;" rows="5">link(); ?>><?php echo esc_textarea( $this->value() ); ?></textarea>
</label>
<?php
}
}
$wp_customize->add_setting(
'custom_css', array(
'default' => '')
);
$wp_customize->add_control(new t3n_Customize_Textarea_Control($wp_customize, 'custom_css', array(
'label' => __('Custom CSS', 't3n'),
'section' => 'css',
'settings' => 'custom_css')
));
$wp_customize->add_section('css' , array(
'title' => __('CSS','t3n'))
);
Der einzig wirklich neue Teil steht gleich am Anfang. Wir müssen die Klasse WP_Customize_Control
um unsere eigene Klasse t3n_Customize_Textarea_Control
erweitern. Wir definieren darin den Typ textarea
und überschreiben anschließend die Funktion render_content()
, um eine Textarea darzustellen. Hierbei ziehen wir uns mit $this->label
die Beschreibung des Feldes, mit $this->link()
alle weiteren Informationen, die der Theme Customizer benötigt, wie etwa das name
-Attribut und über $this->value()
geben wir schließlich den Inhalt aus. esc_textarea()
ist für die Formatierung des Textes da. Anschließend müssen wir bei add_control
wieder eine neue Instanz einer WP_Customize_Control
-Klasse – hier unsere vorher definierte Klasse t3n_Customize_Textarea_Control
– erstellen, wie ganz am Anfang bei den Farben auch. Zum Schluss müssen wir noch den Bereich css
erstellen, in dem die Einstellungs-Möglichkeit erscheinen soll.
Aus dem Theme Customizer und der Funktion t3n_customize_register()
können wir uns jetzt zurückziehen – wir haben alle Einstellungen vorgenommen, die für die Eingabe und Speicherung der Werte von Nöten sind. Schön wäre es jetzt natürlich, wenn die Einstellungen auch eine Auswirkung auf das Theme haben.
WordPress-Theme-Customizer: Die Anpassungen sichtbar machen
Dazu nutzen wir im Fall von CSS-Anpassungen eine weitere Funktion, die wieder in die functions.php
gehört. Diese geben wir dann dem Hook wp_head
mit, und das sieht (CSS gekürzt, was ja von Theme zu Theme unterschiedlich ist) im Ganzen so aus:
function t3n_insert_custom(){
$text_color = get_header_textcolor();
$header_image = get_header_image();
$design_color = get_theme_mod('design_color');
$background_size = get_theme_mod( 'background_size' );
?>
<style>::selection {background:<?php echo $design_color ; ?>;color: #fff;}
<?php echo get_theme_mod( 'custom_css');?>
</style>
<style>
<?php
if ( ! display_header_text() ) :
?>
.site-title,
.site-description {
position: absolute;
clip: rect(1px 1px 1px 1px); /* IE7 */
clip: rect(1px, 1px, 1px, 1px);
}
#branding{
height:122px;
}
<?php
if ( empty( $header_image ) ) :
?>
.site-header .home-link {
min-height: 0;
}
#branding{
height:0px;
}
<?php
endif;
elseif ( $text_color != get_theme_support( 'custom-header', 'default-text-color' ) ) :
?>
.site-title a,
.site-description {
color: #<?php echo esc_attr( $text_color ); ?>;
}
<?php endif; ?>
<?php if ( ! empty( $header_image ) ) : ?>
background:url('<?php echo esc_url( $header_image ); ?>') no-repeat 50% 0;
<?php if($background_size =='cover'){ ?>
background-size:cover;
<?php }elseif($background_size =='height'){ ?>
background-size:auto 100%;
<?php } ?>
<?php endif; ?>
</style>
<?php
}
add_action('wp_head', 'fanoe_insert_custom');
Am Anfang holen wir uns alle Angaben, die wir brauchen – das sind in unserem Fall die Farbe der Header-Texte, die standardmäßig geändert werden können, sofern es mit get_theme_support
nachgerüstet ist, das Header-Bild, die Design-Farbe und die Einstellung für das Header-Hintergrundbild. Für Text-Farbe und Bild nutzen wir die vorgefertigten WordPress-Funktionen, bei der Design-Farbe und dem Header-Bild holen wir uns den Wert mittels der Funktion get_theme_mod
, der wir die id des Wertes, also bei der Design-Farbe design_color
und bei dem Header-Bild background_size
übergeben.
Das funktioniert so in jeder Theme-Datei, weshalb wir auf die Funktion gleich noch einmal zurückkommen werden, wenn es um die weiteren Anpassungen geht, die nicht mit CSS zu tun haben. Nach den Variablendeklarationen folgt ein CSS-Block, in dem alle Werte überschrieben werden, die die Standard-Design-Farbe festlegen. Vor dem Schließen des Style-Tags bringen wir hier auch noch das CSS unter, das vom Nutzer selbst eingetragen wurde.
Jetzt folgt etwas CSS, womit der Text im Header versteckt wird, falls im Theme Customizer eingestellt. Wenn zusätzlich auch kein Header-Image ausgewählt ist, wird die Höhe des Headers auf Null gesetzt. Wenn der Text angezeigt werden soll, die festgelegte Farbe aber nicht mit der Standardfarbe übereinstimmt, wird auch das im CSS geändert. Es folgt noch ein Block, der die Einstellungen für das Header-Bild übernimmt: Wenn ein Bild gewählt ist, wird es dem Tag mit der id branding
als Hintergrund zugewiesen und zentriert. Wenn dann die Option gewählt ist, dass es den gesamten Header ausfüllen soll (besitzt die id cover
), dann wird dem CSS ein background-size:cover;
hinzugefügt. Soll es stattdessen nur die Höhe ausfüllen, wird background-size:auto 100%;
eingesetzt. Anschließend wird die Funktion an den Hook wp_head
übergeben.
Schauen wir uns nun an, wie wir die Social-Media-Buttons und die Autoren-Box verstecken können. Es läuft immer nach demselben Schema ab: Wir prüfen mit get_theme_mod('id-der-einstellung')
, ob eine Einstellung einen bestimmten Wert hat, und reagieren entsprechend. Beispielhaft steht folgender Code in der content-aside.php
, um die Share-Buttons zu verstecken, falls gewünscht:
$share_btns_blogview = get_theme_mod( 'share_btns_blogview' ); if($share_btns_blogview == 0){}else{ ?>
//hier folgt die ul-Liste mit den Share-Buttons
<?php }
Der Zustand einer Checkbox ist entweder 1
oder 0
. Wir prüfen also nur, ob die Checkbox nicht ausgewählt ist – dann machen wir nichts – oder wir stellen die Liste dar, wenn der Haken gesetzt ist (was bei uns standardmäßig der Fall ist). Diesen Code baut ihr jetzt einfach entsprechend überall ein, wo ihr die Social-Media-Buttons verwendet oder – was um einiges besser ist – ihr packt den Code in eine Funktion in die functions.php
und schreibt in die Theme-Dateien nur noch den Funktionsaufruf. Um die anderen zwei Optionen im Theme zu nutzen, wählt ihr einfach als Parameter die entsprechenden ids, also für die Social-Media-Buttons in der Einzelansicht share_btns_singleview
und für die Autoren-Beschreibung in Blogs mit nur einem Autor könnt ihr author_bio
verwenden.
Jetzt fehlen nur noch der Sidebar-Button und das Copyright. Beginnen wir mit dem Copyright-Hinweis:
<p><?php $copyright = htmlspecialchars_decode(get_theme_mod( 'copyright' ));
if($copyright !=''){
echo $copyright;}
else{?>© <?php echo date('Y'); ?> <?php bloginfo( 'name' ); ?>
<?php }?></p>
Zuerst holen wir uns wie gewohnt die Inhalte, die in das Feld eingetragen wurden – dabei stellen wir mit htmlspecialchars_decode
sicher, dass eventuell eingetragenes HTML auch wieder als HTML ausgegeben wird. Wenn das Feld nicht leer ist, dann wird einfach der Inhalt ausgegeben. Ist nichts eingetragen, wird das Copyright-Zeichen, das aktuelle Jahr und der Name des Blogs ausgegeben.
Die Anpassung des Sidebar-Buttons folgt dem gleichen Prinzip:
<a class="sidebar-button<?php $sidebar_btn = get_theme_mod( 'sidebar_btn' );
if ($sidebar_btn != ""){
echo " text";
}else{
echo " stripes";}?>"
href="#sidebar-menu">
<?php if ($sidebar_btn != ""){
echo $sidebar_btn;
}else{?>?<!--?php }?>
</a>
Wir holen uns zuerst wieder den Wert und geben – je nachdem, ob das Feld leer ist oder nicht – dem Link-Tag eine zusätzliche Klasse mit. Anschließend wird, wenn etwas eingetragen ist, der Wert ausgegeben. Andernfalls geben wir das Äquivalent-Zeichen aus.
Das müsste es soweit gewesen sein. Habt ihr Fragen zum Einsatz des Theme Customizers in WordPress oder Anregungen, wie man etwas noch eleganter lösen kann? Dann freue ich mich über eure Kommentare!
Wer mehr wissen möchte oder auf der Suche nach weiteren Tutorials und Anleitungen ist, sollte sich den Abschnitt zum WordPress-Theme-Customizer im WordPress Codex anschauen.
Sehr informativer Artikel. Für den unerfahrenen Nutzer ist die Einbindung eines Frontend-Editors mit Drag&Drop Funktionalität künftig sehr interessant. Einige sind bereits kostengünstig auf dem Markt. Damit lassen sich leicht verschiedene Designs erstellen..
Sehr coole Anleitung, vielen Dank dafür! Wie kann ich denn jetzt zusätzlich dazu, dass der Kunde ein Bild individuell im WP Customizer festlegen/hochladen kann, noch zusätzlich für dieses gewählte Bild weitere Einstellungen einblenden/möglich machen, wie z. B. background-position, repeat und Co.? Ich möchte, dass der Kunde z. B. ein Bild als Hintergrund hochladen und entscheiden kann, ob das Bild über die ganze Breite, rechts oben oder z. B. links unten angezeigt werden soll, also ganz individuell bearbeiten kann …