Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Twig attr filter encoding href and src attributes #4984

Closed
mmikkel opened this issue Sep 24, 2019 · 7 comments
Closed

Twig attr filter encoding href and src attributes #4984

mmikkel opened this issue Sep 24, 2019 · 7 comments

Comments

@mmikkel
Copy link
Contributor

mmikkel commented Sep 24, 2019

Description

The new attr filter has the (in my opinion) unfortunate side effect of HTML encoding all attribute values for the tag that the filter operates on (as in, all of them – not only the attributes you're adding or modifying using the filter).

I know this is due to Yii's BaseHtml::renderTagAttributes() method running all the values through htmlspecialchars(), so I don't know if a fix on Craft's end is feasible. But, this unexpected behaviour can definitely lead to some gotcha moments, especially for attributes like src and href, where e.g. ampersands in query strings being encoded to & can be an issue (I just realized some of my Imgix URLs were failing due to this).

Steps to reproduce

{% filter attr({ class: 'foo' }) %}
    <img src="image.jpg?width=100&height=100" />
{% endfilter %}

Renders <img class="foo" src="image.jpg?width=100&amp;height=100" />

Additional info

  • Craft version: 3.3.4.1
  • PHP version:
  • Database driver & version:
  • Plugins & versions:
@brandonkelly
Copy link
Member

In your example, the correct behavior should be to encode the & to &amp;, as the HTML you posted is actually invalid.

However if it already is encoded as &amp;, the filter should not be double-encoding it to &amp;amp;, which it was doing. So I’ve just fixed that for the next release.

@mmikkel
Copy link
Contributor Author

mmikkel commented Sep 25, 2019

Ah! You're absolutely correct. And the double &amp;amp; was my actual issue, of course. Thanks for the quick fix!

@samhibberd
Copy link

@brandonkelly i'm not sure if this is related, a separate issue or me not understanding something but seeing some inconsistencies between rendering HTML chars when run using the attr() function:

<input {{ attr({
    type: "submit",
    value: "Go &rarr;",
    class: "btn btn-green cursor-pointer"
}) }}>

<input type="submit" value="Go &rarr;" class="btn btn-green cursor-pointer">

I would expect these two submit buttons should render exactly the same, but they don't?

Screenshot 2022-03-09 at 13 47 38

Screenshot 2022-03-09 at 13 50 44

@brandonkelly
Copy link
Member

brandonkelly commented Mar 13, 2022

@samhibberd the & is probably getting encoded by the output tag ({{ }}), not the attr() function. Add |raw after the }} to avoid that.

<input {{ attr({
    type: "submit",
    value: "Go &rarr;",
    class: "btn btn-green cursor-pointer"
})|raw }}>

or just use the tag() function:

{{ tag('input', {
    type: "submit",
    value: "Go &rarr;",
    class: "btn btn-green cursor-pointer"
}) }}

@samhibberd
Copy link

Hey @brandonkelly, tried that and the input tag, same deal for me, I must be missing something really obvious :(

Tested the following in a fresh template, with no other content, and only the first raw html version outputs correctly:

Screenshot 2022-03-14 at 11 41 57

<input type="submit" value="Go &rarr;">

<input {{ attr({
    type: "submit",
    value: "Go &rarr;",
}) }}>

<input {{ attr({
    type: "submit",
    value: "Go &rarr;",
})|raw }}>

{{ tag('input', {
    type: "submit",
    value: "Go &rarr;",
}) }}

@brandonkelly
Copy link
Member

Sorry, this is actually expected behavior. I forgot that yii\helpers\Html::renderTagAttributes() (which the attr() Twig function is mapped to) encodes all attribute values. So you will need to pass in directly to the value.

<input {{ attr({
    type: "submit",
    value: "Go →",
}) }}>

@samhibberd
Copy link

Cool. Thanks @brandonkelly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants