Hyphenated custom element tags behave differently (break) when using "Html::modifyTagAttributes" via PHP compared to Twigs "attr" filter.
Writing the following Twig markup with Crafts "attr" filter
<custom-element{{ attr({class:'foo'})}}></custom-element>
...will renders this:
✅ <custom-element class="foo"></custom-element>
````
Where-as writing this in PHP with [Crafts modifyTagAttributes static method](https://docs.craftcms.com/api/v3/craft-helpers-html.html#method-modifytagattributes)
```php
Html::modifyTagAttributes('<custom-element>', ['class'=>'foo']).'</custom-element>';
...will renders this:
❌ <custom class="foo" -element=""></custom>
It doesn't seem the handle the hyphen correctly, which is odd because is seems that the Twig filter is using the same Html::modifyTagAttributes method behind the scenes.
I'm unable to find any related issues or restrictions further up the chain. Yii's renderTagAttributes doesn't mention anything about special behaviours when using hyphenated custom elements.
private static function modifyTagAttributes($tag, $attributes, $content = '') {
$_tag = str_replace('-', '_', $tag);
$html = Html::modifyTagAttributes('<'.$_tag.'>', $attributes);
$html = str_replace($_tag, $tag, $html);
$html .= (string)$content;
$html .= '</'.$tag.'>';
return Template::raw($html);
}
As-per my original example:
echo static::modifyTagAttributes('custom-element', ['class' => 'foo']);
🎉 <custom-element class="foo"></custom-element
Thanks for reporting that, just fixed for the next release.
It doesn't seem the handle the hyphen correctly, which is odd because is seems that the Twig filter is using the same
Html::modifyTagAttributesmethod behind the scenes.
To clarify, your template code is calling the attr() _function_ (which calls renderTagAttributes() and is used to generate a string of standalone HTML attributes); not the |attr _filter_ (which calls modifyTagAttributes() and is used to _modify_ the HTML attributes on a passed-in HTML element). You would be able to reproduce the same bug in Twig if you did this instead:
{{ '<custom-element></custom-element>'|attr({class:'foo'}) }}
Thank you @brandonkelly. Not just for a quick response, but also for the detailed explanation.... that makes a big difference.
Craft 3.5.13 is out now with that fix.