Code Styling Project

It’s not a bug, it’s always a feature.
  • Deutsch
  • English
  • rss
  • Home
  • Blog
  • Impressum
  • Entwicklungen
  • Fehlerbehebungen
  • Anleitungen

Wie verwende ich WordPress Metaboxen in eigenen Plugins

codestyling | 22. Februar 2009 | 00:19

Mit dem Erscheinen der WordPress Version 2.7 wurden im Backend die Metaboxen geändert und können nun beliebig angeordnet oder auch ausgeblendet werden. Dies macht das Arbeiten mit dem Backend deutlich einfacher.
Jedoch wurde die nötigen Funktionen bisher nicht ausreichend dokumentiert, damit man das in eigenen Plugins verwenden kann. Ich versuche hiermit ein wenig Licht ins Dunkel zu bekommen, beschreibe die Funktionen ein wenig und stelle ein Beispiel-Plugin als Demonstration zum Download bereit.

Voraussetzungen

In meinen Ausführungen befasse ich mich nur mit WordPress ab Version 2.7, für ältere Versionen ist diese Beschreibung ungeeignet, denn die alten Versionen kennen diese Funktionen nicht in dieser Art.
Man könnte das zwar halbwegs kompatibel programmieren, das habe ich mir wegen der Übersichlichkeit aber gespart. Auch die gettext Fähigkeit des Demo-Plugins habe ich weggelassen, da dieses zum Artikel gehörende Plugin nur ein How To darstellt.

Funktionsbeschreibungen

Betrachten wir mal als Einstieg nötigen Funktionen, die WordPress bereitstellt. Hier die Definitionen:

PHP
1
2
3
4
5
function add_meta_box($id, $title, $callback, $page, 
                      $context = 'advanced', $priority = 'default')
 
function do_meta_boxes($page, $context, $object)
 
timing: 0.080s

Funktion: add_meta_box

Die Funktion add_meta_box(…) wird dazu verwendet, WordPress mitzuteilen, das man eine eigene Metabox bereitstellen möchte.
Der Parameter $id ist eine eindeutige Kennung der jeweiligen Metabox.
Mit $title gibt man an, was man als Titel in der Kopfzeile der Box haben möchte, es empfiehlt sich hier gettext basierten Text zu verwenden, damit sich die besser in anderen Sprachen übersetzen lässt.
Der Wert $callback erwartet eine Funktion, die von WordPress aufgerufen werden soll, wenn der Inhalt der Box ausgegeben werden soll.
Der Parameter $page beschreibt die Seite, in der die neue Box erscheinen soll. Somit kann man auch in fremden Plugin-Seiten Boxen einblenden lassen, wenn man deren verwendeten Parameter kennt.
Der Parameter $context wird verwendet, um Boxen nur in einem bestimmen Context ausgeben zu lassen. Meist wird diese zu Unterscheidung zwischen Content-Boxen und Sidebar-Boxen verwendet.
Mit Hilfe von $priority hat man die Möglichkeit, in begrenztem Maße auf die Reihenfolge der Boxen im entsprechenden Container zu reagieren. Zur Verfügung stehen: ‘high’, ‘core’, ‘default’, ‘low’.

Funktion: do_meta_boxes

Wenn man die Funktion do_meta_boxes(…) aufruft, führt das zur Ausgabe aller Metaboxen, die auf die angebenen Parameter passen und bisher registriert wurden. Der Parameter $object steht frei zur Verfügung, wenn man eigene Metabox-Seiten programmiert und ermöglicht die Weitergabe von Daten an die Callback Funktion, die den Inhalt der Box erstellen und ausgeben soll.

Callback Funktionen für Boxen-Inhalte

PHP
1
2
3
4
5
6
7
8
9
10
11
<?php function on_contentbox_1_content($data) {
	sort($data);
	?>
		<p>
			The given parameter at <b>sorted</b> order are: 
			<em><?php echo implode(' | ', $data); ?></em>
		</p>
	<?php
}
?>
 
timing: 0.064s

Im Beispiel wird als $object ein Array ($data Parameter) mit Strings übergeben, die dann in der Box ausgewertet werden können. Es steht jedem Programmierer frei, was er an die Callback für die Box-Inhalte weitergibt.
In der Seite “Artikel schreiben” zum Beispiel ist diese Objekt der Artikel als PHP Objekt selbst ($post).

Metabox Registrierung - der Zeitpunkt spielt eine Rolle

