-
-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Translation custom loaders #4166
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
8b6c584
dee7fb2
e2fd5fa
105a168
bfd78b3
629a008
c0f3b0a
69491ae
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
.. index:: | ||
single: Translation; Adding Custom Format Support | ||
|
||
Adding Custom Format Support | ||
============================ | ||
|
||
Sometimes, you need to deal with custom formats for translation files. The | ||
Translation component is flexible enough to support this. Just create a | ||
loader (to load translations) and, optionally, a dumper (to dump translations). | ||
|
||
Imagine that you have a custom format where translation messages are defined | ||
using one line for each translation and parentheses to wrap the key and the | ||
message. A translation file would look like this: | ||
|
||
.. code-block:: text | ||
|
||
(welcome)(accueil) | ||
(goodbye)(au revoir) | ||
(hello)(bonjour) | ||
|
||
Creating a Custom Loader | ||
------------------------ | ||
|
||
To define a custom loader that is able to read this kind of files, you must create a | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ... these kind of files ... |
||
new class that implements the | ||
:class:`Symfony\\Component\\Translation\\Loader\\LoaderInterface`. The | ||
:method:`Symfony\\Component\\Translation\\Loader\\LoaderInterface::load` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think listing the methods of the interface is needed in this paragraph. Implementing an inteface involves implementing all its methods. |
||
method will get a filename and parse it into an array. Then, it will | ||
create the catalog that will be returned:: | ||
|
||
use Symfony\Component\Translation\MessageCatalogue; | ||
use Symfony\Component\Translation\Loader\LoaderInterface; | ||
|
||
class MyFormatLoader implements LoaderInterface | ||
{ | ||
public function load($resource, $locale, $domain = 'messages') | ||
{ | ||
$messages = array(); | ||
$lines = file($resource); | ||
|
||
foreach ($lines as $line) { | ||
if (preg_match('/\(([^\)]+)\)\(([^\)]+)\)/', $line, $matches)) { | ||
$messages[$matches[1]] = $matches[2]; | ||
} | ||
} | ||
|
||
$catalogue = new MessageCatalogue($locale); | ||
$catalogue->add($messages, $domain); | ||
|
||
return $catalogue; | ||
} | ||
|
||
} | ||
|
||
Once created, it can be used as any other loader:: | ||
|
||
use Symfony\Component\Translation\Translator; | ||
|
||
$translator = new Translator('fr_FR'); | ||
$translator->addLoader('my_format', new MyFormatLoader()); | ||
|
||
$translator->addResource('my_format', __DIR__.'/translations/messages.txt', 'fr_FR'); | ||
|
||
echo $translator->trans('welcome'); | ||
|
||
It will print *"accueil"*. | ||
|
||
Creating a Custom Dumper | ||
------------------------ | ||
|
||
It is also possible to create a custom dumper for your format, which is | ||
useful when using the extraction commands. To do so, a new class | ||
implementing the | ||
:class:`Symfony\\Component\\Translation\\Dumper\\DumperInterface` | ||
must be created. To write the dump contents into a file, extending the | ||
:class:`Symfony\\Component\\Translation\\Dumper\\FileDumper` class | ||
will save a few lines:: | ||
|
||
use Symfony\Component\Translation\MessageCatalogue; | ||
use Symfony\Component\Translation\Dumper\FileDumper; | ||
|
||
class MyFormatDumper extends FileDumper | ||
{ | ||
protected function format(MessageCatalogue $messages, $domain = 'messages') | ||
{ | ||
$output = ''; | ||
|
||
foreach ($messages->all($domain) as $source => $target) { | ||
$output .= sprintf("(%s)(%s)\n", $source, $target); | ||
} | ||
|
||
return $output; | ||
} | ||
|
||
protected function getExtension() | ||
{ | ||
return 'txt'; | ||
} | ||
} | ||
|
||
The :method:`Symfony\\Component\\Translation\\Dumper\\FileDumper::format` | ||
method creates the output string, that will be used by the | ||
:method:`Symfony\\Component\\Translation\\Dumper\\FileDumper::dump` method | ||
of the FileDumper class to create the file. The dumper can be used like any other | ||
built-in dumper. In the following example, the translation messages defined in the | ||
YAML file are dumped into a text file with the custom format:: | ||
|
||
use Symfony\Component\Translation\Loader\YamlFileLoader; | ||
|
||
$loader = new YamlFileLoader(); | ||
$catalogue = $loader->load(__DIR__ . '/translations/messages.fr_FR.yml' , 'fr_FR'); | ||
|
||
$dumper = new MyFormatDumper(); | ||
$dumper->dump($catalogue, array('path' => __DIR__.'/dumps')); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,3 +6,4 @@ Translation | |
|
||
introduction | ||
usage | ||
custom_formats |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and what about an extractor?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
totally unrelated. The extractor does not care about the format of your translation files. It relies on the loader and dumper for it (it would be great to add a cookbook about adding extractors though)