Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Wordpress/TinyMCE - Add elements to formats dropdown

Adding Elements to the TinyMCE Format Dropdown

On a recent migration project, one of the requirements was to add a few blockquote styles to the TinyMCE dropdown list to match the editorial process of the old CMS. Wordpress provides a filter to add a secondary or tetriary dropdown, but if you only have a couple additional elements, it seems like bad UX to seperate it from the original dropdown.

Going off a tip from Chancey Mathews, I realized that Wordpress does not send a argument for block_formats when initializing TinyMCE, thus relying on the defaults. By adding this argument to the tiny_mce_before_init filter, we can add in our extra elements*:

* Note: since we're overriding the defaults, we need to include the original elements (p, h1-h6..etc)

function mce_formats( $init ) {

	$formats = array(
		'p'          => __( 'Paragraph', 'text-domain' ),
		'h1'         => __( 'Heading 1', 'text-domain' ),
		'h2'         => __( 'Heading 2', 'text-domain' ),
		// ... h3 - h6 ...
		'pre'        => __( 'Preformatted', 'text-domain' ),
		'pullquote-1' => __( 'Pull Quote 1', 'text-domain' ),
		'pullquote-2' => __( 'Pull Quote 2', 'text-domain' ),
		'pullquote-3' => __( 'Pull Quote 3', 'text-domain' ),
	);
    
    // concat array elements to string
	array_walk( $formats, function ( $key, $val ) use ( &$block_formats ) {
		$block_formats .= esc_attr( $key ) . '=' . esc_attr( $val ) . ';';
	}, $block_formats = '' );

	$init['block_formats'] = $block_formats;

	return $init;
}
add_filter( 'tiny_mce_before_init', __NAMESPACE__ . '\\mce_formats' );

tinymce dropdown with extra elements

Now that we have the elements in the dropdown, we need to register them with TinyMCE via the tinymce.activeEditor.formatter.register() method. (docs)

jQuery( document ).on( 'tinymce-editor-init', function( event, editor ) {
    // register the formats
    tinymce.activeEditor.formatter.register('pullquote-1', {
        block : 'blockquote',
        classes : 'blockquote-1',
    });
    tinymce.activeEditor.formatter.register('pullquote-2', {
        block : 'blockquote',
        classes : 'blockquote-2',
    });
    tinymce.activeEditor.formatter.register('pullquote-3', {
        block : 'blockquote',
        classes : 'blockquote-3',
    });
});

And there you have it.

html inserted with our new tinymce buttons

@rpolidura
Copy link

rpolidura commented Apr 26, 2018

There's a missing explanation on how to achieve the last step related to: tinymce.activeEditor.formatter.register()

@ZeroGravityWeb
Copy link

ZeroGravityWeb commented Jun 27, 2018

I put the jQuery code in a file, tinymce-format-init.js, and added this code to functions.php

// Enqueue the script to customize the formats
add_action( 'after_wp_tiny_mce', 'custom_after_wp_tiny_mce' );
function custom_after_wp_tiny_mce() {
printf( "<script type='text/javascript' src='%s/js/tinymce-format-init.js'></script>", get_stylesheet_directory_uri() );
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment