diff --git a/components/map.rst.inc b/components/map.rst.inc index 81d63df5562..572f19352d8 100644 --- a/components/map.rst.inc +++ b/components/map.rst.inc @@ -130,6 +130,7 @@ * :doc:`/components/translation/introduction` * :doc:`/components/translation/usage` + * :doc:`/components/translation/custom_formats` * :doc:`/components/yaml/index` diff --git a/components/translation/custom_formats.rst b/components/translation/custom_formats.rst new file mode 100644 index 00000000000..a212b7b1910 --- /dev/null +++ b/components/translation/custom_formats.rst @@ -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 +new class that implements the +:class:`Symfony\\Component\\Translation\\Loader\\LoaderInterface`. The +:method:`Symfony\\Component\\Translation\\Loader\\LoaderInterface::load` +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')); diff --git a/components/translation/index.rst b/components/translation/index.rst index 3f87cbc1425..c50e43f2be7 100644 --- a/components/translation/index.rst +++ b/components/translation/index.rst @@ -6,3 +6,4 @@ Translation introduction usage + custom_formats diff --git a/components/translation/introduction.rst b/components/translation/introduction.rst index 7300f01f7a9..a97e13d7701 100644 --- a/components/translation/introduction.rst +++ b/components/translation/introduction.rst @@ -62,8 +62,7 @@ The Translation component uses Loader classes to load catalogs. You can load multiple resources for the same locale, which will then be combined into one catalog. -The component comes with some default Loaders and you can create your own -Loader too. The default loaders are: +The component comes with some default loaders: * :class:`Symfony\\Component\\Translation\\Loader\\ArrayLoader` - to load catalogs from PHP arrays. @@ -95,6 +94,9 @@ Loader too. The default loaders are: All file loaders require the :doc:`Config component `. +You can also :doc:`create your own Loader `, +in case the format is not already supported by one of the default loaders. + At first, you should add one or more loaders to the ``Translator``:: // ...