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

Cms Translation Bundle Laravel Package

canabelle/cms-translation-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the bundle via Composer:

    composer require canabelle/cms-translation-bundle
    

    Enable the bundle in config/bundles.php (Symfony):

    Canabelle\CMSTranslationBundle\CanabelleCMSTranslationBundle::class => ['all' => true],
    
  2. Configuration Publish the default config:

    php artisan vendor:publish --tag=cms-translation-config
    

    Update config/cms_translation.php with your preferred locales (e.g., ['en', 'fr']).

  3. First Use Case: Translating a Page

    • Create a Page entity with a title field (string) and a content field (text).
    • Add translation fields to the entity:
      /**
       * @ORM\Column(type="string", length=255)
       * @Assert\NotBlank()
       */
      private $title;
      
      /**
       * @ORM\Column(type="text")
       */
      private $content;
      
      // Add translation mappings (if using Doctrine Extensions)
      public function __toString() { return $this->title; }
      
    • Use the bundle’s translation service to fetch localized content:
      use Canabelle\CMSTranslationBundle\Service\TranslationService;
      
      $translationService = $this->container->get('cms_translation.service');
      $page = $translationService->getTranslatedPage($pageId, $locale);
      

Implementation Patterns

Workflow: Localization Pipeline

  1. Content Creation

    • Store base content in the default locale (e.g., en).
    • Use the bundle’s TranslationManager to generate translation tasks:
      $translationManager = $this->container->get('cms_translation.manager');
      $translationManager->createTranslationTask($page, ['fr', 'es']);
      
  2. Translation Workflow

    • Implement a TranslationListener to hook into events (e.g., postPersist):
      use Canabelle\CMSTranslationBundle\Event\TranslationEvent;
      
      public function onTranslationEvent(TranslationEvent $event) {
          // Send to a translation API or queue for manual review
      }
      
    • Register the listener in services.yaml:
      services:
          App\EventListener\TranslationListener:
              tags:
                  - { name: 'kernel.event_listener', event: 'cms_translation.send', method: 'onTranslationEvent' }
      
  3. Rendering Localized Content

    • Use a Twig extension to dynamically switch locales:
      {{ cms_translation(page, app.request.locale) }}
      
    • Or fetch translations in a controller:
      $translatedTitle = $translationService->translateField($page, 'title', $locale);
      

Integration Tips

  • Doctrine Extensions: If using Gedmo\Translation, ensure the bundle’s TranslationListener doesn’t conflict with existing translation logic. Disable one or merge strategies.
  • APIs: For headless CMS, expose translated fields via API resources:
    public function toArray($request) {
        return [
            'title' => $this->title->translated[$request->locale],
            'content' => $this->content->translated[$request->locale],
        ];
    }
    
  • Fallback Logic: Configure fallback locales in config/cms_translation.php:
    'fallback_locale' => 'en',
    

Gotchas and Tips

Pitfalls

  1. Outdated Dependencies

    • The bundle relies on Symfony 3.x and Doctrine ORM 2.5+. If using newer versions, expect compatibility issues (e.g., EventDispatcher changes).
    • Fix: Override the TranslationService to adapt to your Symfony version.
  2. Translation Field Naming

    • The bundle assumes fields like title_translations (for Gedmo\Translation). If using custom field names, configure the translation_field_suffix in the config:
      'translation_field_suffix' => '_i18n',
      
  3. Circular Dependencies

    • If translating entities that reference each other (e.g., Page has Category, which also needs translation), the bundle may not handle this natively.
    • Fix: Implement a custom TranslationStrategy for recursive entities.
  4. Performance with Large Content

    • Fetching all translations for a page can be slow. Use DQL or repository methods to limit loaded fields:
      $page = $entityManager->getRepository(Page::class)
          ->createQueryBuilder('p')
          ->leftJoin('p.titleTranslations', 'tt')
          ->where('tt.locale = :locale')
          ->setParameter('locale', $locale)
          ->getQuery()
          ->getOneById($pageId);
      

Debugging

  • Missing Translations: Check if the TranslationListener is registered and fired. Add logging:
    public function onTranslationEvent(TranslationEvent $event) {
        \Log::debug('Translation event triggered for entity:', [$event->getEntity()->getId()]);
    }
    
  • Locale Switching: Verify the locale is set in the request (e.g., via RequestStack). Override the LocaleListener if needed.

Extension Points

  1. Custom Translation Sources

    • Extend the TranslationService to support non-Doctrine sources (e.g., JSON files):
      class CustomTranslationService extends TranslationService {
          public function getTranslatedContent($key, $locale) {
              return json_decode(file_get_contents("translations/{$locale}/{$key}.json"));
          }
      }
      
    • Register the service in services.yaml:
      services:
          App\Service\CustomTranslationService:
              decorates: 'cms_translation.service'
              arguments: ['@custom_translation_service.inner']
      
  2. Translation Validation

    • Add validation constraints to translated fields:
      use Symfony\Component\Validator\Constraints as Assert;
      
      /**
       * @Assert\Length(max=500)
       */
      private $content;
      
    • The bundle will validate translations during prePersist/preUpdate if the ValidationListener is enabled.
  3. Bulk Translation

    • Use the TranslationManager to batch-create translation tasks:
      $pages = $entityManager->getRepository(Page::class)->findAll();
      foreach ($pages as $page) {
          $translationManager->createTranslationTask($page, ['fr']);
      }
      
    • Process tasks asynchronously with a queue worker (e.g., Symfony Messenger).
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.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle