BazingaJsTranslationBundle

repository·master·Indexed 20 days ago

https://github.com/willdurand/bazingajstranslationbundle

A Symfony bundle that exposes server-side translation messages to client-side JavaScript applications. It provides a bridge to use existing Symfony translations in the frontend, featuring a CLI tool (`bazinga:js-translation:dump`) to export messages to JS or JSON files, and a JavaScript Translator API (available via NPM as `bazinga-translator`) that supports placeholder replacement, pluralization via `transChoice`, and ICU MessageFormat.

Tokens
5.9K
Snippets
22
Records
25
Agent score
68%

What's inside BazingaJsTranslationBundle

  1. Overview of JsTranslationBundle

    master
    JsTranslationBundle is a Symfony bundle designed to expose your Symfony translation messages to client-side applications (such as JavaScript frameworks). It provides a bridge between the server-side translation files and the client-side environment, allowing you to use your existing Symfony translations in your frontend code.
  2. Use ICU MessageFormat for advanced translations

    master

    The bundle supports the ICU MessageFormat for complex logic like dates, numbers, and advanced pluralization.

    Requirements:

    • You must install the intl-messageformat library (via NPM or CDN).
    • Translation files must use the +intl-icu suffix (e.g., messages+intl-icu.en.yaml).

    Example YAML:

    name_has_x_projects: {name} has {projectCount, plural, =0 {no projects} one {# project} other {# projects}}

    Example JS:

    Translator.trans('name_has_x_projects', { name: 'John', projectCount: 1 }, 'messages');
    // returns "John has 1 project."
    // Requires intl-messageformat library
    Translator.trans('hello_name', { name: 'John' }, 'messages');
  3. Configure routing for JsTranslationBundle

    master

    Register the bundle's routing in app/config/routing.yml. This is optional because the dump command does not depend on the router component, but it is required for the automatic translation loading via URLs.

    # app/config/routing.yml
    _bazinga_jstranslation:
        resource: "@BazingaJsTranslationBundle/Resources/config/routing/routing.yml"
  4. Load translations via JSON

    master

    You can fetch translations as JSON using the fetch API, jQuery, or other methods by adding the _format=json parameter to the URL. Once retrieved, feed the data to the translator using Translator.fromJSON().

    <!-- URL for JSON format -->
    {{ url('bazinga_jstranslation_js', { '_format': 'json' }) }}
    
    <!-- JS usage -->
    Translator.fromJSON(myRetrievedJSONString);
  5. Update Routing and Asset Configuration for 2.0

    master

    If upgrading to 2.0, you must update your routing definitions and asset paths to reflect the new bundle name and routing keys.

    Routing Update: Change the resource import in app/config/routing.yml from @BazingaExposeTranslationBundle to @BazingaJsTranslationBundle and update the route prefix to _bazinga_jstranslation.

    Asset and URL Updates:

    • Update the asset() path for translator.min.js to use bundles/bazingajstranslation/.
    • Update the url() helper for the JS translation route to use bazinga_jstranslation_js.
    # app/config/routing.yml
    
    # after
    _bazinga_jstranslation:
        resource: "@BazingaJsTranslationBundle/Resources/config/routing/routing.yml"
    <!-- Asset path update -->
    <script src="{{ asset('bundles/bazingajstranslation/js/translator.min.js') }}"></script>
    
    <!-- URL helper update -->
    <script src="{{ url('bazinga_jstranslation_js') }}"></script>
  6. Migrate from 1.x to 2.0

    master

    When upgrading from version 1.x to 2.0, several breaking changes occur regarding package names, namespaces, and configuration.

    Key Changes:

    • Package Name: Renamed from willdurand/expose-translation-bundle to willdurand/js-translation-bundle.
    • Bundle Name: Renamed from BazingaExposeTranslationBundle to BazingaJsTranslationBundle.
    • Namespace: The namespace has changed to Bazinga\Bundle\JsTranslationBundle.
    • Symfony Requirement: Requires Symfony 2.3 or higher.
    • Configuration Root: The configuration key in config*.yml has changed from bazinga_expose_translation to bazinga_js_translation.
    • Commands: CLI commands have been renamed from bazinga:expose-translation:* to bazinga:js-translation:*.
    // before
    new \Bazinga\ExposeTranslationBundle\BazingaExposeTranslationBundle()
    
    // after
    new \Bazinga\Bundle\JsTranslationBundle\BazingaJsTranslationBundle()
  7. Install JsTranslationBundle via Composer

    master

    To install the bundle in a Symfony project, use Composer to require the package and then register the bundle in your app/AppKernel.php file.

    composer require "willdurand/js-translation-bundle"
    <?php
    // app/AppKernel.php
    public function registerBundles()
    {
        return array(
            // ...
            new Bazinga\Bundle\JsTranslationBundle\BazingaJsTranslationBundle(),
        );
    }
  8. Load the JS Translator globally or as a module

    master

    You can access the Translator object in two ways:

    1. Globally: Add a script tag to your template.
    2. As a module: Use a bundler like Webpack (requires NPM installation).

    Note: Ensure your <html> tag has a lang attribute (e.g., <html lang="en">) so the translator can automatically detect the locale.

    <!-- Global loading -->
    <script src="{{ asset('bundles/bazingajstranslation/js/translator.min.js') }}"></script>
    
    <!-- Module loading (ES2015) -->
    import Translator from 'bazinga-translator';
    
    <!-- Module loading (ES5) -->
    var Translator = require('bazinga-translator');
  9. Load translations via script tags

    master

    You can load translations by adding a script tag that points to the bundle's translation URL. This automatically loads messages for the current locale.

    Basic usage

    <script src="{{ url('bazinga_jstranslation_js') }}"></script>

    Loading specific domains

    Use the domain parameter to load a specific translation domain:

    <script src="{{ url('bazinga_jstranslation_js', { 'domain': 'DOMAIN_NAME' }) }}"></script>

    Loading specific locales

    Use the locales query parameter to load one or multiple languages (comma-separated):

    <!-- Single locale -->
    <script src="{{ url('bazinga_jstranslation_js', { 'domain': 'DOMAIN_NAME', 'locales': 'MY_LOCALE' }) }}"></script>
    
    <!-- Multiple locales -->
    <script src="{{ url('bazinga_jstranslation_js', { 'domain': 'DOMAIN_NAME', 'locales': 'fr,en' }) }}"></script>
    <!-- Example: Loading multiple locales for a specific domain -->
    <script src="{{ url('bazinga_jstranslation_js', { 'domain': 'admin', 'locales': 'fr,en' }) }}"></script>