To put things in context, I'm using Gantry on WordPress, which is bundled with Timber and Twig.

I have this code, basic, make-your-text-bold shortcode

// Add Shortcode
function bold_text_shortcode( $atts , $content = null ) {
    return '<strong>' . $content . '</strong>';
add_shortcode( 'b', 'bold_text_shortcode' );

and then in my twig particle,

  {% filter shortcodes %}
  [b] bold text [/b]
  {% endfilter %}

the expected result would be bold text, right?

or in HTML terms

<strong>bold text</strong>

but what I'm getting is

&lt;strong&gt; bold text &lt;/strong&gt;

I've read shortcodes on the wordpress codex, timber shortcode how-tos, Twig escaping, used the php functions

html_entity_decode("<code>foo and bar@!</code>");
htmlentities("<code>foo and bar@!</code>");

and a combination of both, but no dice.

I'm at my wit's end. I can't figure out where the escaping is happening. Made an account for this. Any help is greatly appreciated.


1 Answer 1


I would recommend using single quotes if you want to include some HTML, also you need to return something otherwise nothing happens.

// WP Shortcode
function text_shortcode() {
    return '<strong>bold text:</strong> <a href="https://wordpress.stackexchange.com/questions/318934/shortcode-returns-escaped-html-tags">See wordpress.stackexchange.com</a>';
add_shortcode('bold-text', 'text_shortcode');

Your WordPress shortcode would be:


Edit: You don't need html_entity_decode or htmlentities only when you're doing something very complex or when you want to output some HTML.

The Escaper Extension Twig
You're using Twig, so you need to check if you have enabled escaping mode somewhere.

Escaper Extension

The escaper extension adds automatic output escaping to Twig. It defines a tag, autoescape, and a filter, raw.
When creating the escaper extension, you can switch on or off the global output escaping strategy:

$escaper = new Twig_Extension_Escaper('html');

If set to html, all variables in templates are escaped (using the html escaping strategy), except those using the raw filter:

{{ article.to_html|raw }}

You can also change the escaping mode locally by using the autoescape tag:

{% autoescape 'html' %}
    {{ var }}
    {{ var|raw }}      {# var won't be escaped #}
    {{ var|escape }}   {# var won't be double-escaped #}
{% endautoescape %}

Please bear with me, I don't use Twig, so I could only guide you on this. So, in your case you would need to do something like this:

{% autoescape %}
    {% set hello = '<strong>Hello</strong>' %}
    {% set hola = '<strong>Hola</strong>' %}

    {{ false ? '<strong>Hola</strong>' : hello|raw }}
    does not render the same as
    {{ false ? hola : hello|raw }}
    but renders the same as
    {{ (false ? hola : hello)|raw }}
{% endautoescape %}

Edit 2:
Also see quote WP PHP Coding Standards below and see link: https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/

Single and Double Quotes #

Single and Double Quotes Use single and double quotes when appropriate. If you’re not evaluating anything in the string, use single quotes. You should almost never have to escape quotes in a string, because you can just alternate your quoting style, like so:

echo '<a href="/static/link" title="Yeah yeah!">Link name</a>';
echo "<a href='$link' title='$linktitle'>$linkname</a>";

Text that goes into attributes should be run through esc_attr() so that single or double quotes do not end the attribute value and invalidate the HTML and cause a security issue. See Data Validation in the Codex for further details.

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.