How to customize TinyMCE4 in WP 3.9 – the old way for styles and formats doesn’t work anymore

If you look in class-wp-editor.php you’ll find that the filter you are using is still there, however the settings are different.

self::$first_init = array(
                    'theme' => 'modern',
                    'skin' => 'lightgray',
                    'language' => self::$mce_locale,
                    'formats' => "{
                        alignleft: [
                            {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles: {textAlign:'left'}},
                            {selector: 'img,table,dl.wp-caption', classes: 'alignleft'}
                        ],
                        aligncenter: [
                            {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles: {textAlign:'center'}},
                            {selector: 'img,table,dl.wp-caption', classes: 'aligncenter'}
                        ],
                        alignright: [
                            {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles: {textAlign:'right'}},
                            {selector: 'img,table,dl.wp-caption', classes: 'alignright'}
                        ],
                        strikethrough: {inline: 'del'}
                    }",
                    'relative_urls' => false,
                    'remove_script_host' => false,
                    'convert_urls' => false,
                    'browser_spellcheck' => true,
                    'fix_list_elements' => true,
                    'entities' => '38,amp,60,lt,62,gt',
                    'entity_encoding' => 'raw',
                    'keep_styles' => false,
                    'paste_webkit_styles' => 'font-weight font-style color',

                    // Limit the preview styles in the menu/toolbar
                    'preview_styles' => 'font-family font-size font-weight font-style text-decoration text-transform',

                    'wpeditimage_disable_captions' => $no_captions,
                    'wpeditimage_html5_captions' => current_theme_supports( 'html5', 'caption' ),
                    'plugins' => implode( ',', $plugins ),
                );

I’m guessing, but I think you need to change the array key you are targeting to formats.

EDIT Leaving this in place, but the OP confirms that this does not do what he is attempting.

function mce_mod( $init ) {
        $init['formats'] = "{
                            alignleft: [
                                {selector: 'p,h3,h4,td,th,div,ul,ol,li', styles: {textAlign:'left'}},
                                {selector: 'img,table,dl.wp-caption', classes: 'alignleft'}
                            ],
                            aligncenter: [
                                {selector: 'p,h3,h4,td,th,div,ul,ol,li', styles: {textAlign:'center'}},
                                {selector: 'img,table,dl.wp-caption', classes: 'aligncenter'}
                            ],
                            alignright: [
                                {selector: 'p,h3,h4,td,th,div,ul,ol,li', styles: {textAlign:'right'}},
                                {selector: 'img,table,dl.wp-caption', classes: 'alignright'}
                            ],
                            strikethrough: {inline: 'del'}
                        }";
    return $init;
}
add_filter('tiny_mce_before_init', 'mce_mod');

Keep in mind that this is totally untested, so your mileage may vary. (And don’t use on a production site until you’ve tested it).

Continuing onwards

Digging deeper the formats appear to be a custom tinyMCE button. You can see that the formatselect button is added to mce_buttons_2 in the class-wp-editor.php. And then I tracked that to tinymce.js :

    editor.addButton('formatselect', function() {
        var items = [], blocks = createFormats(editor.settings.block_formats ||
            'Paragraph=p;' +
            'Address=address;' +
            'Pre=pre;' +
            'Heading 1=h1;' +
            'Heading 2=h2;' +
            'Heading 3=h3;' +
            'Heading 4=h4;' +
            'Heading 5=h5;' +
            'Heading 6=h6'
        );

With that in mind, I think the new target would be to 1. (ideally) change the editor.settings.block_formats or 2. remove that button by filtering mce_buttons_2 and adding your own custom version.

Tested and working

function mce_mod( $init ) {
    $init['block_formats'] = 'Paragraph=p;Heading 3=h3;Heading 4=h4';

    $style_formats = array (
        array( 'title' => 'Bold text', 'inline' => 'b' ),
        array( 'title' => 'Red text', 'inline' => 'span', 'styles' => array( 'color' => '#ff0000' ) ),
        array( 'title' => 'Red header', 'block' => 'h1', 'styles' => array( 'color' => '#ff0000' ) ),
        array( 'title' => 'Example 1', 'inline' => 'span', 'classes' => 'example1' ),
        array( 'title' => 'Example 2', 'inline' => 'span', 'classes' => 'example2' )
    );

    $init['style_formats'] = json_encode( $style_formats );

    $init['style_formats_merge'] = false;
    return $init;
}
add_filter('tiny_mce_before_init', 'mce_mod');

function mce_add_buttons( $buttons ){
    array_splice( $buttons, 1, 0, 'styleselect' );
    return $buttons;
}
add_filter( 'mce_buttons_2', 'mce_add_buttons' );

Small caveat: I’m not sure where to add the styles for the drop-down items themselves. In the TinyMCE sample, the “Red Headline” option is red. I couldn’t figure this out. If you do please let me know.

Leave a Comment