11

Is there a method to force the refresh of editor-style.css, when I change manually the stylesheet for the TinyMCE editor? Modification doesn't show immediately but they will be cached in the admin side of administration backend.

For example like this:

editor-style.css?ver=3393201
  • If it's for your development purposes why not just do a hard refresh in the browser or turn the browser cache off? – sanchothefat Nov 10 '11 at 10:30
  • 3
    I've had the same problem, and a hard refresh doesn't always work. The caching seems to be pretty stubborn. – Ray Gulick Nov 15 '11 at 18:52
10

There is a hook for that: 'mce_css'. It is called in _WP_Editors::editor_settings() and you get all loaded stylesheets comma separated as the first and only parameter.

Now it is easy: Use the global variable $editor_styles (here are your theme’s and parent theme’s editor stylesheets stored already), add the time of the file’s last modification as a parameter and rebuild the string.

As a plugin:

<?php # -*- coding: utf-8 -*-
/**
 * Plugin Name: Refresh Editor Stylesheets
 * Description: Enforces fresh editor stylesheets per version parameter.
 * Version:     2012.07.21
 * Author:      Fuxia
 * Plugin URI:  http://wordpress.stackexchange.com/q/33318/73
 * Author URI:  https://fuxia.me
 * License:     MIT
 * License URI: http://www.opensource.org/licenses/mit-license.php
 */

    add_filter( 'mce_css', 't5_fresh_editor_style' );

    /**
     * Adds a parameter of the last modified time to all editor stylesheets.
     *
     * @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;
        }

        // Modified copy of _WP_Editors::editor_settings()
        $mce_css   = array();
        $style_uri = get_stylesheet_directory_uri();
        $style_dir = get_stylesheet_directory();

        if ( is_child_theme() )
        {
            $template_uri = get_template_directory_uri();
            $template_dir = get_template_directory();

            foreach ( $editor_styles as $key => $file )
            {
                if ( $file && file_exists( "$template_dir/$file" ) )
                {
                    $mce_css[] = add_query_arg(
                        'version',
                        filemtime( "$template_dir/$file" ),
                        "$template_uri/$file"
                    );
                }
            }
        }

        foreach ( $editor_styles as $file )
        {
            if ( $file && file_exists( "$style_dir/$file" ) )
            {
                $mce_css[] = add_query_arg(
                    'version',
                    filemtime( "$style_dir/$file" ),
                    "$style_uri/$file"
                );
            }
        }

        return implode( ',', $mce_css );
    }
  • In WordPress 3.9 this plugin now seems to break the image editing buttons. I haven't had a chance to try to figure out why. – mrwweb Jun 17 '14 at 16:08
  • 2016 Update: Adding this code exactly as-is (but in my functions.php file rather than a plugin) with WP 4.6.1, it works perfectly. There don't seem to be any issues with adding media or editing media inline. It's crazy that you can't add an argument to add_editor_css with filemtime the way you can with wp_enqueue_style, or even a garbage string on the end of the filename... but this totally works. – indextwo Dec 6 '16 at 16:49
  • Thank you for this useful plugin! I'm using it with WP 4.9.6. The only bug that I found at the moment is when the plugin is activated the <!--more--> tag isn't displayed within TinyMCE. Any ideas how can I solve this? – pa4080 May 30 '18 at 8:16
  • This breaks the loading of the default editor styles. – xsonic Feb 18 at 8:42
9

I couldn't get toscho's answer to work for the current version of WordPress (4.7.2), and that seems to be because the TinyMCE init array has a cache_suffix set to 'wp-mce-' . $tinymce_version.

So instead, you can just overwrite that with the tiny_mce_before_init filter, like so:

function wpse33318_tiny_mce_before_init( $mce_init ) {

    $mce_init['cache_suffix'] = 'v=123';

    return $mce_init;    
}
add_filter( 'tiny_mce_before_init', 'wpse33318_tiny_mce_before_init' );

Of course, this isn't nearly as good as filemtime(), but at least this works in 4.7.2.

Note: This also adds the cache buster to other editor styles (like skin.min.css, content.min.css, dashicons.min.css, and wp-content.css)

  • 2
    If you are in active testing and development, I would add a 'version' number that will always be different. One way to accomplish this is using seconds since the Unix Epoch (January 1 1970 00:00:00 GMT) $mce_init['cache_suffix'] = "v=" . time(); or something even simpler like $mce_init['cache_suffix'] = "v=" . rand(100000000,999999999); – roberthuttinger Apr 14 '17 at 18:34
6

Instead of just calling add_editor_style with your CSS file, add a cache buster query string parameter:

add_action('admin_enqueue_scripts', function(){
  if(is_admin()){
    add_editor_style(get_template_directory_uri().'/assets/css/editor.css?1');
  }
});
  • This is the easiest method so far that works flawlessly every time. – antikbd Dec 29 '18 at 0:20
  • 1
    I like the simplicity of this approach and the fact it doesn't add the query string to other unrelated stylesheets. I combined this with filemtime() to automate cache-busting updates: add_editor_style(get_stylesheet_directory_uri() . '/editor-style.css?v=' . filemtime(get_stylesheet_directory() . '/editor-style.css')); – Josh Harrison Apr 30 at 15:26
  • The key here is to always use the absolute path for the css file(s) in question (i.e. use get_template_directory_uri()), when appending a cache buster; otherwise it won't work. – Zoli Szabó Jun 4 at 11:03
3

I had the same issue (2012, WP 3.4.2 !!). Possible solutions while this bug is around:

1) If you use firebug, [x]Disable Browser Cache in the Net panel helps. I even had a very strange issue, that the cached editor-style briefly appears (in a css-filtered) Firebug net panel for a split second, than disappears again. Took screenshots to prove to myself.

2) A full browser cache clear helps. For whatever reason thereafter the issue did not reappear.

3) Lastly, my preferred advice, if you have to also make sure, i.e. your clients on staging or live server get your incremental improvements (w/o any annoying cache clearance advice):

Relocate the file and keep counting up:

// add_editor_style('editor-style-01.css'); bump for every deployment
// add_editor_style('editor-style-02.css');
add_editor_style('editor-style-03.css');

Hacky, but reliable.

0

The problem with accepted answer in latest versions I assume is $editor_styles array only contains stylesheets added using theme, so as a result it strips rest of the stylesheets added by core wordpress or plugins from the returning string.

Following is the solution I came up with after tweaking the code, you can use it in your functions.php file. My solution uses nested loop and checks for stylesheets present in $editor_styles array, and appends the last modified time as parameter to query string and updates the value in array.

add_filter('mce_css', 'fresh_editor_style');

function fresh_editor_style($mce_css_string){
    global $editor_styles;
    $mce_css_list = explode(',', $mce_css_string);

    foreach ($editor_styles as $filename){
        foreach($mce_css_list as $key => $fileurl){
            if(strstr($fileurl, '/' . $filename)){
                $filetime = filemtime(get_stylesheet_directory() . '/' . $filename);
                $mce_css_list[$key] =  add_query_arg('time', $filetime, $fileurl);
            }
        }
    }

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.