Jedes WordPress-Theme enthält ein CSS-Stylesheet, welches die Formatierung für alle Posts und Pages einheitlich festlegt (z.B. Hintergrundfarben, Schriftgrößen oder Abstände). Manchmal ist es jedoch erwünscht, bestimmte Posts (bzw. Pages) individuell gestalten zu können. In meinem Blog "Blaustern Fotografie" wollte ich z.B. die Hintergrundfarbe der Menüleiste am oberen Rand der Seite für jeden Post individuell anpassen. Um diese Funktionalität zu erhalten, habe ich ein Plugin entwickelt, welches folgende Merkmale besitzt:
- Das Plugin ergänzt im Admin-Bereich neben dem Editor eine Meta-Box.
- Die Meta-Box enthält einen Color-Picker, der die Auswahl eines Farbwertes ermöglicht.
- Des Weiteren enthält die Meta-Box einen Button, der die Media-Library öffnet, sodass ein Foto ausgewählt werden kann. Der Nutzer kann eine beliebige Stelle in dem Foto anklicken, um den Farbwert an dieser Stelle in den Color-Picker zu übernehmen.
- Die ausgewählte Farbe wird in den Meta-Daten des jeweiligen Posts abgespeichert. Beim Anzeigen des Posts wird die gewählte Farbe der Menüleiste als Hintergrundfarbe zugewiesen.
Die Farbe der Menüleiste lässt sich so z.B. auf das Featured-Bild des Posts abstimmen. Ein Beispiel finden Sie in meinem Post "Blühende Brennnesseln".
Im Folgenden werde ich die Schritte zur Entwicklung dieses Plugins erläutern. Die Vorgehensweise lässt sich abwandeln, um andere CSS-Eigenschaften bzw. andere Seitenelemente zu konfigurieren.
1. Vorbereitung der Meta-Box
Mein neues Plugin nenne ich 'specific_colors'. Zuerst lege ich einen neuen Ordner mit diesem Namen an. In dem Ordner erstelle ich eine neue php-Datei 'specific_colors.php'. Für den Aufbau dieser Datei gibt es einige Konventionen, auf die ich nicht näher eingehen werde (es geht u.a. um Lizenzinformationen und Namenskonventionen). Wenn Sie aber vorhaben, ein Plugin zu veröffentlichen, beachten Sie bitte die Hinweise im WordPress Codex.
In die PHP-Datei füge ich Quellcode ein, um im Admin-Bereich eine neue Meta-Box anzulegen:
<?php
add_action( 'add_meta_boxes', 'specific_colors_add_custom_box' );
function specific_colors_add_custom_box($type) {
add_meta_box('specific_colors_box', 'Specific Colors',
'specific_colors_inner_box', $type, 'side', 'core');
}
function specific_colors_inner_box(){
?>
<p>
<label>Color value for the navigation bar:<label>
<input class="meta-color-picker" name="meta-color-nav" id="meta-color-nav" type="text"
value="<?php echo esc_attr( get_post_meta( get_the_ID(), 'meta-color-nav', true ) ); ?>"/>
</p>
<?php
}
?>
In der ersten Zeile teile ich WordPress mit, dass bei der WordPress-Aktion 'add_meta_boxes' meine Funktion 'specific_colors_add_custom_box' ausgeführt werden soll. Diese Funktion habe ich darunter definiert. Sie ruft die WordPress-Funktion 'add_meta_box' aus. Als Parameter übergebe ich
- eine eindeutige ID,
- die anzuzeigende Überschrift der Meta-Box,
- den Namen einer Callback-Funktion, die aufgerufen werden kann, um den HTML-Code für den Inhalt der Box zu erhalten,
- den Post-Typ (spielt für mich keine Rolle, ich reiche einfach das Argument $type weiter),
- die gewünschte Position der Box (hier kann man zwischen 'normal', 'advanced' oder 'side' wählen),
- die Priorität der Box ('high', 'core', 'default', or 'low'), die Einfluss auf die Reihenfolge der Meta-Boxen hat.
Den HTML-Code für den Boxinhalt spezifiziere ich in der Funktion 'specific_colors_inner_box'. Auf die einzelnen Bestandteile gehe ich in den folgenden Abschnitten ein.
Noch ein Hinweis zum PHP-Code: Nach dem "?>" am Ende der Datei dürfen keine Leerzeichen oder Leerzeilen mehr folgen, sonst scheitert die Ausführung des Plugins! Stellen Sie das ggf. sicher, indem Sie im Editor den Cursor nach dem ">" platzieren und einige Sekunden lang die "Entf"-Taste drücken. Außerdem empfiehlt es sich, im Editor die Kodierung "UTF-8 ohne BOM" einzustellen.
2. Integration des Color-Pickers
WordPress enthält bereits einen Color-Picker, der mit Javascript-Code initialisiert werden kann. Ich lege dazu im gleichen Ordner eine neue Datei "specific_colors.js" an und füge folgenden Code ein:
jQuery(document).ready(function(){
$('.meta-color-picker').wpColorPicker();
}
Die WordPress-Funktion "wpColorPicker" kann auf einem beliebigen Input-Element aufgerufen werden. Ich lege fest, dass der Color-Picker bei dem Input-Element mit der Klasse "meta-color-picker" initialisiert wird (vgl. obige Funktion 'specific_colors_inner_box').
Die Funktion 'wpColorPicker' steht allerdings nicht ohne Weiteres zur Verfügung. In der PHP-Datei muss ich zunächst veranlassen, dass die von WordPress für den Picker benötigten CSS- und Javascript-Dateien beim Laden der Webseite vom Server mit ausgeliefert werden. Außerdem muss ich veranlassen, dass meine eigene Javascript-Datei "specific_colors.js" auch mit vom Server ausgeliefert wird:
add_action( 'admin_enqueue_scripts', 'specific_colors_add_picker' );
function specific_colors_add_picker(){
wp_enqueue_style( 'wp-color-picker' );
wp_enqueue_script( 'specific_colors_js',
plugin_dir_url( __FILE__ ) . 'specific_colors.js', array( 'wp-color-picker' ) );
}
In der ersten Zeile teile ich WordPress mit, dass bei der WordPress-Aktion 'admin_enqueue_scripts' meine Funktion 'specific_colors_add_picker' ausgeführt werden soll. In dieser Funktion veranlasse ich WordPress dazu, das Stylesheet 'wp-color-picker' in die Warteschlange zur Auslieferung an den Client einzureihen. Danach veranlasse ich WordPress dazu, mein eigenes Script mit einzureihen. Die ersten beiden Parameter spezifizieren dabei den Titel und den vollständigen Dateipfad des Scripts. Der dritte Parameter ist eine Liste von anderen Scripts, die vorher geladen werden müssen, weil mein Skript von ihnen abhängig ist (in diesem Fall das Script 'wp-color-picker').
3. Routine zum Speichern des gewählten Farbwertes
Ich möchte nun erreichen, dass der vom Nutzer eingestellte Farbwert beim Speichern des Posts mit abgespeichert wird. In WordPress werden zu jedem Post sogenannte Meta-Daten abgespeichert. Dazu gehören Angaben über den Post wie z.B. Autor, Kategorien oder Erstellungsdatum. Den Farbwert, der für den Post ausgewählt wurde, möchte ich in dem Bereich der Meta-Daten ablegen. Im PHP-Code ergänze ich folgendes:
add_action( 'save_post', 'specific_colors_save' );
function specific_colors_save($post_id){
if( isset( $_POST[ 'meta-color-nav' ] ) ) {
update_post_meta( $post_id, 'meta-color-nav', sanitize_text_field( $_POST[ 'meta-color-nav' ] ) );
}
}
Als erstes teile ich WordPress mit, dass beim Speichern eines Posts meine Funktion 'specific_colors_save' aufgerufen werden soll. In dieser Funktion greife ich auf das Array $_POST zu, welches alle Parameter enthält, die bei dem POST-Request zum Speichern der Blog-Seite an den Server gesendet werden. In diesem Array sind die Inhalte aller Formularelemente (z.B. Input-Felder) enthalten. Jedes Formularelement kann über seinen Namen erreicht werden, der im name-Attribut hinterlegt ist. Wie in Abschnitt 1 gezeigt, hat mein Input-Feld den Namen 'meta-color-nav', sodass sein Wert über diesen Namen abgefragt werden kann.
Die WordPress-Funktion 'update_post_meta' kann ich nun aufrufen, um für den aktuellen Post eine neue Meta-Eigenschaft 'meta-color-nav' (der Name kann prinzipiell frei gewählt werden) mit dem entsprechenden Wert zu hinterlegen.
Wenn die Blog-Seite erneut bearbeitet wird, soll der gespeicherte Farbwert natürlich wieder im Input-Feld angezeigt werden. Wie das funktioniert, ist bereits in der Funktion 'specific_colors_inner_box' im ersten Abschnitt zu sehen:
... value="<?php echo esc_attr( get_post_meta( get_the_ID(), 'meta-color-nav', true ) ); ?>"...
Mit der WordPress-Funktion 'get_post_meta' wird auf den Wert der Meta-Eigenschaft 'meta-color-nav' zugegriffen. Der Wert wird dem value-Attribut des Input-Felds übergeben.
Anmerkung: Theoretisch ist es nicht notwendig, einen Color-Picker zu verwenden, um Farbwerte einzutragen, abzuspeichern und wieder anzuzeigen. Es reicht aus, das Input-Feld in der Meta-Box bereitzustellen (d.h. Abschnitt 2 kann bei Bedarf übersprungen werden). Der Nutzer kann dort Farbwerte manuell eintragen. Der Color-Picker bietet lediglich die komfortablere Möglichkeit, Farbwerte durch Anklicken der Farbskala in das Input-Feld zu übertragen.
4. Routine zum Anwenden des Farbwertes als Hintergrundfarbe
Beim Öffnen einer Blog-Seite soll nun ein Inline-CSS-Stylesheet dynamisch generiert und an den Client gesendet werden. Das dynamische CSS enthält eine Anweisung, um die Hintergrundfarbe eines gewünschten HTML-Elements auf den in den Meta-Daten des Posts gespeicherten Farbwert zu setzen.
add_action( 'wp_enqueue_scripts', 'specific_colors_set_post_color' );
function specific_colors_set_post_color() {
$color = '#336600';
if(!is_front_page()){
$color = get_post_meta( get_the_ID(), 'meta-color-nav', true );
}
echo '
<style type="text/css">
.navigation{
background: '.$color.' !important;
}
</style>
';
wp_add_inline_style( 'custom-style', $custom_css );
}
Im Gegensatz zu den oben beschriebenen Funktionen verwende ich den Aktionsnamen 'wp_enqueue_scripts' anstelle von 'admin_enqueue_scripts', denn ich möchte in diesem Fall meine Skripts bzw. Styles nicht für die Admin-Ansicht, sondern für die Frontend-Ansicht bereitstellen.
Die CSS-Angaben müssen Sie natürlich individuell anpassen. Die Menüleiste besitzt in meinem Fall die Klasse 'navigation'. In Ihrem Fall muss sicherlich ein anderes Element selektiert werden - welche Klasse oder ID das gewünschte Element besitzt, müssen Sie ggf. erst mit den Browser-Entwicklerwerkzeugen (z.B. DOM-Inspector) herausfinden. Welche CSS-Eigenschaft Sie dann für das gewählte Element anpassen (in meinem Fall background), ist ebenso Ihnen überlassen. Die Angabe !important ist jedoch wichtig, da sonst ggf. andere, bereits im Theme enthaltene CSS-Angaben unsere Einstellungen wieder überschreiben.
Durch Aufrufen der Funktion 'wp_add_inline_style' kann das dynamisch generierte CSS an WordPress zur Auslieferung an den Client weitergereicht werden.
Für den Fall, dass ich mich auf der Startseite (front-page) des Blogs befinde, habe ich einen Standard-Farbwert vorgegeben.
Im zweiten Teil dieses Beitrags erläutere ich die Erweiterung des Plugins, damit ein Farbwert aus einem selbst gewählten Bild extrahiert werden kann.