BazingaJsTranslationBundle
repository·master·Indexed 20 days ago
https://github.com/willdurand/bazingajstranslationbundleA 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.
What's inside BazingaJsTranslationBundle
- 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.
Use ICU MessageFormat for advanced translations
masterThe bundle supports the ICU MessageFormat for complex logic like dates, numbers, and advanced pluralization.
Requirements:
- You must install the
intl-messageformatlibrary (via NPM or CDN). - Translation files must use the
+intl-icusuffix (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');- You must install the
Configure routing for JsTranslationBundle
masterRegister the bundle's routing in
app/config/routing.yml. This is optional because thedumpcommand 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"Load translations via JSON
masterYou can fetch translations as JSON using the
fetchAPI, jQuery, or other methods by adding the_format=jsonparameter to the URL. Once retrieved, feed the data to the translator usingTranslator.fromJSON().<!-- URL for JSON format --> {{ url('bazinga_jstranslation_js', { '_format': 'json' }) }} <!-- JS usage --> Translator.fromJSON(myRetrievedJSONString);Update Routing and Asset Configuration for 2.0
masterIf 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.ymlfrom@BazingaExposeTranslationBundleto@BazingaJsTranslationBundleand update the route prefix to_bazinga_jstranslation.Asset and URL Updates:
- Update the
asset()path fortranslator.min.jsto usebundles/bazingajstranslation/. - Update the
url()helper for the JS translation route to usebazinga_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>- Update the
Install the JS Translator via NPM (optional)
masterWhile the files are included in the Composer bundle, you can install the package via NPM to manage it as a front-end dependency or to use the
Translatorobject as a module dependency in your JS files.npm install bazinga-translator --saveMigrate from 1.x to 2.0
masterWhen 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-bundletowilldurand/js-translation-bundle. - Bundle Name: Renamed from
BazingaExposeTranslationBundletoBazingaJsTranslationBundle. - Namespace: The namespace has changed to
Bazinga\Bundle\JsTranslationBundle. - Symfony Requirement: Requires Symfony
2.3or higher. - Configuration Root: The configuration key in
config*.ymlhas changed frombazinga_expose_translationtobazinga_js_translation. - Commands: CLI commands have been renamed from
bazinga:expose-translation:*tobazinga:js-translation:*.
// before new \Bazinga\ExposeTranslationBundle\BazingaExposeTranslationBundle() // after new \Bazinga\Bundle\JsTranslationBundle\BazingaJsTranslationBundle()- Package Name: Renamed from
Install JsTranslationBundle via Composer
masterTo install the bundle in a Symfony project, use Composer to require the package and then register the bundle in your
app/AppKernel.phpfile.composer require "willdurand/js-translation-bundle"<?php // app/AppKernel.php public function registerBundles() { return array( // ... new Bazinga\Bundle\JsTranslationBundle\BazingaJsTranslationBundle(), ); }Integrate with AngularJS
masterTo expose Symfony translations to an AngularJS application, use the
angular-symfony-translationmodule. This module acts as the bridge between your Symfony backend and your AngularJS frontend. For detailed setup instructions and usage patterns, refer to the official repository for that module.https://github.com/boxuk/angular-symfony-translationLoad the JS Translator globally or as a module
masterYou can access the
Translatorobject in two ways:- Globally: Add a script tag to your template.
- As a module: Use a bundler like Webpack (requires NPM installation).
Note: Ensure your
<html>tag has alangattribute (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');Load translations via script tags
masterYou 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
domainparameter to load a specific translation domain:<script src="{{ url('bazinga_jstranslation_js', { 'domain': 'DOMAIN_NAME' }) }}"></script>Loading specific locales
Use the
localesquery 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>Configure HTML lang attribute for translations
masterTo ensure the application correctly identifies the current locale for translation purposes, you should add a
langattribute to your root<html>tag using the application's request locale.<html lang="{{ app.request.locale }}">