WordPress visual editor not visible (because of user-agent sniffing)

December 4, 2013

One thing you get touted into from the very beginning when you start with web development is that user agent sniffing is bad. In other words, trying to figure out what browser the user has and then change things that you think will be a better experience.

It’s not that changing things are bad, it’s that user agent sniffing seldomly work all the time.

We had this one problem where the visual editor in wordpress wouldn’t work. And when I say it didn’t work, I mean it wasn’t even rendered out. No javascript errors, no erorrs in the webserver log. The editor worked on all our dev servers, but once it was out on the production replica server, it just stopped working.

After a lot of changing and fiddeling with the server configs I started to work through the wordpress core files. Apparently wordpress tries to detect if the user is on a mobile phone or not, if the user is on a mobile phone the visual editor is not rendered out, a matter a fact, as long as it can’t detect that you’re on a desktop computer, it won’t render the visual editor at all.

This usually won’t be a problem, but if you have your frontend servers behind a proxy or load balancer that strips the user agent, wordpress will automatically¬†assume that you’re on a non-desktop device, and not render the editor.

The problem can be traced to the function user_can_richedit in the file wp-includes/general-template.php

/**
* Whether the user should have a WYSIWIG editor.
*
* Checks that the user requires a WYSIWIG editor and that the editor is
* supported in the users browser.
*
* @since 2.0.0
*
* @return bool
*/
function user_can_richedit() {
	global $wp_rich_edit, $is_gecko, $is_opera, $is_safari, $is_chrome, $is_IE;

	if ( !isset($wp_rich_edit) ) {
		$wp_rich_edit = false;

		if ( get_user_option( 'rich_editing' ) == 'true' || ! is_user_logged_in() ) { // default to 'true' for logged out users
			if ( $is_safari ) {
				$wp_rich_edit = ! wp_is_mobile() || ( preg_match( '!AppleWebKit/(\d+)!', $_SERVER['HTTP_USER_AGENT'], $match ) && intval( $match[1] ) >= 534 );
			} elseif ( $is_gecko || $is_chrome || $is_IE || ( $is_opera && !wp_is_mobile() ) ) {
				$wp_rich_edit = true;
			}
		}
	}

	return apply_filters('user_can_richedit', $wp_rich_edit);
}

The easiest way to circumvent this problem is to add a filter that overrides the base-functionality, just paste this code snippet into your functions.php file in your theme;

<?php
/**
* Overrides the function user_can_richedit and only checks the
* user preferences instead of doing UA sniffing.
*
* @return bool
*/
function user_can_richedit_custom() {
	global $wp_rich_edit;

	if (get_user_option('rich_editing') == 'true' || !is_user_logged_in()) {
		$wp_rich_edit = true;
		return true;
	}

	$wp_rich_edit = false;
	return false;
}

add_filter('user_can_richedit', 'user_can_richedit_custom');

Tags