12

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
2
  • If it's for your development purposes why not just do a hard refresh in the browser or turn the browser cache off? Nov 10, 2011 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, 2011 at 18:52

5 Answers 5

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 );
    }
4
  • 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, 2014 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, 2016 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, 2018 at 8:16
  • This breaks the loading of the default editor styles.
    – xsonic
    Feb 18, 2019 at 8:42
10

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');
  }
});
4
  • This is the easiest method so far that works flawlessly every time.
    – antikbd
    Dec 29, 2018 at 0:20
  • 2
    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')); Apr 30, 2019 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. Jun 4, 2019 at 11:03
  • This totally made my day. Excellent solution! Oct 22, 2020 at 5:55
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)

1
  • 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); Apr 14, 2017 at 18:34
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.

1

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 and acknowledge you have read our privacy policy.

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