Skip to content

Commit

Permalink
Support symfony TranslatableInterface in enum fields
Browse files Browse the repository at this point in the history
  • Loading branch information
zyberspace committed Nov 13, 2024
1 parent 89953cf commit f7687fb
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 5 deletions.
58 changes: 53 additions & 5 deletions docs/reference/field_types.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Fieldtype Description
``FieldDescriptionInterface::TYPE_DATETIME`` display a formatted date and time. Accepts the options ``format`` and ``timezone``
``FieldDescriptionInterface::TYPE_STRING`` display a text
``FieldDescriptionInterface::TYPE_EMAIL`` display a mailto link. Accepts the options ``as_string``, ``subject`` and ``body``
``FieldDescriptionInterface::TYPE_ENUM`` display the name of a backed enum
``FieldDescriptionInterface::TYPE_ENUM`` display an enum
``FieldDescriptionInterface::TYPE_TEXTAREA`` display a textarea
``FieldDescriptionInterface::TYPE_TRANS`` translate the value with a provided ``value_translation_domain`` and ``format`` (sprintf format) option
``FieldDescriptionInterface::TYPE_FLOAT`` display a number
Expand Down Expand Up @@ -199,13 +199,61 @@ The ``FieldDescriptionInterface::TYPE_CHOICE`` field type also supports multiple

You can use the following options:

====================================== ==============================================================
====================================== ========================================================================
Option Description
====================================== ==============================================================
====================================== ========================================================================
**use_value** Determines if the field must show the value or the case' name.
``false`` by default.
**enum_translation_domain** Translation domain.
====================================== ==============================================================

*Ignored if the enum implements Symfony's* ``TranslatableInterface`` *.*
**enum_translation_domain** | Translation domain. If set, the enum value or case' name will be send
to the translator.
| ``{{ value|trans({}, translation_domain) }}``

*Ignored if the enum implements Symfony's* ``TranslatableInterface`` *.*
====================================== ========================================================================

.. note::

If the enum implements Symfony's ``TranslatableInterface`` the options above will be ignored and the enum's
``trans()`` method will be used instead to display the enum.

This provides full compatibility with symfony's
`EnumType <https://symfony.com/doc/current/reference/forms/types/enum.html>`_ form type:

.. code-block:: php

Check failure on line 224 in docs/reference/field_types.rst

View workflow job for this annotation

GitHub Actions / DOCtor-RST

Please do not use ".. code-block:: php", use "::" instead.
protected function configureListFields(ListMapper $list): void
{
$list
// Sonata Admin will select the `FieldDescriptionInterface::TYPE_ENUM`
// field type automatically. If the enum implements `TranslatableInterface`,
// the `trans()` method will be used to render its value.
->add('saluation')
;
}
protected function configureFormFields(FormMapper $form): void
{
$form
// Symfony's EnumType form field will automatically detect the usage of
// the `TranslatableInterface` and use the enum's `trans()` method to
// render the choice labels.
->add('salutation', EnumType::class, [
'class' => Salutation::class,
])
;
}
protected function configureShowFields(ShowMapper $show): void
{
$show
// Again, Sonata Admin will select the `FieldDescriptionInterface::TYPE_ENUM`
// field type automatically. If the enum implements `TranslatableInterface`,
// the `trans()` method will be used to render its value.
->add('salutation')
;
}
``FieldDescriptionInterface::TYPE_URL``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
3 changes: 3 additions & 0 deletions src/Resources/views/CRUD/display_enum.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ file that was distributed with this source code.
{%- apply spaceless %}
{% if value is null %}
&nbsp;
{% elseif value.trans is defined %}
{# Enum implements TranslatableInterface and therefore has direct control over how it should be displayed. #}
{{ value|trans }}
{% else %}
{% set value = use_value|default(false) ? value.value : value.name %}

Expand Down
35 changes: 35 additions & 0 deletions tests/Fixtures/Enum/TranslatableSuit.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

/*
* This file is part of the Sonata Project package.
*
* (c) Thomas Rabaix <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Sonata\AdminBundle\Tests\Fixtures\Enum;

use Symfony\Contracts\Translation\TranslatableInterface;
use Symfony\Contracts\Translation\TranslatorInterface;

enum TranslatableSuit: string implements TranslatableInterface
{
case Hearts = 'hearts';
case Diamonds = 'diamonds';
case Clubs = 'clubs';
case Spades = 'spades';

#[\Override]
public function trans(TranslatorInterface $translator, ?string $locale = null): string
{
return $translator->trans(
id: 'enum.suit.'.$this->value,
domain: 'render-element-extension-test',
locale: $locale,
);
}
}
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
D: '[trans]D[/trans]'
Diamonds: '[trans]Diamonds[/trans]'
enum:
suit:
hearts: '[trans]enum.suit.hearts[/trans]'
diamonds: '[trans]enum.suit.diamonds[/trans]'
clubs: '[trans]enum.suit.clubs[/trans]'
spades: '[trans]enum.suit.spades[/trans]'
19 changes: 19 additions & 0 deletions tests/Twig/Extension/RenderElementExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use Sonata\AdminBundle\Templating\TemplateRegistryInterface;
use Sonata\AdminBundle\Tests\Fixtures\Entity\FooToString;
use Sonata\AdminBundle\Tests\Fixtures\Enum\Suit;
use Sonata\AdminBundle\Tests\Fixtures\Enum\TranslatableSuit;
use Sonata\AdminBundle\Tests\Fixtures\StubFilesystemLoader;
use Sonata\AdminBundle\Twig\Extension\RenderElementExtension;
use Sonata\AdminBundle\Twig\Extension\XEditableExtension;
Expand Down Expand Up @@ -1579,6 +1580,24 @@ class="x-editable"
],
];

$elements[] = [
'<td class="sonata-ba-list-field sonata-ba-list-field-enum" objectId="12345"> [trans]enum.suit.hearts[/trans] </td>',
FieldDescriptionInterface::TYPE_ENUM,
TranslatableSuit::Hearts,
[],
];

$elements[] = [
'<td class="sonata-ba-list-field sonata-ba-list-field-enum" objectId="12345"> [trans]enum.suit.spades[/trans] </td>',
FieldDescriptionInterface::TYPE_ENUM,
TranslatableSuit::Spades,
[
// These values are ignored if the enum implements the TranslatableInterface
'use_value' => false,
'enum_translation_domain' => 'doesnt-exist',
],
];

return $elements;
}

Expand Down

0 comments on commit f7687fb

Please sign in to comment.