Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

Before WP 3.9 i had the following two filters applied in the functions.php:

function my_mce_buttons_2( $buttons ) {
    array_unshift( $buttons, 'styleselect' );
    return $buttons;
}
add_filter('mce_buttons_2', 'my_mce_buttons_2');

function mce_mod( $init ) {
    $init['theme_advanced_blockformats'] = 'p,h3,h4';
    $init['theme_advanced_styles'] = "Header gross=mus-bi news-single-bighead; Header klein=mus-bi news-single-smallhead; Link=news-single-link; List Items=news-single-list";
    return $init;
}
add_filter('tiny_mce_before_init', 'mce_mod');

so that the paragraph formats dropdown only shows p, h3 and h4 while the custom styles dropdown shows "Header gross", "Header klein" and so on. But unfortunately wp and tinymce don't bother anymore since wp 3.9, i only see the standard paragraph formats dropdown now

paragraph

as well as the standard styles format dropdown:

styles

So far i haven't found any docs about if any hooks have changed with the update to tinymce 4. Anyone knows? Best regards Ralf

Update: Ok based on a little more research and the comments beneath i guess i've figured things out:

//Creating the style selector stayed the same
function my_mce_buttons( $buttons ) {
   array_unshift( $buttons, 'styleselect' );
   return $buttons;
}
add_filter('mce_buttons', 'my_mce_buttons');

function mce_mod( $init ) {
   //theme_advanced_blockformats seems deprecated - instead the hook from Helgas post did the trick
   $init['block_formats'] = "Paragraph=p; Heading 3=h3; Heading 4=h4";

   //$init['style_formats']  doesn't work - instead you have to use tinymce style selectors
   $style_formats = array(
    array(
        'title' => 'Header 3',
        'classes' => 'mus-bi news-single-bighead'
    ),
    array(
        'title' => 'Header 4',
        'classes' => 'mus-bi news-single-smallhead'
    ),
    array(
        'title' => 'Link',
        'block' => 'a',
        'classes' => 'news-single-link',
        'wrapper' => true
    )
   );
   $init['style_formats'] = json_encode( $style_formats );
   return $init;
}
add_filter('tiny_mce_before_init', 'mce_mod');
share|improve this question
1  
Have you seen wordpress.stackexchange.com/questions/139163/…? –  toscho Apr 17 at 9:24
    
No i haven't seen. Thanks! But unfortunately with the code described there it is only possible to create a button instead of reshaping style and paragraph drop downs. Have to keep on reading and researching. –  rpk Apr 17 at 11:47
    
Here's how you can keep the original menu items in style_select and add a "Classes" menu to it. wordpress.stackexchange.com/questions/143689/… –  Howdy_McGee May 7 at 18:07

1 Answer 1

up vote 16 down vote accepted

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.

share|improve this answer
    
thanks helga! i've looked into the class-wp-editor before too. But was unsure what the syntax had to be (there isn't much wp related documentation for the updated tinymceapi) . tried your suggestion now. same results like with my initial snippets. TinyMCE doesn't mind what the init looks like. on the tinymce site i've found an example for custom formats, js only, and i failed to adapt it towards wp and php: tinymce.com/tryit/custom_formats.php –  rpk Apr 17 at 12:06
    
ahhhh brilliant! the hint with editor.settings.block_formats did the trick. I've post an update to my initial post. thanks! –  rpk Apr 17 at 13:59
1  
Great help, thanks! Just wanted to add that the block_formats option can't have a trailing ; . I was building the value from saved configurable options and had a trailing ; that borked the list. Hope that saves somebody a few minutes. –  Adam Pope May 15 at 9:07
1  
@indextwo yup, I solved it here (as best as I could) and decided... hey... blog post! You don't get the class on a span even if you define it as inline? array( 'title' => 'Red text', 'inline' => 'span', 'styles' => array( 'color' => '#ff0000' ) ),? –  helgatheviking May 22 at 13:51
1  
The items in the format menu inherit the styles from your editor-styles.css, except for the color styles. If you want the color styles as well, adding this code to the mce_mod() function worked for me: unset($init['preview_styles']); –  Dalton Jul 8 at 14:17

protected by Community May 7 at 18:09

Thank you for your interest in this question. Because it has attracted low-quality answers, posting an answer now requires 10 reputation on this site.

Would you like to answer one of these unanswered questions instead?

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