Man kann die Metaboxen zu 2 verschiedenen Zeitpunkten registrieren:

  1. wenn WordPress bekannt gibt, die Plugin-Seite laden zu wollen
  2. während der Ausgabe des Plugin Seiteninhalts

Der Unterschied des Zeitpunktes bestimmt, ob man die entsprechende Metabox über das Screen Options Menü ausblenden kann oder nicht. Boxen, die registriert werden während der Lade-Anforderung kann man auch bei Bedarf ausblenden. Wenn man die Box im 2. Falle erst während der Seitenausgabe - aber vor dem Aufruf von do_meta_boxes(…) - registriert, kann man diese Box nicht mehr ausblenden, sie ist immer auf der Seite verfügbar.
Man muss sich mit diesen Mechanismus nicht befassen, WordPress selbst sorgt dafür, das Metaboxen in dem Reiter Screen Options aufgenommen werden.

Javascript wird für Drag/Drop und Ausblenden benötigt

Wenn man bis hierher alles implementiert hat, wundert man sich, warum die Boxen nicht verschoben werden können, warum sich WordPress nicht merkt, welche davon ausgeblendet wurde und welche zugeklappt wurde. Dies liegt daran, daß man dafür natürlich noch für ein wenig Javascript Magic braucht und dafür sorgen muß.

PHP
1
2
3
4
wp_enqueue_script('common');
wp_enqueue_script('wp-lists');
wp_enqueue_script('postbox');
 
timing: 0.049s

Die o.g. Scripts müssen aufgenommen werden, damit das prinzipiell funktionieren kann. Allerdings muß man auch eine Initialisierung vornehmen, die meist in der Seite per inline Javascript geschieht:

Javascript
1
2
3
4
5
6
7
8
9
10
11
<script type="text/javascript">
	//<![CDATA[
	jQuery(document).ready( function($) {
		// close postboxes that should be closed
		$('.if-js-closed').removeClass('if-js-closed').addClass('closed');
		// postboxes setup
		postboxes.add_postbox_toggles('<?php echo $this->pagehook; ?>');
	});
	//]]>
</script>
 
timing: 0.007s

Screenshots des Beispiel-Plugins

Damit man sich das besser vorstellen und nachvollziehen kann, habe ich mal 2 Screenshots gemacht und diese hier verlinkt. Es zeigt die Demo-Plugin Seite mit und ohne eingeblendeter Screen Options Konfiguration:
 

Update: Anpassung an neues Box Modell in WordPress 2.8

Mit der kommenden Version 2.8 hat WordPress ein wenig die Funktionsweise der Metaboxen verändert und das System um Spaltenbezüge erweitert. Zur Verdeutlichung folgt nun ein Screenshot, der die neuen Möglichkeiten in der Einstellung demonstriert:

Dies macht es notwendig, darauf auch einzugehen, denn ohne diese zusätzliche Behandlung zeigt WordPress 2.8 keine rechte Sidebar für die Boxen an. Man benötigt als erstes einen neuen Filter:

PHP
1
2
3
4
5
6
7
8
9
add_filter('screen_layout_columns', array(&$this, 'on_screen_layout_columns'), 10, 2);
...
//for WordPress 2.8 we have to tell, that we support 2 columns !
function on_screen_layout_columns($columns, $screen) {
	if ($screen == $this->pagehook) {
		$columns[$this->pagehook] = 2;
	}
	return $columns;
}
timing: 0.050s

Innerhalb der Filteraufrufes muß man in das Array die Anzahl der unterstützten Spalten (in dem Falle 2 - Inhalt und rechte Sidebar) übergeben. Damit ist es aber noch nicht getan. Bei der Ausgabe der Metaboxen muß nun auf den aktuell eingestellten Wert Rücksicht genommen werden und eine zusätzliche HTML class Angabe in Abhängigkeit der aktuellen Spaltenanzahl geschrieben werden:

PHP
1
2
3
global $screen_layout_columns;
...
<div id="poststuff" class="metabox-holder<?php echo 2 == $screen_layout_columns ? ' has-right-sidebar' : ''; ?>">
timing: 0.048s

Nach diesen Anpassungen funktioniert das nun mit WordPress unter 2.7 und 2.8 ohne Probleme. Der unten angegebene Download ist bereits angepasst und im Quelltext dokumentiert.

Download des Beispiel-Plugins

Basierend auf den hier gemachten Beschreibungen habe ich zum besseren Verständnis das Ganze auch nochmal in ein Demo-Plugin verpackt, das einen Überblick geben soll, wie man das verwendet. Der Code ist GPL und kann benutzt werden frei nach eigenen Wünschen.
Wer diese Arbeit honorieren möchte, kann mich gern als Quelle in seinem Plugin erwähnen oder verlinken, ganz nach Belieben.

