Skip to content

[TwigComponent] PreMount VS required props #1686

Closed
@cavasinf

Description

@cavasinf

First time using TwigComponent, but works like a charm good job 👍
I've stumbled upon a case that I can't accomplish without feeling like "it's too much code".

Simple case:

  • Required props title.
  • Pass Entity to the props which is Stringable.
  • Component used like this:
    <twig:DropdownHeaderItem title="{{ app.user }}"/>

Here's the Component:

// src/Twig/Components/DropdownHeaderItem.php

#[AsTwigComponent]
final class DropdownHeaderItem extends DropdownItem
{
    public string $title;
}

And his twig:

{# templates/components/DropdownHeaderItem.html.twig #}

<h6
        {{ attributes }}
        class="dropdown-header {{ this.extraClass }}" {{ macros.attr_to_html(this.attr) }}
>
    {{ this.title }}
</h6>

Sadly, this is not enough to make the title option required AND with an explicit error message.
If you call the component with no parameters:

<twig:DropdownHeaderItem/>

This is the error that is displayed:
image

Two problems:

  1. It show the error INSIDE his component template and not where it is used.
  2. The stack trace (as usual with twig) doesn't show where the error occured in twig (only controller with ->render()...)

Looking at the doc, we should use PreMount hook with the OptionsResolver like this:

#[AsTwigComponent]
final class DropdownHeaderItem extends DropdownItem
{
    public string $title;

    #[PreMount]
    public function preMount(array $data): array
    {
        $resolver = new OptionsResolver();
        $resolver->setRequired('title');
        $resolver->setAllowedTypes('title', ['string', \Stringable::class]);

        return $resolver->resolve($data);
    }
}

I'm not a fan of that because:

  1. Nowadays we can do a lot with only PHP8 (declarations/types/attributes) for simple cases.
    PHP auto __toString() call if property typed to string when class implements the method.
  2. The string reference 'title' to the property $title (maintainability).
  3. You need to declare ALL other properties, otherwise you'll get The option "xxxx" does not exist
  4. All the default value from the PHP declaration, need to be redefined IN the OptionsResolver.
  5. +9 lines of code just for a required.

Is there any limitation, to not be able to print required error without the OptionResolver?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions