This morning, I was scrolling through Twitter as I tried to wake up (as I do most every morning), when I came across this tweet from the wonderful Carrie Dils asking how to customize the WordPress TinyMCE block formats:
I want an option in the WordPress editor to style something as code (not <pre><code>, just <code>). I know I could code it myself but I figure there's probably already a plugin. Know of one? #lazyweb pic.twitter.com/TCuCP4U1NF
— Carrie Dils 🇺🇦 (@cdils) March 6, 2018
“That’s funny,” I thought to myself, “I used to do those customizations on client sites all the time. In fact, some of those customizations are even in my (now-abandoned) WordPress Starter Theme repo on GitHub!”
I was able to throw together a quick gist to demonstrate how to pull off a <code>
 block format, but doing so reminded me how much of a struggle it was to figure that all out to begin with. In the interest of helping everyone else configure TinyMCE, here’s a quick breakdown:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<?php /** * Change the block formats available in TinyMCE. * * @link http://codex.wordpress.org/TinyMCE_Custom_Styles * * @param array $init Default settings to be overridden. * * @return array The modified $init array. */ function cdils_change_mce_block_formats( $init ) { $block_formats = array( 'Paragraph=p', 'Heading 1=h1', 'Heading 2=h2', 'Heading 3=h3', 'Heading 4=h4', 'Heading 5=h5', 'Heading 6=h6', 'Preformatted=pre', 'Code=code', ); $init['block_formats'] = implode( ';', $block_formats ); return $init; } add_filter( 'tiny_mce_before_init', 'cdils_change_mce_block_formats' ); |
First, we’re hooking into the “tiny_mce_before_init” filter, which lets us access the configuration for TinyMCE. To give you a sense of what this looks like, here are some of the WordPress defaults:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
Array ( [theme] => modern [skin] => lightgray [language] => en [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] => [remove_script_host] => [convert_urls] => [browser_spellcheck] => 1 [fix_list_elements] => 1 [entities] => 38,amp,60,lt,62,gt [entity_encoding] => raw [keep_styles] => [cache_suffix] => wp-mce-4607-20180123 [resize] => [menubar] => [branding] => [preview_styles] => font-family font-size font-weight font-style text-decoration text-transform [end_container_on_empty_block] => 1 [wpeditimage_html5_captions] => 1 [wp_lang_attr] => en-US [wp_keep_scroll_position] => 1 [wp_shortcut_labels] => {"Heading 1":"access1","Heading 2":"access2","Heading 3":"access3","Heading 4":"access4","Heading 5":"access5","Heading 6":"access6","Paragraph":"access7","Blockquote":"accessQ","Underline":"metaU","Strikethrough":"accessD","Bold":"metaB","Italic":"metaI","Code":"accessX","Align center":"accessC","Align right":"accessR","Align left":"accessL","Justify":"accessJ","Cut":"metaX","Copy":"metaC","Paste":"metaV","Select all":"metaA","Undo":"metaZ","Redo":"metaY","Bullet list":"accessU","Numbered list":"accessO","Insert\/edit image":"accessM","Remove link":"accessS","Toolbar Toggle":"accessZ","Insert Read More tag":"accessT","Insert Page Break tag":"accessP","Distraction-free writing mode":"accessW","Keyboard Shortcuts":"accessH"} [content_css] => http://liquidweb.local/wp-includes/css/dashicons.css?ver=4.9.4,http://liquidweb.local/wp-includes/js/tinymce/skins/wordpress/wp-content.css?ver=4.9.4,https://fonts.googleapis.com/css?family=Libre+Franklin%3A300%2C300i%2C400%2C400i%2C600%2C600i%2C800%2C800i&subset=latin%2Clatin-ext,http://liquidweb.local/wp-content/themes/twentyseventeen/assets/css/editor-style.css [plugins] => charmap,colorpicker,hr,lists,media,paste,tabfocus,textcolor,fullscreen,wordpress,wpautoresize,wpeditimage,wpemoji,wpgallery,wplink,wpdialogs,wptextpattern,wpview [selector] => #content [wpautop] => 1 [indent] => [toolbar1] => formatselect,bold,italic,bullist,numlist,blockquote,alignleft,aligncenter,alignright,link,wp_more,spellchecker,dfw,wp_adv [toolbar2] => strikethrough,hr,forecolor,pastetext,removeformat,charmap,outdent,indent,undo,redo,wp_help [toolbar3] => [toolbar4] => [tabfocus_elements] => content-html,save-post [body_class] => content post-type-post post-status-auto-draft post-format-standard page-template-default locale-en-us [wp_autoresize_on] => 1 [add_unload_trigger] => ) |
This is a PHP array representation of the settings that will be passed to TinyMCE when it’s initialized. Settings that are missing will naturally fall back to their TinyMCE-provided defaults. We can take advantage of this fact to adjust TinyMCE’s configuration in all sorts of ways, including editing the block_formats
 setting.
Note that TinyMCE is expecting a semi-colon-delimited string, so the code snippet above writes out each format as a value in the $block_formats
 array, then uses implode( ';', $block_formats)
 to bring them all together. You’ll also need to be respectful of other plugins that might be editing the block_formats
 configuration (the example above will wholesale rewrite $init['block_formats']
, whether it exists or not).
For more on customizing TinyMCE within WordPress, be sure to check out the “TinyMCE Custom Styles” article in the WordPress Codex!
Reformat
Really handy this, just wish I could figure out how to easily add classes at this level. When I use style_formats it adds the horrible Formats dropdown which adds classes on rather than toggle them. I guess core has abandoned this now in favour of block editor though.