Skip to content

Commit

Permalink
[5.x] Refactor Form and SVG tags to use :attr prefix instead of `$k…
Browse files Browse the repository at this point in the history
…nownTagParams` (#9576)
  • Loading branch information
JohnathonKoster authored Feb 26, 2024
1 parent 153f6ca commit 5b07862
Show file tree
Hide file tree
Showing 13 changed files with 51 additions and 81 deletions.
37 changes: 27 additions & 10 deletions src/Tags/Concerns/RendersAttributes.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace Statamic\Tags\Concerns;

use Statamic\Support\Str;

trait RendersAttributes
{
/**
Expand All @@ -14,6 +16,10 @@ protected function renderAttributes($attributes)
{
return collect($attributes)
->map(function ($value, $attribute) {
if (Str::startsWith($attribute, 'attr:')) {
$attribute = mb_substr($attribute, 5);
}

if ($value === null) {
return;
}
Expand All @@ -29,20 +35,31 @@ protected function renderAttributes($attributes)
}

/**
* Render HTML attributes from rest of tag params, except for specifically known params.
* Render HTML attributes from tag params.
*
* Parameters that are not prefixed with attr: will be automatically removed.
*
* @param array $knownTagParams
* @return string
*/
protected function renderAttributesFromParams($knownTagParams = [])
protected function renderAttributesFromParams()
{
$attributes = collect($this->params->all())
->except($knownTagParams)
->mapWithKeys(function ($value, $attribute) {
return [preg_replace('/^attr:/', '', $attribute) => $value];
})
->all();
$params = $this->params->filter(function ($value, $attribute) {
return preg_match('/^attr:/', $attribute);
})->all();

return $this->renderAttributes($params);
}

return $this->renderAttributes($attributes);
/**
* Render HTML attributes and merge attributes from tag params.
*
* @return string
*/
protected function renderAttributesFromParamsWith(array $attrs)
{
return collect([
$this->renderAttributes($attrs),
$this->renderAttributesFromParams(),
])->filter()->implode(' ');
}
}
5 changes: 2 additions & 3 deletions src/Tags/Concerns/RendersForms.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,9 @@ protected function formOpen($action, $method = 'POST', $knownTagParams = [], $ad
$attrs['enctype'] = 'multipart/form-data';
}

$attrs = $this->renderAttributes($attrs);
$paramAttrs = $this->renderAttributesFromParams(array_merge(['method', 'action'], $knownTagParams));
$attrs = $this->renderAttributesFromParamsWith($attrs);

$html = collect(['<form', $attrs, $paramAttrs])->filter()->implode(' ').'>';
$html = collect(['<form', $attrs])->filter()->implode(' ').'>';

if ($this->params->bool('csrf', true)) {
$html .= csrf_field();
Expand Down
2 changes: 1 addition & 1 deletion src/Tags/Svg.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public function index()
$svg = $this->params->get('src');
}

$attributes = $this->renderAttributesFromParams(['src', 'title', 'desc', 'sanitize']);
$attributes = $this->renderAttributesFromParams();

if ($this->params->get('title') || $this->params->get('desc')) {
$svg = $this->setTitleAndDesc($svg);
Expand Down
2 changes: 1 addition & 1 deletion tests/Fieldtypes/IconTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public function it_finds_default_icons()
/** @test */
public function it_accepts_svg_strings()
{
$result = (string) Antlers::parse('{{ svg :src="test" class="w-4 h-4" sanitize="false" }}', ['test' => new Value('add', $this->fieldtype())]);
$result = (string) Antlers::parse('{{ svg :src="test" attr:class="w-4 h-4" sanitize="false" }}', ['test' => new Value('add', $this->fieldtype())]);

$this->assertStringContainsString('<svg class="w-4 h-4"', $result);
}
Expand Down
70 changes: 12 additions & 58 deletions tests/Tags/Concerns/RendersAttributesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ public function it_renders_attributes_from_array()
$this->assertEquals('', $this->tag->renderAttributes([]));

$output = $this->tag->renderAttributes([
'class' => 'm-0 mb-2',
':name' => 'first_name',
'disabled' => 'true',
'autocomplete' => true,
'focusable' => false,
'dont_render_nulls' => null,
'attr:class' => 'm-0 mb-2',
'attr::name' => 'first_name',
'attr:disabled' => 'true',
'attr:autocomplete' => true,
'attr:focusable' => false,
'attr:dont_render_nulls' => null,
]);

$this->assertEquals('class="m-0 mb-2" :name="first_name" disabled="true" autocomplete="true" focusable="false"', $output);
Expand All @@ -43,64 +43,18 @@ public function it_renders_attributes_from_params()
$output = $this->tag
->setContext(['first_name' => 'Han'])
->setParameters([
'class' => 'm-0 mb-2',
':name' => 'first_name',
'attr:class' => 'm-0 mb-2',
':attr:name' => 'first_name',
'attr:src' => 'avatar.jpg',
'focusable' => false,
'dont_render_nulls' => null,
'disabled' => 'true',
'autocomplete' => true,
'attr:focusable' => false,
'attr:dont_render_nulls' => null,
'attr:disabled' => 'true',
'attr:autocomplete' => true,
])
->renderAttributesFromParams();

$this->assertEquals('class="m-0 mb-2" name="Han" src="avatar.jpg" focusable="false" disabled="true" autocomplete="true"', $output);
}

/** @test */
public function it_wont_render_attributes_for_known_params_unless_attr_prepended()
{
$output = $this->tag
->setParameters([
'class' => 'm-0 mb-2',
'src' => 'avatar.jpg',
'name' => 'Han',
])
->renderAttributesFromParams(['src', 'name']);

$this->assertEquals('class="m-0 mb-2"', $output);

$output = $this->tag
->setParameters([
'class' => 'm-0 mb-2',
'attr:src' => 'avatar.jpg',
'name' => 'Han',
])
->renderAttributesFromParams(['src', 'name']);

$this->assertEquals('class="m-0 mb-2" src="avatar.jpg"', $output);
}

/** @test */
public function it_will_render_falsy_attributes()
{
$this->assertEquals('', $this->tag->renderAttributesFromParams());

$output = $this->tag
->setContext(['first_name' => 'Han'])
->setParameters([
'class' => 'm-0 mb-2',
':name' => 'first_name',
'attr:src' => 'avatar.jpg',
'focusable' => false,
'dont_render_nulls' => null,
'disabled' => 'true',
'autocomplete' => true,
'aria-hidden' => true,
])
->renderAttributesFromParams();

$this->assertEquals('class="m-0 mb-2" name="Han" src="avatar.jpg" focusable="false" disabled="true" autocomplete="true" aria-hidden="true"', $output);
}
}

