A pretty nice way to expose your translated messages to your JavaScript.
Warning:
- The PHP code of this bundle is not unit tested, so don't use it or provides tests if you want to contribute.
## Prerequisite
The famous JavaScript framework jQuery is mandatory.
## Installation
As usual, add this bundle to your submodules:
git submodule add git://github.com/Bazinga/BazingaExposeTranslationBundle.git vendor/bundles/Bazinga/ExposeTranslationBundle
Register the namespace in app/autoload.php
:
<?php
// app/autoload.php
$loader->registerNamespaces(array(
// ...
'Bazinga' => __DIR__.'/../vendor/bundles',
));
Register the bundle in app/AppKernel.php
:
<?php
// app/AppKernel.php
public function registerBundles()
{
return array(
// ...
new Bazinga\ExposeTranslationBundle\BazingaExposeTranslationBundle(),
);
}
Register the routing in app/config/routing.yml
:
# app/config/routing.yml
_bazinga_exposetranslation:
resource: "@BazingaExposeTranslationBundle/Resources/config/routing/routing.yml"
Publish assets:
php app/console assets:install --symlink web
Just add this line in your layout:
<script type="text/javascript" src="{{ asset('bundles/bazingaexposetranslation/js/translation.js') }}"></script>
Now, you just have to specify which translation files to load. But how to do that ?
Just by adding a line as below:
<script type="text/javascript" src="{{ url('bazinga_exposetranslation_js') }}"></script>
This will use the current locale
and will provide translated messages found in each messages.CURRENT_LOCALE.*
files of your project.
<script type="text/javascript" src="{{ url('bazinga_exposetranslation_js', { 'domain_name': 'DOMAIN_NAME' }) }}"></script>
This will use the current locale
and will provide translated messages found in each DOMAIN_NAME.CURRENT_LOCALE.*
files of your project.
You can specify a locale
to use for translation if you want, just add the _locale
parameter:
<script type="text/javascript" src="{{ url('bazinga_exposetranslation_js', { 'domain_name': 'DOMAIN_NAME', '_locale' : 'MY_LOCALE' }) }}"></script>
This will provide translated messages found in each DOMAIN_NAME.MY_LOCALE.*
files of your project.
It's quite simple:
ExposeTranslation.has('DOMAIN_NAME:key');
// true or false
ExposeTranslation.get('DOMAIN_NAME:key');
// the translated message or undefined
If you don't specify any domain, a guesser is provided to find the best translated message for the given key
.
To configure the guesser, you have to set the defaultDomains
attribute. By default, the configured default domain is messages
.
ExposeTranslation.get('key');
// will try to find a translated message in default domains.
Note: this will only work if default domains are previously loaded (see the Load translation domains first section).
Read the official documentation about Symfony2 message placeholders.
The get()
method accepts a second argument that takes placeholders without %
delimiters:
ExposeTranslation.get('DOMAIN_NAME:key', { "foo" : "bar" });
// will replace each "%foo%" in the message by "bar".
You can override the placeholder delimiters by setting the placeHolderSuffix
and placeHolderPrefix
attributes.
Probably the best feature provided in this bundle ! It allows you to use pluralization exactly like you can do in Symfony2.
Read the official doc about pluralization.
A third parameter can be added to the get()
method, it's the number of objects being described. Here is an example:
# app/Resources/messages.en.yml
apples: "{0} There is no apples|{1} There is one apple|]1,19] There are %count% apples|[20,Inf] There are many apples"
ExposeTranslation.locale = 'en';
ExposeTranslation.get('apples', {"count" : 0}, 0);
// will return "There is no apples"
ExposeTranslation.get('apples', {"count" : 1}, 1);
// will return "There is one apple"
ExposeTranslation.get('apples', {"count" : 2}, 2);
// will return "There are 2 apples"
ExposeTranslationExposeTranslation.get('apples', {"count" : 10}, 10);
// will return "There are 10 apples"
ExposeTranslation.get('apples', {"count" : 19}, 19);
// will return "There are 19 apples"
ExposeTranslation.get('apples', {"count" : 20}, 20);
// will return "There are many apples"
ExposeTranslation.get('apples', {"count" : 100}, 100);
// will return "There are many apples"
Note: This is not tested at the moment. It works fine for english/french translations.
You can get the current locale by accessing the locale
attribute:
ExposeTranslation.locale;
// will return the current locale.
Consider the following translation files:
# app/Resources/translations/Hello.fr.yml
foo: "Bar"
ba:
bar: "Hello world"
placeholder: "Hello %username% !"
# app/Resources/translations/messages.fr.yml
placeholder: "Hello %username%, how are you ?"
You can do:
ExposeTranslation.get('Hello:foo');
// will return 'Bar' if the current locale is set to 'fr', undefined otherwise.
ExposeTranslation.get('Hello:ba.bar');
// will return 'Hello world' if the current locale is set to 'fr', undefined otherwise.
ExposeTranslation.get('Hello:placeholder');
// will return 'Hello %username% !' if the current locale is set to 'fr', undefined otherwise.
ExposeTranslation.get('Hello:placeholder', { "username" : "will" });
// will return 'Hello will !' if the current locale is set to 'fr', undefined otherwise.
ExposeTranslation.get('placeholder', { "username" : "will" });
// will return 'Hello will, how are you ?' if the current locale is set to 'fr', undefined otherwise.
ExposeTranslation.get('placeholder');
// will return 'Hello %username%, how are you ?' if the current locale is set to 'fr', undefined otherwise.
You can easily add your own default domains by adding these lines in your app/config/config*.yml
files:
bazinga_expose_translation:
default_domains: [ messages ]
Note: You still have to include a <script>
tag to expose messages but you avoid writing domain names before each of your keys.
- William DURAND (Bazinga) as main author.
- Jan Sorgalla as contributor.
- Stan Chollet as contributor.