Documentation Register Additional HTML Attributes for TinyMCE and WP KSES

Register Additional HTML Attributes for TinyMCE and WP KSES

Out of the box, WordPress gives content creators a fair amount of flexibility in what can be entered into the Visual and Text editors. They can enter all sorts of HTML tags which can be a blessing or a curse. You may find you want to register additional HTML elements or attributes for them to use, or to remove ones you don’t want them to use.

To keep additional HTML attributes from being stripped by WP Kses when the post is saved, you’ll need to register them on the $allowedposttags global. Here’s what it would look like:

add_action( 'init', 'vipx_allow_contenteditable_on_divs' );
function vipx_allow_contenteditable_on_divs() {
	global $allowedposttags;

	$tags = array( 'div' );
	$new_attributes = array( 'contenteditable' => array() );

	foreach ( $tags as $tag ) {
		if ( isset( $allowedposttags[ $tag ] ) && is_array( $allowedposttags[ $tag ] ) )
			$allowedposttags[ $tag ] = array_merge( $allowedposttags[ $tag ], $new_attributes );

With just that snippet, however, you’ll find that you can save the proper markup in the Text editor but it gets stripped out in the Visual (TinyMCE) editor. To get around this, you’ll need to also register your new attributes with TinyMCE:

add_filter('tiny_mce_before_init', 'vipx_filter_tiny_mce_before_init');
function vipx_filter_tiny_mce_before_init( $options ) {

	if ( ! isset( $options['extended_valid_elements'] ) ) {
		$options['extended_valid_elements'] = '';
	} else {
		$options['extended_valid_elements'] .= ',';

	if ( ! isset( $options['custom_elements'] ) ) {
		$options['custom_elements'] = '';
	} else {
		$options['custom_elements'] .= ',';

	$options['extended_valid_elements'] .= 'div[contenteditable|class|id|style]';
	$options['custom_elements']         .= 'div[contenteditable|class|id|style]';
	return $options;

Documentation is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.