TinyMCE zur Bearbeitung von Mediendateien

Alle sagen es geht nicht bis einer kommt und es einfach macht. So ging es mir bei diesem G+ Post. Das Problem ist einfach umrissen: In der Medienübersicht wird der Standard-Editor zur Bearbeitung der Medienbeschreibung verwendet. Der Wunsch war jedoch den TinyMCE dafür einzusetzen. Normalerweise reicht es dafür aus einen Filter auf die Editor-Einstellungen zu verwenden und das Flag für den TinyMCE auf True zu setzen.

Wir haben im Prinzip drei Möglichkeiten um die Editor-Einstellungen zu beeinflussen. Zum einen dann wenn sie definiert werden.

$editor_args = array(
	'textarea_name' => 'content',
	'textarea_rows' => 5,
	'media_buttons' => false,
	'tinymce' => false,
	'quicktags' => $quicktags_settings,
);

$editor_args = apply_filter( 'some_filter', $editor_args );

Leider ist dies nicht immer möglich, vor allen Dingen im gegebenen Fall nicht. Leider bietet auch die verwendetet Funktion wp_editor() noch die die Klasse _WP_Editors einen entsprechenden Filter an. Warum das so ist, sei mal dahingestellt. Ebenso das es bereits diverse Tickets im Trac zu den Thema gibt. Wenn man sein Ziel nicht auf direkten Weg erreichen kann, dann muss man manchmal einen kleinen Umweg gehen.

Eine Lösung wäre, wenn die Funktion wp_editor() plugable wäre, man sie also gegen eine eigene Funktion austauschen kann. Ist sie aber nicht, muss man den Hebel also woanders ansetzen.

Im betreffenden Fall wurde angeregt in der Klasse einen zusätzlichen Filter einzubauen. Bis dies umgesetzt ist, muss man sich also mit einen kleinen Workaround behelfen.
Wirft man einen Blick in den Code, so sieht man das abgefragt wird ob die Klasse _WP_Editors bereits geladen wurde. Nur wenn sie nicht geladen wurde, wird die Klasse aus dem WordPress-Core geladen. Für uns bedeutet dies also, wir können die Original-Klasse durch eine gleichnamige eigene Klasse ersetzen. Wir müssen nur dafür sorgen das unsere Klasse möglichst früh geladen wird. Am einfachsten erreicht man dies indem man einen der sehr früh ausgelösten Hooks benutzt um die eigene Klasse mittels require_once()/include_once() einzubinden.

Wie man sieht, gibt es in WordPress nicht nur eine Möglichkeit um etwas zu beeinflussen. Der einfachste Weg sind Filter und Actions um Variablen direkt zu beeinflussen. Sind diese nicht gegeben, schaut man sich an ob die betreffende Funktion etwas hergibt, also ob diese ggf. einen Filter/Action besitzt oder ob man sie ersetzen kann. Ist dies auch nicht gegeben, so kann man, wie hier im Beispiel, noch eine letzte Chance nutzen und eine Klasse komplett austauschen.

Der erste Schritt zum Plugin besteht also darin die Klasse _WP_Editors komplett in sein Plugin-Ordner zu kopieren. Der nächste Schritt ist das Einbinden der kopierten Klasse:

/**
 * Including the modified WP class _WP_Editors
 */
add_action(
	'plugins_loaded',
	function() {
		require_once dirname( __FILE__ ) . '/class-wp-editor.php';
	},
	0,
	0
);

Um zu überprüfen ob nun die kopierte oder die Original-Klasse geladen wird, kann man am Anfang der Kopie einfach mal ein die( 'Kopierte Klasse' ); setzen. Bricht WordPress nach einem Neuladen mit einen weißen Bildschirm ab auf dem nur “Kopierte Klasse” steht, so können wir sicher sein das nur unsere kopierte Klasse geladen wird. Nun geht es daran die kopierte Klasse zu modifizieren. Wie im Ticket vorgeschlagen ergänzen wir die Klasse um einen zusätzlichen Filter.

Da wir nun in der kopierten Klasse einen Filter haben den wir nutzen können, reicht es aus diesen zu setzen und in einer passenden Funktion die Werte entsprechend zu ändern.

/**
 * Add the filter to modify the editor settings
 */

add_filter( 'wp_editor_settings', 'modify_editor_settings', 0, 2 );

/**
 * Modify the editor settings. Currently only set the value for using the TinyMCE to true.
 *
 * @param array $settings Array with editor settings
 * @param array $editor_id The ID of the editor
 * @return array
 */
function modify_editor_settings( $settings, $editor_id ) {

	if ( 'attachment_content' == $editor_id )
		$settings['tinymce'] = true;

	return $settings;

}

Ich habe hier bewusst auf umständliche Prüfungen verzichtet um das Beispiel einfach zu halten. Man könnte zusätzlich darauf prüfen ob man sich auch tatsächlich in der Medienübersicht bzw. Medienbearbeitung befindet. Es wird lediglich geprüft ob die Editor-ID attachment_content ist und dann das Flag für den TinyMCE auf true gesetzt.
Durch Anpassung der Funktion modify_editor_settings() lässt sich so der TinyMCE für nahezu alle Eingabefelder aktivieren sofern die Editor-ID bekannt ist und das Eingabefeld über die Funktion wp_editor() erzeugt wird.

Das Plugin ist recht wartungsfreundlich. Sollte eines Tages ein Filter zum Modifizieren der Editor-Einstellungen vorhanden sein, so muss man nicht das komplette Plugin neu konstruieren. Es reicht aus die Einbindung der eigenen Klasse zu entfernen und ggf. den Filter-Namen anzupassen.