Hier das Demo-Plugin als Download: howto-metabox-plugin.zip (783 downloads)

Kategorien
Deutsch, WordPress (DE)
RSS Kommentare
RSS Kommentare

« PHPMailer in WordPress - warum fehlen Übersetzungen ? WordPress 2.8 ändert Sprachdatei-Zugriffe »

8 Antworten    Schreib einen Kommentar

Michael

Michael

22.02.2009 | 18:48

Ich nutze 2.7.x ja schon ein paar Tage, aber das man die boxen verschieben kann, ist mir heute nur zufällig aufgefallen, also eigentlich war es eher ein Versehen.

Antworten »

Sergej Müller

Sergej Müller

22.02.2009 | 20:23

Ich liebe deinen strukturierten und kommentierten Code, Heiko.

Ende 2008 hatte ich kurz überlegt, die superlange Liste mit wpSEO-Optionen in solche Boxen mithilfe dieser Technik zu verpacken. Hatte mich aber dagegen entschieden, da ich für ältere WordPress-Versionen eine Sonderbehandlung einführen müsste. Habe mich für eine statische Lösung entschieden, die vom optischen her identisch ist.

Antworten »

codestyling

codestyling

22.02.2009 | 20:37

Die gesonderte Behandlung für ältere Versionen mache normalerweise durch eine compatibility.php, die das Plugin nur dann lädt, wenn es feststellt, dass die Version kleiner als benötigt ist. Damit kann ich immer aktuell entwickeln und sorge dann nur per Datei Load für Kompatibilität. Das spart Nerven, erlaubt bessere Code Strukturierung und kann als 2. Schritt in der Entwicklung nachgeschoben werden. (Hab bisher die Abwärtskompatibilität immer erst im 1. Update erst nachgelegt, wenn nötig).

Antworten »

Sergej Müller

Sergej Müller

23.02.2009 | 10:23

Bei auf Grund neu entwickelten Plugins macht es durchaus Sinn, nach deinem Vorschlag zu gehen. Bei bestehenden müsste man mehr umbauen. Mit der Zeit will ich mein Plugin sowieso neu aufsetzen, da werden dann solche Dinge berücksichtigt.

Danke dir für den Artikel.

Antworten »

Tom

Tom

30.06.2009 | 11:35

Fuktioniert! Danke für die Erklärungen und Beispiele! :)

Antworten »

ocean90

ocean90

11.08.2009 | 18:47

Vielen Dank, sowas habe ich gesucht und nun bei dir gefunden.
Danke für das tolle Beispiel, damit versteh sogar ich es. :)

Gruß

Antworten »

ocean90

ocean90

30.08.2009 | 17:03

Hi,
auch wenn man andere Kommentar noch nicht freigeschaltet wurde, wollte ich mal fragen, wie das Gerüst aussehen muss, wenn man das Dashboard nachbauen möchte, also auch 4 Spalten nutzen möchte?

Danke im Vorraus.

Gruß

Antworten »

Jürgen Schulze

Jürgen Schulze

08.07.2010 | 16:56

Danke für die Meta-Box-Tipss.
Ich selbst benutze Meta-Boxen nicht nur bei den Settings, sondern auch in “Post” oder “Page”.
Einfach ein $page=’post’ und fertig.
Jürgen

Antworten »

Du kannst diese Tags verwenden : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Navigation

  • Allgemein
  • jQuery in WordPress
  • Politik
  • WordPress (DE)

Suche

Neuere Beiträge ...

  • PHP Funktion version_compare korrekt verwenden
  • Mathematische Finesse der Abwrack-Prämie
  • WordCamp Vortrag “Lokalisierung” als PDF Download
  • Permalinks mit Umlauten ohne o42-clean-umlauts
  • WordPress 2.8 ändert Sprachdatei-Zugriffe

Ältere Beiträge ...

  • PHPMailer in WordPress - warum fehlen Übersetzungen ?
  • PHP Funktion setlocale() … und Zahlen stimmen nicht mehr
  • prozentuale Angaben - was Browser meinen zu verstehen
  • WordPress Lokalisierung - Features und Weiterentwicklung
  • WordPress Kategorie-Baum Chaos in “Artikel bearbeiten”
rss RSS Kommentare valid xhtml 1.0 design by jide powered by Wordpress get firefox