-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
RFC / WIP - html_attributes function #4405
base: 3.x
Are you sure you want to change the base?
Conversation
35668a6
to
bcba2bc
Compare
ab96d70
to
93fadaa
Compare
html_attributes
function
html_attributes
function
|
I suppose that the implementation of |
@fabpot Yep it could do. I still haven't fully considered the twig methods yet. Given the existing static methods the public static function htmlClasses(...$args): string
{
$attributes = HtmlAttributes::merge(['class' => $args]);
return HtmlAttributes::renderAttributes($attributes);
} I'm also interested in your (and @stof) opinion on merging vs replacing on some attributes. I thought using the |
An alternative implementation to #3930
Addresses:
This WIP pr demonstrates a html attribute merging strategy for html attributes, aria-attributes with special handling for
class
,style
data
andaria
attributes.I've currently focussed on the
HtmlAttributes::merge
function which returns the merged attributes array.Examples
See
./Tests/HtmlAttributesTest.php
for usage examplesThe return value of
HtmlAttributes::merge
should also be able to be used as an input forHtmlAttributes::merge
as demonstrated here:https://github.com/twigphp/Twig/pull/4405/files#diff-210291f849102679e6c0a1050d5bcd3076cf55b3cc9677c20fab26dcd15f543cR27-R75
Rendering Attributes
The
HtmlAttributes::renderAttributes
method that takes the output ofHtmlAttributes::merge
and creates the attribute string.This method:
null
attribute valuesclass
,style
anddata-controller
attribute valuesaria-*
boolean attribute values to'true'
'false'
strings.data-*
array valuesfalse
values (seearia-*
coercion above)true
boolean values./Tests/HtmlAttributesTest.php
demonstrate the return value ofHtmlAttributes::merge
andHtmlAttributes::renderAttributes
There was some consideration made to coerce
data-*
boolean values to string'true'
and'false'
but this was decided against. StimulusJs uses the following conditional to determine if adata-*-value
attribute istrue
orfalse
when internally coercing to a javascriptBoolean
.Illustrated here: https://codepen.io/leevigraham/pen/MWNOyLr
Challenges
The challenge with a
html_attributes
like function is that the merging strategy is arbitrary.class
andstyle
attributes are usually merged together. Other attributes override the previous values.Symfony UX twig components recommend Stimulus for interaction. Stimulus uses
data-controller
attributes for functionality. Thedata-controller
value can be a space delimited list of strings. In this case should the multipledata-controller
values be merged or overridden? For StimulusJs also applies todata-target
anddata-action
Alternative implementation ideas
Merge strategy options
Given the challenges with
data-controller
above maybe the method should take 2 arguments:In the example above the
$options
argument would be used to determine which values to merge. Other values would replace.Given the return value of
HtmlAttributes::merge
can also be used as the$attributes
argument ofHtmlAttributes::merge
the developer could callHtmlAttributes::merge
multiple times which would be the equivalent of multiple attribute arrays / argument unpacking.References in other platforms / frameworks:
Yii2 has a similar function: https://github.com/yiisoft/yii2/blob/master/framework/helpers/BaseHtml.php#L1966-L2046
The renderTagAttributes method has the following rules:
'aria' => ['role' => 'checkbox', 'value' => 'true']
would be rendered asaria-role="checkbox" aria-value="true
".'data' => ['params' => ['id' => 1, 'name' => 'yii']]
would be rendered asdata-params='{"id":1,"name":"yii"}
'.CraftCMS uses twig and provides an attr() twig method that implements renderTagAttributes. I've used this helper many times and the rules above are great. Especially the "Attributes whose values are null will not be rendered".
Vuejs v2 -> v3 also went through some changes for false values https://v3-migration.vuejs.org/breaking-changes/attribute-coercion.html. This aligns with "Attributes whose values are null will not be rendered." above.
TODO