Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Translatable Form Field Laravel Package

benedicthelfer/translatable-form-field

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require benedicthelfer/translatable-form-field
    

    Register the bundle in AppKernel.php:

    new Bnh\TranslatableFieldBundle\BnhTranslatableFieldBundle(),
    
  2. Configuration Add to config/packages/bnh_translatable_field.yaml:

    bnh_translatable_field:
        default_locale: en_GB
        locales: ['en_GB', 'de_DE']
        templating: 'BnhTranslatableFieldBundle:FormType:bnhtranslations.html.twig'
    
  3. First Use Case Create a translatable entity with Gedmo/Translatable:

    use Gedmo\Mapping\Annotation as Gedmo;
    use Gedmo\Translatable\Translatable;
    
    class Product implements Translatable
    {
        /** @Gedmo\Translatable */
        private $name;
    
        /** @Gedmo\Locale */
        private $locale;
    }
    

    Then, in Sonata Admin, override the form type to use the translatable field:

    $formMapper
        ->add('name', 'bnh_translatable_field', [
            'locales' => ['en_GB', 'de_DE'],
        ]);
    

Implementation Patterns

Workflow for Translatable Fields

  1. Entity Setup

    • Use @Gedmo\Translatable on fields requiring translations.
    • Ensure the entity implements Gedmo\Translatable\Translatable.
    • For personal translations, define a separate Translation entity (e.g., ProductTranslation) with @Gedmo\TranslationEntity.
  2. Sonata Admin Integration Replace standard form fields with bnh_translatable_field:

    $formMapper
        ->add('description', 'bnh_translatable_field', [
            'locales' => $this->getConfigurationPool()->getContainer()->getParameter('bnh_translatable_field.locales'),
            'default_locale' => $this->getConfigurationPool()->getContainer()->getParameter('bnh_translatable_field.default_locale'),
        ]);
    
  3. Dynamic Locale Handling Fetch locales dynamically from config:

    $locales = $this->getConfigurationPool()->getContainer()->getParameter('bnh_translatable_field.locales');
    
  4. Twig Template Overrides Customize the translatable field template by overriding: templates/bnh_translatable_field/bnhtranslations.html.twig Extend the base template (BnhTranslatableFieldBundle:FormType:bnhtranslations.html.twig).

  5. Validation & Localization Use Symfony’s validation constraints with locale-aware messages:

    $builder->add('name', 'bnh_translatable_field')
        ->addConstraint(new NotBlank(), [
            'message' => 'translatable_field.not_blank_{{ locale }}',
        ]);
    

Gotchas and Tips

Pitfalls

  1. Missing Gedmo Extensions Ensure stof/doctrine-extensions-bundle is installed and configured for @Gedmo\Translatable to work:

    # config/packages/doctrine.yaml
    doctrine:
        orm:
            mappings:
                gedmo_translatable:
                    type: attribute
                    prefix: Gedmo\Translatable\Entity\Mapping\Annotation\Legacy
                    dir: "%kernel.project_dir%/vendor/gedmo/doctrine-extensions/src/Entity/Mapping/Annotation/Legacy"
                    alias: GedmoTranslatable
    
  2. Locale Mismatch If translations aren’t saved, verify:

    • The locale field is set in the entity (e.g., via setTranslatableLocale()).
    • The default_locale in config matches the entity’s default locale.
  3. Template Caching Clear Twig cache after overriding templates:

    php bin/console cache:clear
    
  4. Sonata Admin Field Conflicts If the field doesn’t render, ensure:

    • The form type is correctly registered in Sonata’s form_types config.
    • No naming collisions with other field types (e.g., translatable vs. bnh_translatable_field).

Debugging Tips

  1. Check Database Verify translations are stored in the *_translation table (e.g., product_translation):

    SELECT * FROM product_translation WHERE object_id = [ID];
    
  2. Log Locale Switching Add debug logs in the entity’s setTranslatableLocale() to confirm locale assignment:

    public function setTranslatableLocale($locale)
    {
        $this->locale = $locale;
        error_log("Locale set to: {$locale}"); // Debug line
    }
    
  3. Form Data Inspection Dump form data in Sonata’s prePersist() to verify translatable values:

    public function prePersist($entity)
    {
        dump($entity->getName()); // Check if translations are attached
    }
    

Extension Points

  1. Custom Field Types Extend the base field type for specialized behavior:

    class CustomTranslatableFieldType extends AbstractType
    {
        public function configureOptions(OptionsResolver $resolver)
        {
            $resolver->setDefaults([
                'locales' => ['en_GB', 'de_DE'],
                'custom_option' => false,
            ]);
        }
    }
    
  2. Dynamic Locale Selection Fetch locales from a service or database:

    # config/services.yaml
    services:
        App\Service\LocaleProvider:
            arguments:
                $locales: '%env(APP_TRANSLATABLE_LOCALES)%'
    

    Then inject into the form type:

    $formMapper->add('title', 'bnh_translatable_field', [
        'locales' => $this->localeProvider->getLocales(),
    ]);
    
  3. Translation Fallback Implement fallback logic in the entity’s getTranslatedField():

    public function getName()
    {
        if (null === $this->locale) {
            $this->setTranslatableLocale($this->getDefaultLocale());
        }
        return $this->name;
    }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
nasirkhan/laravel-sharekit
directorytree/privacy-filter-classifier
directorytree/privacy-filter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony