It is commonly useful to escape encode special HTML characters in output to avoid breaking output attributes (among other reasons):

Take the following seemingly innocent template snippet:

<!DOCTYPE html>
{exp:channel:entries channel="blog"}

    <meta name="description" content="{meta_description}"/>

This will not perform as one might expect when meta_description contains special characters like double quotes or ampersands.

For example, bad output:

<!DOCTYPE html>

    <title>Some Blog Title</title>

    <meta name="description" content="Learn how to program with "Best practices & methods""/>

How can this be resolved?

7 Answers 7


You can use Ce_string for this, which is the ultimate swiss army knife.

{exp:ce_str:ing htmlspecialchars=":CONST:ENT_QUOTES"}<a href='test'>Test</a>{/exp:ce_str:ing}

ExpressionEngine does not appear to provide a way to deal with this scenario out-of-the-box.

One solution would be to create a custom plugin like the following. I have intentionally named this "Utility Functions" because I plan to add additional functionality as needed. But hopefully this will save some time for future readers.

$plugin_info       = array(
    'pi_name'        => 'Utility Functions',
    'pi_version'     => '1.0.0',
    'pi_author'      => 'Lea Hayes',
    'pi_author_url'  => 'http://leahayes.co.uk',
    'pi_description' => 'A selection of utility functions for use in templates.',
    'pi_usage'       => util::usage()

class util {

    public function htmlspecialchars() {
        $this->EE = &get_instance();
        return htmlspecialchars($this->EE->TMPL->tagdata);

    public static function usage() {
        return '{exp:util:htmlspecialchars}Place unescaped content here...{/exp:util:htmlspecialchars}';

/* End of file pi.util.php */
/* Location: ./system/third_party/util/pi.util.php */

The original template can then be written as:

<!DOCTYPE html>
{exp:channel:entries channel="blog"}

    <meta name="description" content="{exp:util:htmlspecialchars}{meta_description}{/exp:util:htmlspecialchars}"/>

Meaning that the output is:

<!DOCTYPE html>

    <title>Some Blog Title</title>

    <meta name="description" content="Learn how to program with &quot;Best practices &amp; methods&quot;"/>

It is likely that there are already other add-ons that deal with this, but at least with this approach you can add your own functions as needed.


aren't we overkillingt this somewhat??

How about setting PHP on Output and dropping this into the template :

<?php echo addslashes("{meta_description}"); ?>

Simple, no need for extra plugins (and extra work for CI or EE), just PHP on templates. Plus addslashes does exactly what the OP's asking for, no silly str_replace with massive arrays of escape characters ect...

Just my 2 pennith!


This did the trick for me (plugin doesn't work with later versions of EE).

{exp:markdown} Text to be parsed. (for me the channel field tag {data_feedback_text}) {/exp:markdown}

Without the markdown tag some php code I had was dying due to quotes within the string.


If anyone is still wondering, now you can use native variable modifiers. {meta_description:attr_safe}



I know it may be way too late to answer your question, but in case any body else sees this thread, you can use PHP String Fun. This plugin allows you to use practically any PHP string functions. I used the str_replace function with the parameter reverse="y". You can do, for example, something like this:

{exp:phpstringfun reverse="y" function="str_replace" par1='\"' par2='"'}

Edit : you can use PHP String Fun of course, or Ce_string or even roll your own... or you could just add some PHP snippet to the template and do it yourself (set the PHP on output). in this case though the most sensible PHP function for the specific challange in the OP is addslashes


There's a first party add-on for that.

<meta name="description"
  content="{exp:html_attribute_content limit="200" end_char="&#8230;"}{meta_description}{/exp:html_attribute_content}"

There's a list of useful add-ons to download right from EECMS user guide.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.