26

I successfully added a TinyMCE stylesheet using add_editor_style() so that I can preview the styles in the body of the TinyMCE editor.

However, am I right in assuming that the add_editor_style() function can only access style for the body of the editor?

If so, is there another method or function that I can use to access the styling of the TinyMCE Format dropdown as well?

enter image description here

3 Answers 3

55

You can not enhance the drop-down list formatselect. But you can enhance with the hook tiny_mce_before_init the second drop down styleselect, there is to hide in a default WordPress install. The documentation list all defaults and possibilities.

  • inline – Name of the inline element to produce, for example “span”. The current text selection will be wrapped in this inline element.
  • block – Name of the block element to produce, for example "h1". Existing block elements within the selection gets replaced with the new block element.
  • selector – CSS 3 selector pattern to find elements within the selection by. This can be used to apply classes to specific elements or complex things like odd rows in a table.
  • classes – Space separated list of classes to apply to the selected elements or the new inline/block element.
  • styles – Name/value object with CSS Style items to apply such as color etc.
  • attributes – Name/value object with attributes to apply to the selected elements or the new inline/block element.
  • exact – Disables the merge similar styles feature when used. This is needed for some CSS inheritance issues such as text-decoration for underline/strike though.
  • wrapper – State that tells that the current format is a container format for block elements. For example, a div wrapper or blockquote.

The Style Button

Note that, by default, the Style dropdown is hidden on WordPress. At first add the button for custom formats to a menu bar of TinyMCE, in example line 2 with hook mce_buttons_2.

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

The Custom Styles

Then enhance the drop-down of this button. Also useful the enhancement via additional value in the array, see the codex for this example.

/**
 * Add styles/classes to the "Styles" drop-down
 */ 
add_filter( 'tiny_mce_before_init', 'fb_mce_before_init' );

function fb_mce_before_init( $settings ) {

    // Set to true to include the default settings.
    $settings['style_formats_merge'] = true;
    
    $style_formats = array(
        array(
            'title' => 'Download Link',
            'selector' => 'a',
            'classes' => 'download'
            ),
        array(
            'title' => 'My Test',
            'selector' => 'p',
            'classes' => 'mytest',
        ),
        array(
            'title' => 'AlertBox',
            'block' => 'div',
            'classes' => 'alert_box',
            'wrapper' => true
        ),
        array(
            'title' => 'Red Uppercase Text',
            'inline' => 'span',
            'styles' => array(
                'color'         => 'red', // or hex value #ff0000
                'fontWeight'    => 'bold',
                'textTransform' => 'uppercase'
            )
        )
    );
    
    $settings['style_formats'] = json_encode( $style_formats );
    
    return $settings;

}
     

Result

enter image description here

Enhanced Drop down menu

You can also enhance the drop-down with a tree menu. Create the var from the example source above with more structure in the array, like the follow source.

    $style_formats = array(
        array(
            'title' => 'Headers',
                'items' => array(
                array(
                    'title' => 'Header 1',
                    'format' => 'h1',
                    'icon' => 'bold'
                ),
                array(
                    'title' => 'Header 2',
                    'format' => 'h2',
                    'icon' => 'bold'
                )
            )
        ),
        array(
            'title' => 'Download Link',
            'selector' => 'a',
            'classes' => 'download'
        )
    );

enter image description here

For more possibilities and parameters, see the default values of the Style Format drop-down field (writing in JavaScript).

var defaultStyleFormats = [
    {title: 'Headers', items: [
        {title: 'Header 1', format: 'h1'},
        {title: 'Header 2', format: 'h2'},
        {title: 'Header 3', format: 'h3'},
        {title: 'Header 4', format: 'h4'},
        {title: 'Header 5', format: 'h5'},
        {title: 'Header 6', format: 'h6'}
    ]},

    {title: 'Inline', items: [
        {title: 'Bold', icon: 'bold', format: 'bold'},
        {title: 'Italic', icon: 'italic', format: 'italic'},
        {title: 'Underline', icon: 'underline', format: 'underline'},
        {title: 'Strikethrough', icon: 'strikethrough', format: 'strikethrough'},
        {title: 'Superscript', icon: 'superscript', format: 'superscript'},
        {title: 'Subscript', icon: 'subscript', format: 'subscript'},
        {title: 'Code', icon: 'code', format: 'code'}
    ]},

    {title: 'Blocks', items: [
        {title: 'Paragraph', format: 'p'},
        {title: 'Blockquote', format: 'blockquote'},
        {title: 'Div', format: 'div'},
        {title: 'Pre', format: 'pre'}
    ]},

    {title: 'Alignment', items: [
        {title: 'Left', icon: 'alignleft', format: 'alignleft'},
        {title: 'Center', icon: 'aligncenter', format: 'aligncenter'},
        {title: 'Right', icon: 'alignright', format: 'alignright'},
        {title: 'Justify', icon: 'alignjustify', format: 'alignjustify'}
    ]}
];