class FakeTagWithRendersAttributes extends Tags
Expand Down
2 changes: 1 addition & 1 deletion tests/Tags/Concerns/RendersFormsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public function it_renders_form_open_tags_with_custom_attributes()
{
$output = $this->tag
->setParameters([
'class' => 'mb-2',
'attr:class' => 'mb-2',
'attr:id' => 'form',
'method' => 'this should not render',
'action' => 'this should not render',
Expand Down
2 changes: 1 addition & 1 deletion tests/Tags/Form/FormCreateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public function it_renders_form()
/** @test */
public function it_renders_form_with_params()
{
$output = $this->tag('{{ form:contact redirect="/submitted" error_redirect="/errors" class="form" id="form" }}{{ /form:contact }}');
$output = $this->tag('{{ form:contact redirect="/submitted" error_redirect="/errors" attr:class="form" attr:id="form" }}{{ /form:contact }}');

$this->assertStringStartsWith('<form method="POST" action="http://localhost/!/forms/contact" class="form" id="form">', $output);
$this->assertStringContainsString('<input type="hidden" name="_redirect" value="/submitted" />', $output);
Expand Down
2 changes: 1 addition & 1 deletion tests/Tags/SvgTagTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public function it_renders_svg()
/** @test */
public function it_renders_svg_with_additional_params()
{
$this->assertStringStartsWith('<svg class="mb-2" xmlns="', $this->tag('{{ svg src="users" sanitize="false" class="mb-2" }}'));
$this->assertStringStartsWith('<svg class="mb-2" xmlns="', $this->tag('{{ svg src="users" sanitize="false" attr:class="mb-2" }}'));
}

/** @test */
Expand Down
2 changes: 1 addition & 1 deletion tests/Tags/User/ForgotPasswordFormTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public function it_renders_form()
/** @test */
public function it_renders_form_with_params()
{
$output = $this->tag('{{ user:forgot_password_form redirect="/submitted" error_redirect="/errors" reset_url="/resetting" class="form" id="form" }}{{ /user:forgot_password_form }}');
$output = $this->tag('{{ user:forgot_password_form redirect="/submitted" error_redirect="/errors" reset_url="/resetting" attr:class="form" attr:id="form" }}{{ /user:forgot_password_form }}');

$this->assertStringStartsWith('<form method="POST" action="http://localhost/!/auth/password/email" class="form" id="form">', $output);
$this->assertStringContainsString('<input type="hidden" name="_redirect" value="/submitted" />', $output);
Expand Down
2 changes: 1 addition & 1 deletion tests/Tags/User/LoginFormTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public function it_renders_form()
/** @test */
public function it_renders_form_with_params()
{
$output = $this->tag('{{ user:login_form redirect="/submitted" error_redirect="/errors" class="form" id="form" }}{{ /user:login_form }}');
$output = $this->tag('{{ user:login_form redirect="/submitted" error_redirect="/errors" attr:class="form" attr:id="form" }}{{ /user:login_form }}');

$this->assertStringStartsWith('<form method="POST" action="http://localhost/!/auth/login" class="form" id="form">', $output);
$this->assertStringContainsString('<input type="hidden" name="_redirect" value="/submitted" />', $output);
Expand Down
2 changes: 1 addition & 1 deletion tests/Tags/User/PasswordFormTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public function it_renders_form_with_params()
{
$this->actingAs(User::make()->password('mypassword')->save());

$output = $this->tag('{{ user:password_form redirect="/submitted" error_redirect="/errors" class="form" id="form" }}{{ /user:password_form }}');
$output = $this->tag('{{ user:password_form redirect="/submitted" error_redirect="/errors" attr:class="form" attr:id="form" }}{{ /user:password_form }}');

$this->assertStringStartsWith('<form method="POST" action="http://localhost/!/auth/password" class="form" id="form">', $output);
$this->assertStringContainsString('<input type="hidden" name="_redirect" value="/submitted" />', $output);
Expand Down
2 changes: 1 addition & 1 deletion tests/Tags/User/ProfileFormTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public function it_renders_form_with_params()
{
$this->actingAs(User::make()->save());

$output = $this->tag('{{ user:profile_form redirect="/submitted" error_redirect="/errors" class="form" id="form" }}{{ /user:profile_form }}');
$output = $this->tag('{{ user:profile_form redirect="/submitted" error_redirect="/errors" attr:class="form" attr:id="form" }}{{ /user:profile_form }}');

$this->assertStringStartsWith('<form method="POST" action="http://localhost/!/auth/profile" class="form" id="form">', $output);
$this->assertStringContainsString('<input type="hidden" name="_redirect" value="/submitted" />', $output);
Expand Down
2 changes: 1 addition & 1 deletion tests/Tags/User/RegisterFormTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public function it_renders_form()
/** @test */
public function it_renders_form_with_params()
{
$output = $this->tag('{{ user:register_form redirect="/submitted" error_redirect="/errors" class="form" id="form" }}{{ /user:register_form }}');
$output = $this->tag('{{ user:register_form redirect="/submitted" error_redirect="/errors" attr:class="form" attr:id="form" }}{{ /user:register_form }}');

$this->assertStringStartsWith('<form method="POST" action="http://localhost/!/auth/register" class="form" id="form">', $output);
$this->assertStringContainsString('<input type="hidden" name="_redirect" value="/submitted" />', $output);
Expand Down

0 comments on commit 5b07862

Please sign in to comment.