Back to Top

No Smilies Conversion in Code Tags

Previous Post:

No Smilies Conversion in Code Tags

Needless to say, those cute little smiley faces you use everyday play an important role in expressing your virtual feelings or opinions. WordPress allows you to convert text smilies, such as 🙂, to their icon counterparts, e.g. :), automatically.

The magic is done by the convert_smilies1 function, hooked to the_content, located in wp-includes/default-filters.php.

Sadly, not all smilies are cute, and not all situations require such conversion. See the text smiley I used above as a demonstration? If it were converted to an icon, it would look way uglier inside that code tag. <code> and <pre> are mostly used to display pre-formatted things, and we don’t want to have some converted smilies messing around inside them, do we?

// We want a text smiley like this 🙂

When I were looking for a work around, I found an enhancement ticket by Viper007Bond, which addressed the very issue we’re discussing here. Unfortunately, that ticket is still awaiting review and the current patch is still in need of more thorough tests. I haven’t tried that patch myself to say the truth, but I personally don’t want to wait for it to be included within the official WordPress. That’s why I come up with my own work around that doesn’t require any core file hack.

Remember the article I wrote about protecting shortcodes from wpautop and other built-in formatting functions? What we are going to do here is pretty much the same, though a little simpler. First of all, we pull all contents inside the <code> and <pre> tags out of your post’s contents and put them into two temporary arrays, namely $bwp_code_matches and $bwp_pre_matches.

To do that, put the following snippet into your theme’s functions.php:

add_filter('the_content', 'bwp_before_format', 7);

// Init some global variables
$bwp_code_matches = array();
$bwp_pre_matches = array();
$bwp_hash = md5(rand(0, 1000));

function bwp_build_pre_match($match)
{
	global $bwp_pre_matches, $bwp_hash;

	$bwp_pre_matches[] = $match[2];
	return "<pre" . $match[1] . ">" . $bwp_hash . sprintf("%03d", sizeof($bwp_pre_matches) - 1) . "</pre>\n";
}

function bwp_build_code_match($match)
{
	global $bwp_code_matches, $bwp_hash;

	$bwp_code_matches[] = $match[2];
	return "<code" . $match[1] . ">" . $bwp_hash . sprintf("%03d", sizeof($bwp_code_matches) - 1) . "</code>\n";
}

function bwp_before_format($content)
{
	$content = preg_replace_callback(
		"/<pre([^>]+)?>(.*?)<\/pre>/siu",
		"bwp_build_pre_match",
		$content
	);
	$content = preg_replace_callback(
		"/<code([^>]+)?>(.*?)<\/code>/siu",
		"bwp_build_code_match",
		$content
	);
	return $content;
}

Next, we put the contents back into your post’s contents, after all formatting functions have finished their tasks, by setting our putting filter’s priority to at least 11, like so:

add_filter('the_content', 'bwp_after_format', 11);

function bwp_put_pre($identifier)
{
	global $bwp_pre_matches;

	$identifier = (int) $identifier[1];
	$content = (isset($bwp_pre_matches[$identifier])) ? $bwp_pre_matches[$identifier] : '';
	return '>' . $content . '</pre>';
}

function bwp_put_code($identifier)
{
	global $bwp_code_matches;

	$identifier = (int) $identifier[1];
	$content = (isset($bwp_code_matches[$identifier])) ? $bwp_code_matches[$identifier] : '';
	return '>' . $content . '</code>';
}

function bwp_after_format($content)
{
	global $bwp_hash;

	$content = preg_replace_callback(
		"/>" . $bwp_hash . "(\d{3})<\/pre>/siu",
		"bwp_put_pre",
		$content
	);
	$content = preg_replace_callback(
		"/>" . $bwp_hash . "(\d{3})<\/code>/siu",
		"bwp_put_code",
		$content
	);

	// Saving some memory 😉
	unset($GLOBALS['bwp_pre_matches']);
	unset($GLOBALS['bwp_code_matches']);

	return $content;
}

That’s it! Try putting this 🙂 into your post and see if the text version of the smiley is left untouched!

Please note that the two filters used by this work around will be called every time the_content is called. If you wish to protect smiley text only for a singular page, simply add this line: if (!is_singular()) return $content; to the beginning of each filter, i.e. bwp_before_format and bwp_after_format.

Is there anything else you must do? Nah, have fun with your plain-but-cool smilies!

References

  1. http://codex.wordpress.org/Function_Reference/convert_s ... rt_smilies []

Take Social Sharing to
the Next Level with Monarch!

Take Social Sharing to the Next Level with Monarch!
Print Article Trackback Trackback to this Article   Subscribe to Comments RSS Subscribe to Comments RSS

Speak Up Your Mind!

An asterisk (*) indicates a required field and must be filled.




  • Web page and e-mail addresses turn into links automatically.
  • Wrap codes in: <code lang=""></code> or <pre lang="" extra="">
  • Lines and paragraphs break automatically.

Next Post: