toscho.design

WordPress: Aktuelle editor-style.css laden

TinyMCE, der visuelle Editor, kann vom Theme oder einem Plugin mit einem individuellen Stylesheet ergänzt werden. Dazu schreibt man in die functions.php:

add_editor_style();

Im Theme sollte eine Datei namens editor-style.css liegen. Für die RTL-Unterstützung können wir noch eine editor-style-rtl.css dazupacken. WordPress kümmert sich dann selbständig darum, diese Datei dem Editor zu übergeben. Dies geschieht in der Methode _WP_Editors::editor_settings(). Wir können auch einen anderen Pfad angeben:

add_editor_style( 'css/editor.css' );

Sogar mehrere Stylesheets sind möglich:

add_editor_style( 
    array ( 
        'css/editor-basic.css',
        'css/editor-fonts.css'
    )
);

Leider stört uns beim Entwickeln der Cache – wir brauchen einen Weg, die Datei sofort frisch zu laden, wenn wir sie geändert haben. Wie früher schon beschrieben, kann filemtime() uns genau den passenden Parameter hierfür geben. Allerdings möchten wir das nicht ins Theme schreiben, denn unsere Nutzer sollen in der Produktivumgebung ja durchaus den Cache nutzen – und keine Zeit mit unnützen File-Lookups vertrödeln.

Dafür habe ich mir ein kleines Plugin geschrieben, das ich beim Entwickeln nutze. Es filtert mce_css, die Liste aller zu verwendenden Editor-Stylesheets.

GitHub: https://gist.github.com/3154898.

<?php # -*- coding: utf-8 -*-
/**
 * Plugin Name: T5 Fresh Editor Stylesheets
 * Description: Enforces fresh editor stylesheets per version parameter.
 * Version:     2012.08.09
 * Author:      Thomas Scholz
 * Plugin URI:  http://toscho.de/?p=1965
 * Author URI:  http://toscho.de
 * License:     MIT
 * License URI: http://www.opensource.org/licenses/mit-license.php
 */

if ( ! function_exists( 't5_fresh_editor_style' ) )
{
    add_filter( 'mce_css', 't5_fresh_editor_style' );

    /**
     * Adds a parameter of the last modified time to all editor stylesheets.
     *
     * Modified copy of _WP_Editors::editor_settings()
     *
     * @wp-hook mce_css
     * @param  string $css Comma separated stylesheet URIs
     * @return string
     */
    function t5_fresh_editor_style( $css )
    {
        global $editor_styles;

        if ( empty ( $css ) or empty ( $editor_styles ) )
        {
            return $css;
        }

        $mce_css = array();

        // Load parent theme styles first, so the child theme can overwrite it.
        if ( is_child_theme() )
        {
            t5_refill_editor_styles(
                $mce_css,
                get_template_directory(),
                get_template_directory_uri()
            );
        }

        t5_refill_editor_styles(
            $mce_css,
            get_stylesheet_directory(),
            get_stylesheet_directory_uri()
        );

        return implode( ',', $mce_css );
    }

    /**
     * Add version parameter to each stylesheet uri.
     *
     * @param  array  $mce_css Passed by reference.
     * @param  string $dir
     * @param  string $uri
     * @return void
     */
    function t5_refill_editor_styles( &$mce_css, $dir, $uri )
    {
        global $editor_styles;

        foreach ( $editor_styles as $file )
        {
            if ( ! $file or ! file_exists( "$dir/$file" ) )
            {
                continue;
            }

            $mce_css[] = add_query_arg(
                'version',
                filemtime( "$dir/$file" ),
                "$uri/$file"
            );
        }
    }
}

Ich habe mich bei diesen Funktionen sehr am Core-Code orientiert und wenig an der Logik geändert. Wenn wir ein Child-Theme schreiben, dessen visuelle Ausgabe sich sehr von der des Parent-Themes unterscheidet, können wir den Filter auch vom Child-Theme aus ansprechen und die Stylesheets des Parent-Themes wegwerfen.