Add Custom Stylesheet to the editor

Now is the last point, that you include the custom css for this formats, via hook mce_css.

/**
 * Apply styles to the visual editor
 */  
add_filter( 'mce_css', 'fb_mcekit_editor_style');
function fb_mcekit_editor_style($url) {

    if ( ! empty( $url ) )
        $url .= ',';

    // Retrieves the plugin directory URL
    // Change the path here if using different directories
    $url .= trailingslashit( plugin_dir_url( __FILE__ ) ) . '/my-editor-styles.css';

    return $url;
}

Don't forget to add this stylesheet rules also to the front end stylesheet.

Remove the Format Button

As enhancement you can remove the formatselect drop down button via check for the value in the button array. Add the follow source to the function fb_mce_editor_buttons at the hook mce_buttons_2.

$value = array_search( 'formatselect', $buttons );
if ( FALSE !== $value ) {
    foreach ( $buttons as $key => $value ) {
        if ( 'formatselect' === $value )
            unset( $buttons[$key] );
    }
}
9
  • I think I understand this conceptually: essentially you remove WP's standard Formatting box, and then add your own Style dropdown in order to control the styling. Is my understanding correct?
    – Marc P
    Jan 8, 2014 at 16:56
  • Right. Currently I can't find a hook to change the formatselectDropdown. This Dropdown have not a function to build a menu, is static values in the tinymce.js of WP.
    – bueltge
    Jan 8, 2014 at 17:00
  • Also the hint to this answer, there I have found now.
    – bueltge
    Jan 8, 2014 at 17:03
  • Ah ok! Thanks, this is a good solution for now. I'll try it out!
    – Marc P
    Jan 8, 2014 at 17:14
  • 2
    Note: The default styles can be added to the formats dropdown by adding $settings['style_formats_merge'] = true; into »fb_mce_before_init()«. Jul 30, 2015 at 12:27
5

Per this answer, the key to getting the styles to appear in the dropdown is to unset($settings['preview_styles']);

add_filter( 'tiny_mce_before_init', 'fb_mce_before_init' );
function fb_mce_before_init( $settings ) {

    // customize as desired

    // unset the preview styles
    unset($settings['preview_styles']);`

    return $settings;
}
3

Very helpful and thanks for defaultstyles pointers. I found merging arrays wasn't working until converting those default options to valid JSON (not valid JavaScript). Below allows appending the WordPress tinymce's drop-down instead of replacing

Default options (JSON):

$defaults = '[{ "title": "Headers", "items": [
        { "title": "Header 1", "format": "h1" },
        { "title": "Header 2", "format": "h2" },
        { "title": "Header 3", "format": "h3" },
        { "title": "Header 4", "format": "h4" },
        { "title": "Header 5", "format": "h5" },
        { "title": "Header 6", "format": "h6" }
    ] },

    { "title": "Inline", "items": [
        { "title": "Bold", "icon": "bold", "format": "bold" },
        { "title": "Italic", "icon": "italic", "format": "italic" },
        { "title": "Underline", "icon": "underline", "format": "underline" },
        { "title": "Strikethrough", "icon": "strikethrough", "format": "strikethrough" },
        { "title": "Superscript", "icon": "superscript", "format": "superscript" },
        { "title": "Subscript", "icon": "subscript", "format": "subscript" },
        { "title": "Code", "icon": "code", "format": "code" }
    ] },

    { "title": "Blocks", "items": [
        { "title": "Paragraph", "format": "p" },
        { "title": "Blockquote", "format": "blockquote" },
        { "title": "Div", "format": "div" },
        { "title": "Pre", "format": "pre" }
    ] },

    { "title": "Alignment", "items": [
        { "title": "Left", "icon": "alignleft", "format": "alignleft" },
        { "title": "Center", "icon": "aligncenter", "format": "aligncenter" },
        { "title": "Right", "icon": "alignright", "format": "alignright" },
        { "title": "Justify", "icon": "alignjustify", "format": "alignjustify" }
        ] }
 ]'; 

In functions.php return the larger options hash:

add_filter( 'tiny_mce_before_init', 'fb_mce_before_init' );
function fb_mce_before_init( $settings ) {

    $style_formats = array(
    //....

    $settings['style_formats'] = json_encode( array_merge( json_decode($defaults), $style_formats ) );
    return $settings;
}
1
  • Note: The default styles can be added to the formats dropdown by adding $settings['style_formats_merge'] = true; into »fb_mce_before_init()«. Jul 30, 2015 at 12:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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