From 7184f67c8743466f4e4ffc921795094e4e7e2ccb Mon Sep 17 00:00:00 2001 From: Michel Salib Date: Sat, 11 Jun 2011 02:04:56 +0200 Subject: [PATCH 01/13] -- add use of translation:update command from michelsalib:ExtraToolsBundle --- .../Command/TranslationUpdateCommand.php | 227 ++++++++++++++++++ .../TwigBundle/Resources/config/twig.xml | 12 + .../Formatter/FormatterInterface.php | 17 ++ .../Translation/Formatter/PhpFormatter.php | 16 ++ .../Translation/Formatter/PotFormatter.php | 43 ++++ .../Translation/Formatter/XliffFormatter.php | 46 ++++ .../Translation/Formatter/YamlFormatter.php | 16 ++ 7 files changed, 377 insertions(+) create mode 100644 src/Symfony/Bundle/TwigBundle/Command/TranslationUpdateCommand.php create mode 100644 src/Symfony/Component/Translation/Formatter/FormatterInterface.php create mode 100644 src/Symfony/Component/Translation/Formatter/PhpFormatter.php create mode 100644 src/Symfony/Component/Translation/Formatter/PotFormatter.php create mode 100644 src/Symfony/Component/Translation/Formatter/XliffFormatter.php create mode 100644 src/Symfony/Component/Translation/Formatter/YamlFormatter.php diff --git a/src/Symfony/Bundle/TwigBundle/Command/TranslationUpdateCommand.php b/src/Symfony/Bundle/TwigBundle/Command/TranslationUpdateCommand.php new file mode 100644 index 0000000000000..bddc14ffd3652 --- /dev/null +++ b/src/Symfony/Bundle/TwigBundle/Command/TranslationUpdateCommand.php @@ -0,0 +1,227 @@ +setName('translation:update') + ->setDescription('Update the translation file') + ->setDefinition(array( + new InputArgument('locale', InputArgument::REQUIRED, 'The locale'), + new InputArgument('bundle', InputArgument::REQUIRED, 'The bundle where to load the messages'), + new InputOption( + 'prefix', null, InputOption::VALUE_OPTIONAL, + 'Override the default prefix', '__' + ), + new InputOption( + 'output-format', null, InputOption::VALUE_OPTIONAL, + 'Override the default output format (' . implode(', ', $this->supportedFormats) . ')', 'yml' + ), + new InputOption( + 'source-lang', null, InputOption::VALUE_OPTIONAL, + 'Set the source language attribute in xliff files', 'en' + ), + new InputOption( + 'dump-messages', null, InputOption::VALUE_NONE, + 'Should the messages be dumped in the console' + ), + new InputOption( + 'force', null, InputOption::VALUE_NONE, + 'Should the update be done' + ) + )); + } + + /** + * {@inheritDoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $twig = $this->container->get('twig'); + $this->prefix = $input->getOption('prefix'); + + if ($input->getOption('force') !== true && $input->getOption('dump-messages') !== true) { + $output->writeln('You must choose one of --force or --dump-messages'); + return; + } + + if (!in_array($input->getOption('output-format'), $this->supportedFormats)) { + $output->writeln('Wrong output format'); + return; + } + + // get bundle directory + $foundBundle = $this->getApplication()->getKernel()->getBundle($input->getArgument('bundle')); + $bundleTransPath = $foundBundle->getPath() . '/Resources/translations'; + $output->writeln(sprintf('Generating "%s" translation files for "%s"', $input->getArgument('locale'), $foundBundle->getName())); + + $output->writeln('Parsing files.'); + + // load any messages from templates + $this->messages = new \Symfony\Component\Translation\MessageCatalogue($input->getArgument('locale')); + $finder = new Finder(); + $files = $finder->files()->name('*.html.twig')->in($foundBundle->getPath() . '/Resources/views/'); + foreach ($files as $file) { + $output->writeln(sprintf(' > parsing template %s', $file->getPathname())); + $tree = $twig->parse($twig->tokenize(file_get_contents($file->getPathname()))); + $this->crawlNode($tree); + } + + foreach($this->supportedLoaders as $format) { + // load any existing translation files + $finder = new Finder(); + $files = $finder->files()->name('*.' . $input->getArgument('locale') . $format)->in($bundleTransPath); + foreach ($files as $file) { + $output->writeln(sprintf(' > parsing translation %s', $file->getPathname())); + $domain = substr($file->getFileName(), 0, strrpos($file->getFileName(), $input->getArgument('locale') . $attributes[0]['alias']) - 1); + $loader = $this->container->get('translation.loader.' . $format); + $this->messages->addCatalogue($loader->load($file->getPathname(), $input->getArgument('locale'), $domain)); + } + } + + // show compiled list of messages + if($input->getOption('dump-messages') === true){ + foreach ($this->messages->getDomains() as $domain) { + $output->writeln(sprintf("\nDisplaying messages for domain %s:\n", $domain)); + $output->writeln(\Symfony\Component\Yaml\Yaml::dump($this->messages->all($domain),10)); + } + } + + // save the files + if($input->getOption('force') === true) { + $output->writeln("\nWriting files.\n"); + $path = $foundBundle->getPath() . '/Resources/translations/'; + + // get the right formatter + $formatter = $this->container->get('twig.translation.formatter.' . $input->getOption('output-format')); + + foreach ($this->messages->getDomains() as $domain) { + $file = $domain . '.' . $input->getArgument('locale') . '.' . $input->getOption('output-format'); + if (file_exists($path . $file)) { + copy($path . $file, $path . '~' . $file . '.bak'); + } + $output->writeln(sprintf(' > generating %s', $path . $file)); + file_put_contents($path . $file, $formatter->format($this->messages->all($domain))); + } + } + } + + /** + * Recursive function that extract trans message from a twig tree + * + * @param \Twig_Node The twig tree root + */ + private function crawlNode(\Twig_Node $node) + { + if ($node instanceof \Symfony\Bridge\Twig\Node\TransNode && !$node->getNode('body') instanceof \Twig_Node_Expression_GetAttr) { + // trans block + $domain = $node->getNode('domain')->getAttribute('value'); + $message = $node->getNode('body')->getAttribute('data'); + $this->messages->set($message, $this->prefix.$message, $domain); + } else if ($node instanceof \Twig_Node_Print) { + // trans filter (be carefull of how you chain your filters) + $message = $this->extractMessage($node->getNode('expr')); + $domain = $this->extractDomain($node->getNode('expr')); + if($message !== null && $domain!== null) { + $this->messages->set($message, $this->prefix.$message, $domain); + } + } else { + // continue crawling + foreach ($node as $child) { + if ($child != null) { + $this->crawlNode($child); + } + } + } + } + + /** + * Extract a message from a \Twig_Node_Print + * Return null if not a constant message + * + * @param \Twig_Node $node + */ + private function extractMessage(\Twig_Node $node) + { + if($node->hasNode('node')) { + return $this->extractMessage($node->getNode ('node')); + } + if($node instanceof \Twig_Node_Expression_Constant) { + return $node->getAttribute('value'); + } + + return null; + } + + /** + * Extract a domain from a \Twig_Node_Print + * Return null if no trans filter + * + * @param \Twig_Node $node + */ + private function extractDomain(\Twig_Node $node) + { + // must be a filter node + if(!$node instanceof \Twig_Node_Expression_Filter) { + return null; + } + // is a trans filter + if($node->getNode('filter')->getAttribute('value') == 'trans') { + if($node->getNode('arguments')->hasNode(1)) { + return $node->getNode('arguments')->getNode(1)->getAttribute('value'); + } else { + return $this->defaultDomain; + } + } + + return $this->extractDomain($node->getNode('node')); + } + +} diff --git a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml index 178c5b8590afa..a9f91b9bcba08 100644 --- a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml +++ b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml @@ -18,6 +18,10 @@ Symfony\Bridge\Twig\Extension\FormExtension Twig_Extensions_Extension_Text Twig_Extensions_Extension_Debug + Symfony\Component\Translation\Formatter\PhpFormatter + Symfony\Component\Translation\Formatter\PotFormatter + Symfony\Component\Translation\Formatter\XliffFormatter + Symfony\Component\Translation\Formatter\YamlFormatter @@ -80,5 +84,13 @@ + + + + + + + + diff --git a/src/Symfony/Component/Translation/Formatter/FormatterInterface.php b/src/Symfony/Component/Translation/Formatter/FormatterInterface.php new file mode 100644 index 0000000000000..37de0ce16285b --- /dev/null +++ b/src/Symfony/Component/Translation/Formatter/FormatterInterface.php @@ -0,0 +1,17 @@ +\n"'; + $output[] = '"Language-Team: LANGUAGE \n"'; + $output[] = '"MIME-Version: 1.0\n"'; + $output[] = '"Content-Type: text/plain; charset=UTF-8\n"'; + $output[] = '"Content-Transfer-Encoding: 8bit\n"'; + $output[] = '"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"'; + $output[] = ''; + + foreach ($data as $source => $target) { + $source = $this->clean($source); + $target = $this->clean($target); + + $output[] = "msgid \"{$source}\""; + $output[] = "msgstr \"{$target}\""; + $output[] = ''; + } + + return implode("\n", $output) . "\n"; + } + + protected function clean($message) + { + $message = strtr($message, array("\\'" => "'", "\\\\" => "\\", "\r\n" => "\n")); + $message = addcslashes($message, "\0..\37\\\""); + return $message; + } +} diff --git a/src/Symfony/Component/Translation/Formatter/XliffFormatter.php b/src/Symfony/Component/Translation/Formatter/XliffFormatter.php new file mode 100644 index 0000000000000..2bfd8400dcd13 --- /dev/null +++ b/src/Symfony/Component/Translation/Formatter/XliffFormatter.php @@ -0,0 +1,46 @@ + element + */ + public function __construct($source = 'en') + { + $this->source = $source; + } + + /** + * {@inheritDoc} + */ + public function format(array $messages) + { + $dom = new \DOMDocument('1.0', 'utf-8'); + $dom->formatOutput = true; + $xliff = $dom->appendChild($dom->createElement('xliff')); + $xliff->setAttribute('version', '1.2'); + $xliff->setAttribute('xmlns', 'urn:oasis:names:tc:xliff:document:1.2'); + $xliffFile = $xliff->appendChild($dom->createElement('file')); + $xliffFile->setAttribute('source-language', $this->source); + $xliffFile->setAttribute('datatype', 'plaintext'); + $xliffFile->setAttribute('original', 'file.ext'); + $xliffBody = $xliffFile->appendChild($dom->createElement('body')); + $id = 1; + foreach ($messages as $source => $target) { + $trans = $dom->createElement('trans-unit'); + $trans->setAttribute('id', $id); + $s = $trans->appendChild($dom->createElement('source')); + $s->appendChild($dom->createTextNode($source)); + $t = $trans->appendChild($dom->createElement('target')); + $t->appendChild($dom->createTextNode($target)); + $xliffBody->appendChild($trans); + $id++; + } + + return $dom->saveXML(); + } +} diff --git a/src/Symfony/Component/Translation/Formatter/YamlFormatter.php b/src/Symfony/Component/Translation/Formatter/YamlFormatter.php new file mode 100644 index 0000000000000..0d55ee966e674 --- /dev/null +++ b/src/Symfony/Component/Translation/Formatter/YamlFormatter.php @@ -0,0 +1,16 @@ + Date: Sat, 11 Jun 2011 16:03:28 +0200 Subject: [PATCH 02/13] -- extract translation reader and writer to services --- .../Command/TranslationUpdateCommand.php | 157 +++--------------- .../TwigBundle/Resources/config/twig.xml | 16 ++ .../Translation/FileTranslationExtractor.php | 46 +++++ .../Translation/FileTranslationWriter.php | 35 ++++ .../TranslationExtractorInterface.php | 17 ++ .../Translation/TwigTranslationExtractor.php | 124 ++++++++++++++ 6 files changed, 258 insertions(+), 137 deletions(-) create mode 100644 src/Symfony/Bundle/TwigBundle/Translation/FileTranslationExtractor.php create mode 100644 src/Symfony/Bundle/TwigBundle/Translation/FileTranslationWriter.php create mode 100644 src/Symfony/Bundle/TwigBundle/Translation/TranslationExtractorInterface.php create mode 100644 src/Symfony/Bundle/TwigBundle/Translation/TwigTranslationExtractor.php diff --git a/src/Symfony/Bundle/TwigBundle/Command/TranslationUpdateCommand.php b/src/Symfony/Bundle/TwigBundle/Command/TranslationUpdateCommand.php index bddc14ffd3652..4d358cc2187bd 100644 --- a/src/Symfony/Bundle/TwigBundle/Command/TranslationUpdateCommand.php +++ b/src/Symfony/Bundle/TwigBundle/Command/TranslationUpdateCommand.php @@ -11,13 +11,6 @@ class TranslationUpdateCommand extends Command { - /** - * Default domain for found trans blocks/filters - * - * @var string - */ - private $defaultDomain = 'messages'; - /** * Supported formats for output * @@ -25,25 +18,11 @@ class TranslationUpdateCommand extends Command */ private $supportedFormats = array('yml', 'xliff', 'php', 'pot'); - /** - * Supported formats for import - * - * @var array - */ - private $supportedLoaders = array('yml', 'xliff', 'php'); - - /** - * Prefix for newly found message ids - * - * @var string - */ - protected $prefix; - /** * Compiled catalogue of messages * @var \Symfony\Component\Translation\MessageCatalogue */ - protected $messages; + protected $catalogue; /** * {@inheritDoc} @@ -51,7 +30,7 @@ class TranslationUpdateCommand extends Command protected function configure() { $this - ->setName('translation:update') + ->setName('twig:translation:update') ->setDescription('Update the translation file') ->setDefinition(array( new InputArgument('locale', InputArgument::REQUIRED, 'The locale'), @@ -84,9 +63,6 @@ protected function configure() */ protected function execute(InputInterface $input, OutputInterface $output) { - $twig = $this->container->get('twig'); - $this->prefix = $input->getOption('prefix'); - if ($input->getOption('force') !== true && $input->getOption('dump-messages') !== true) { $output->writeln('You must choose one of --force or --dump-messages'); return; @@ -102,126 +78,33 @@ protected function execute(InputInterface $input, OutputInterface $output) $bundleTransPath = $foundBundle->getPath() . '/Resources/translations'; $output->writeln(sprintf('Generating "%s" translation files for "%s"', $input->getArgument('locale'), $foundBundle->getName())); - $output->writeln('Parsing files.'); - + // create catalogue + $catalogue = new \Symfony\Component\Translation\MessageCatalogue($input->getArgument('locale')); + // load any messages from templates - $this->messages = new \Symfony\Component\Translation\MessageCatalogue($input->getArgument('locale')); - $finder = new Finder(); - $files = $finder->files()->name('*.html.twig')->in($foundBundle->getPath() . '/Resources/views/'); - foreach ($files as $file) { - $output->writeln(sprintf(' > parsing template %s', $file->getPathname())); - $tree = $twig->parse($twig->tokenize(file_get_contents($file->getPathname()))); - $this->crawlNode($tree); - } - - foreach($this->supportedLoaders as $format) { - // load any existing translation files - $finder = new Finder(); - $files = $finder->files()->name('*.' . $input->getArgument('locale') . $format)->in($bundleTransPath); - foreach ($files as $file) { - $output->writeln(sprintf(' > parsing translation %s', $file->getPathname())); - $domain = substr($file->getFileName(), 0, strrpos($file->getFileName(), $input->getArgument('locale') . $attributes[0]['alias']) - 1); - $loader = $this->container->get('translation.loader.' . $format); - $this->messages->addCatalogue($loader->load($file->getPathname(), $input->getArgument('locale'), $domain)); - } - } - + $output->writeln('Parsing templates'); + $twigExtractor = $this->container->get('twig.translation.extractor.twig'); + $twigExtractor->setPrefix($input->getOption('prefix')); + $twigExtractor->extractMessages($foundBundle->getPath() . '/Resources/views/', $catalogue); + + // load any existing messages from the translation files + $output->writeln('Parsing translation files'); + $fileExtractor = $this->container->get('twig.translation.extractor.file'); + $fileExtractor->extractMessages($bundleTransPath, $catalogue); + // show compiled list of messages if($input->getOption('dump-messages') === true){ - foreach ($this->messages->getDomains() as $domain) { + foreach ($catalogue->getDomains() as $domain) { $output->writeln(sprintf("\nDisplaying messages for domain %s:\n", $domain)); - $output->writeln(\Symfony\Component\Yaml\Yaml::dump($this->messages->all($domain),10)); + $output->writeln(\Symfony\Component\Yaml\Yaml::dump($catalogue->all($domain),10)); } } // save the files if($input->getOption('force') === true) { - $output->writeln("\nWriting files.\n"); - $path = $foundBundle->getPath() . '/Resources/translations/'; - - // get the right formatter - $formatter = $this->container->get('twig.translation.formatter.' . $input->getOption('output-format')); - - foreach ($this->messages->getDomains() as $domain) { - $file = $domain . '.' . $input->getArgument('locale') . '.' . $input->getOption('output-format'); - if (file_exists($path . $file)) { - copy($path . $file, $path . '~' . $file . '.bak'); - } - $output->writeln(sprintf(' > generating %s', $path . $file)); - file_put_contents($path . $file, $formatter->format($this->messages->all($domain))); - } - } - } - - /** - * Recursive function that extract trans message from a twig tree - * - * @param \Twig_Node The twig tree root - */ - private function crawlNode(\Twig_Node $node) - { - if ($node instanceof \Symfony\Bridge\Twig\Node\TransNode && !$node->getNode('body') instanceof \Twig_Node_Expression_GetAttr) { - // trans block - $domain = $node->getNode('domain')->getAttribute('value'); - $message = $node->getNode('body')->getAttribute('data'); - $this->messages->set($message, $this->prefix.$message, $domain); - } else if ($node instanceof \Twig_Node_Print) { - // trans filter (be carefull of how you chain your filters) - $message = $this->extractMessage($node->getNode('expr')); - $domain = $this->extractDomain($node->getNode('expr')); - if($message !== null && $domain!== null) { - $this->messages->set($message, $this->prefix.$message, $domain); - } - } else { - // continue crawling - foreach ($node as $child) { - if ($child != null) { - $this->crawlNode($child); - } - } - } - } - - /** - * Extract a message from a \Twig_Node_Print - * Return null if not a constant message - * - * @param \Twig_Node $node - */ - private function extractMessage(\Twig_Node $node) - { - if($node->hasNode('node')) { - return $this->extractMessage($node->getNode ('node')); + $output->writeln("Writing files"); + $fileWriter = $this->container->get('twig.translation.writer'); + $fileWriter->writeTranslations($catalogue, $bundleTransPath, $input->getOption('output-format')); } - if($node instanceof \Twig_Node_Expression_Constant) { - return $node->getAttribute('value'); - } - - return null; - } - - /** - * Extract a domain from a \Twig_Node_Print - * Return null if no trans filter - * - * @param \Twig_Node $node - */ - private function extractDomain(\Twig_Node $node) - { - // must be a filter node - if(!$node instanceof \Twig_Node_Expression_Filter) { - return null; - } - // is a trans filter - if($node->getNode('filter')->getAttribute('value') == 'trans') { - if($node->getNode('arguments')->hasNode(1)) { - return $node->getNode('arguments')->getNode(1)->getAttribute('value'); - } else { - return $this->defaultDomain; - } - } - - return $this->extractDomain($node->getNode('node')); } - } diff --git a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml index a9f91b9bcba08..b886a4c896c24 100644 --- a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml +++ b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml @@ -22,6 +22,10 @@ Symfony\Component\Translation\Formatter\PotFormatter Symfony\Component\Translation\Formatter\XliffFormatter Symfony\Component\Translation\Formatter\YamlFormatter + Symfony\Component\Translation\Formatter\YamlFormatter + Symfony\Bundle\TwigBundle\Translation\TwigTranslationExtractor + Symfony\Bundle\TwigBundle\Translation\FileTranslationExtractor + Symfony\Bundle\TwigBundle\Translation\FileTranslationWriter @@ -92,5 +96,17 @@ + + + + + + + + + + + + diff --git a/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationExtractor.php b/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationExtractor.php new file mode 100644 index 0000000000000..cd0c6e0b5994f --- /dev/null +++ b/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationExtractor.php @@ -0,0 +1,46 @@ +container = $container; + } + + /** + * {@inheritDoc} + */ + public function extractMessages($directory, MessageCatalogue $catalogue) { + foreach($this->supportedLoaders as $format) { + // load any existing translation files + $finder = new Finder(); + $files = $finder->files()->name('*.' . $catalogue->getLocale() . $format)->in($directory); + foreach ($files as $file) { + $domain = substr($file->getFileName(), 0, strrpos($file->getFileName(), $input->getArgument('locale') . $attributes[0]['alias']) - 1); + $loader = $this->container->get('translation.loader.' . $format); + $catalogue->addCatalogue($loader->load($file->getPathname(), $input->getArgument('locale'), $domain)); + } + } + } +} diff --git a/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationWriter.php b/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationWriter.php new file mode 100644 index 0000000000000..8c55302302a1e --- /dev/null +++ b/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationWriter.php @@ -0,0 +1,35 @@ +container = $container; + } + + public function writeTranslations(MessageCatalogue $catalogue, $path, $format){ + // get the right formatter + $formatter = $this->container->get('twig.translation.formatter.' . $format); + + // save + foreach ($catalogue->getDomains() as $domain) { + $file = $domain . '.' . $catalogue->getLocale() . '.' . $format; + if (file_exists($path . $file)) { + copy($path . $file, $path . '~' . $file . '.bak'); + } + file_put_contents($path . '/' . $file, $formatter->format($catalogue->all($domain))); + } + } +} diff --git a/src/Symfony/Bundle/TwigBundle/Translation/TranslationExtractorInterface.php b/src/Symfony/Bundle/TwigBundle/Translation/TranslationExtractorInterface.php new file mode 100644 index 0000000000000..2c2d52965b00d --- /dev/null +++ b/src/Symfony/Bundle/TwigBundle/Translation/TranslationExtractorInterface.php @@ -0,0 +1,17 @@ +twig = $twig; + } + + /** + * {@inheritDoc} + */ + public function extractMessages($directory, MessageCatalogue $catalogue) { + $finder = new Finder(); + $files = $finder->files()->name('*.html.twig')->in($directory); + foreach ($files as $file) { + $tree = $this->twig->parse($this->twig->tokenize(file_get_contents($file->getPathname()))); + $this->crawlNode($tree, $catalogue); + } + } + + /** + * Recursive function that extract trans message from a twig tree + * + * @param \Twig_Node The twig tree root + */ + private function crawlNode(\Twig_Node $node, $catalogue) + { + if ($node instanceof \Symfony\Bridge\Twig\Node\TransNode && !$node->getNode('body') instanceof \Twig_Node_Expression_GetAttr) { + // trans block + $domain = $node->getNode('domain')->getAttribute('value'); + $message = $node->getNode('body')->getAttribute('data'); + $catalogue->set($message, $this->prefix.$message, $domain); + } else if ($node instanceof \Twig_Node_Print) { + // trans filter (be carefull of how you chain your filters) + $message = $this->extractMessage($node->getNode('expr')); + $domain = $this->extractDomain($node->getNode('expr')); + if($message !== null && $domain!== null) { + $catalogue->set($message, $this->prefix.$message, $domain); + } + } else { + // continue crawling + foreach ($node as $child) { + if ($child != null) { + $this->crawlNode($child, $catalogue); + } + } + } + } + + /** + * Extract a message from a \Twig_Node_Print + * Return null if not a constant message + * + * @param \Twig_Node $node + */ + private function extractMessage(\Twig_Node $node) + { + if($node->hasNode('node')) { + return $this->extractMessage($node->getNode ('node')); + } + if($node instanceof \Twig_Node_Expression_Constant) { + return $node->getAttribute('value'); + } + + return null; + } + + /** + * Extract a domain from a \Twig_Node_Print + * Return null if no trans filter + * + * @param \Twig_Node $node + */ + private function extractDomain(\Twig_Node $node) + { + // must be a filter node + if(!$node instanceof \Twig_Node_Expression_Filter) { + return null; + } + // is a trans filter + if($node->getNode('filter')->getAttribute('value') == 'trans') { + if($node->getNode('arguments')->hasNode(1)) { + return $node->getNode('arguments')->getNode(1)->getAttribute('value'); + } else { + return $this->defaultDomain; + } + } + + return $this->extractDomain($node->getNode('node')); + } + + public function setPrefix($prefix) { + $this->prefix = $prefix; + } +} From 7da09f539e2fea2f97d12fc984e4ce0886e47b00 Mon Sep 17 00:00:00 2001 From: Michel Salib Date: Sat, 11 Jun 2011 17:01:10 +0200 Subject: [PATCH 03/13] -- tweak transaltion extractor --- .../Command/TranslationUpdateCommand.php | 8 +++-- .../TwigBundle/Resources/config/twig.xml | 5 ++- .../Translation/FileTranslationExtractor.php | 2 +- .../Translation/FileTranslationWriter.php | 6 ++-- .../TranslationExtractorInterface.php | 12 ++++--- .../Translation/TwigTranslationExtractor.php | 32 +++++++++++-------- .../Formatter/FormatterInterface.php | 4 +-- .../Translation/Formatter/PotFormatter.php | 8 ++++- .../Translation/Formatter/YamlFormatter.php | 2 +- 9 files changed, 48 insertions(+), 31 deletions(-) diff --git a/src/Symfony/Bundle/TwigBundle/Command/TranslationUpdateCommand.php b/src/Symfony/Bundle/TwigBundle/Command/TranslationUpdateCommand.php index 4d358cc2187bd..3b1ef702a4e68 100644 --- a/src/Symfony/Bundle/TwigBundle/Command/TranslationUpdateCommand.php +++ b/src/Symfony/Bundle/TwigBundle/Command/TranslationUpdateCommand.php @@ -8,6 +8,8 @@ use Symfony\Component\Finder\Finder; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Yaml\Yaml; class TranslationUpdateCommand extends Command { @@ -79,7 +81,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $output->writeln(sprintf('Generating "%s" translation files for "%s"', $input->getArgument('locale'), $foundBundle->getName())); // create catalogue - $catalogue = new \Symfony\Component\Translation\MessageCatalogue($input->getArgument('locale')); + $catalogue = new MessageCatalogue($input->getArgument('locale')); // load any messages from templates $output->writeln('Parsing templates'); @@ -96,8 +98,10 @@ protected function execute(InputInterface $input, OutputInterface $output) if($input->getOption('dump-messages') === true){ foreach ($catalogue->getDomains() as $domain) { $output->writeln(sprintf("\nDisplaying messages for domain %s:\n", $domain)); - $output->writeln(\Symfony\Component\Yaml\Yaml::dump($catalogue->all($domain),10)); + $output->writeln(Yaml::dump($catalogue->all($domain),10)); } + if($input->getOption('output-format') == 'xliff') + $output->writeln('Xliff output version is 1.2/info>'); } // save the files diff --git a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml index b886a4c896c24..ba2ed1e281a01 100644 --- a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml +++ b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml @@ -22,8 +22,7 @@ Symfony\Component\Translation\Formatter\PotFormatter Symfony\Component\Translation\Formatter\XliffFormatter Symfony\Component\Translation\Formatter\YamlFormatter - Symfony\Component\Translation\Formatter\YamlFormatter - Symfony\Bundle\TwigBundle\Translation\TwigTranslationExtractor + Symfony\Bundle\TwigBundle\Translation\TwigTranslationExtractor Symfony\Bundle\TwigBundle\Translation\FileTranslationExtractor Symfony\Bundle\TwigBundle\Translation\FileTranslationWriter @@ -97,7 +96,7 @@ - + diff --git a/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationExtractor.php b/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationExtractor.php index cd0c6e0b5994f..19294db461204 100644 --- a/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationExtractor.php +++ b/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationExtractor.php @@ -24,7 +24,7 @@ class FileTranslationExtractor implements TranslationExtractorInterface */ private $container; - function __construct($container) { + public function __construct(ContainerInterface $container) { $this->container = $container; } diff --git a/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationWriter.php b/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationWriter.php index 8c55302302a1e..b8247b7aad296 100644 --- a/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationWriter.php +++ b/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationWriter.php @@ -15,11 +15,13 @@ class FileTranslationWriter */ private $container; - function __construct($container) { + public function __construct(ContainerInterface $container) + { $this->container = $container; } - public function writeTranslations(MessageCatalogue $catalogue, $path, $format){ + public function writeTranslations(MessageCatalogue $catalogue, $path, $format) + { // get the right formatter $formatter = $this->container->get('twig.translation.formatter.' . $format); diff --git a/src/Symfony/Bundle/TwigBundle/Translation/TranslationExtractorInterface.php b/src/Symfony/Bundle/TwigBundle/Translation/TranslationExtractorInterface.php index 2c2d52965b00d..9b9d519a194b7 100644 --- a/src/Symfony/Bundle/TwigBundle/Translation/TranslationExtractorInterface.php +++ b/src/Symfony/Bundle/TwigBundle/Translation/TranslationExtractorInterface.php @@ -7,11 +7,13 @@ /** * Interface for translaton extractor */ -interface TranslationExtractorInterface { +interface TranslationExtractorInterface +{ /** - * Extracto transaltion messages to the catalogue - * @param string the directory to look into - * @param Symfony\Component\Translation\MessageCatalogue the catalogue + * Extract translation messages to the catalogue + * + * @param string $directory the directory to look into + * @param MessageCatalogue $catalogue the catalogue */ - public function extractMessages($directory, MessageCatalogue $catalogue); + function extractMessages($directory, MessageCatalogue $catalogue); } diff --git a/src/Symfony/Bundle/TwigBundle/Translation/TwigTranslationExtractor.php b/src/Symfony/Bundle/TwigBundle/Translation/TwigTranslationExtractor.php index 727fcc78bb2dd..a8873c6813b9a 100644 --- a/src/Symfony/Bundle/TwigBundle/Translation/TwigTranslationExtractor.php +++ b/src/Symfony/Bundle/TwigBundle/Translation/TwigTranslationExtractor.php @@ -4,6 +4,7 @@ use Symfony\Component\Translation\MessageCatalogue; use Symfony\Component\Finder\Finder; +use Symfony\Bridge\Twig\Node\TransNode; use Twig_Environment; /** @@ -31,7 +32,7 @@ class TwigTranslationExtractor implements TranslationExtractorInterface */ private $twig; - function __construct(Twig_Environment $twig) { + public function __construct(Twig_Environment $twig) { $this->twig = $twig; } @@ -47,6 +48,14 @@ public function extractMessages($directory, MessageCatalogue $catalogue) { } } + /** + * Set the prefix that should be used for new found messages + * @param type $prefix The prefix + */ + public function setPrefix($prefix) { + $this->prefix = $prefix; + } + /** * Recursive function that extract trans message from a twig tree * @@ -54,16 +63,16 @@ public function extractMessages($directory, MessageCatalogue $catalogue) { */ private function crawlNode(\Twig_Node $node, $catalogue) { - if ($node instanceof \Symfony\Bridge\Twig\Node\TransNode && !$node->getNode('body') instanceof \Twig_Node_Expression_GetAttr) { + if ($node instanceof TransNode && !$node->getNode('body') instanceof \Twig_Node_Expression_GetAttr) { // trans block $domain = $node->getNode('domain')->getAttribute('value'); $message = $node->getNode('body')->getAttribute('data'); $catalogue->set($message, $this->prefix.$message, $domain); - } else if ($node instanceof \Twig_Node_Print) { + } elseif ($node instanceof \Twig_Node_Print) { // trans filter (be carefull of how you chain your filters) $message = $this->extractMessage($node->getNode('expr')); $domain = $this->extractDomain($node->getNode('expr')); - if($message !== null && $domain!== null) { + if ($message !== null && $domain !== null) { $catalogue->set($message, $this->prefix.$message, $domain); } } else { @@ -84,10 +93,10 @@ private function crawlNode(\Twig_Node $node, $catalogue) */ private function extractMessage(\Twig_Node $node) { - if($node->hasNode('node')) { + if ($node->hasNode('node')) { return $this->extractMessage($node->getNode ('node')); } - if($node instanceof \Twig_Node_Expression_Constant) { + if ($node instanceof \Twig_Node_Expression_Constant) { return $node->getAttribute('value'); } @@ -103,22 +112,17 @@ private function extractMessage(\Twig_Node $node) private function extractDomain(\Twig_Node $node) { // must be a filter node - if(!$node instanceof \Twig_Node_Expression_Filter) { + if (!$node instanceof \Twig_Node_Expression_Filter) { return null; } // is a trans filter if($node->getNode('filter')->getAttribute('value') == 'trans') { - if($node->getNode('arguments')->hasNode(1)) { + if ($node->getNode('arguments')->hasNode(1)) { return $node->getNode('arguments')->getNode(1)->getAttribute('value'); - } else { - return $this->defaultDomain; } + return $this->defaultDomain; } return $this->extractDomain($node->getNode('node')); } - - public function setPrefix($prefix) { - $this->prefix = $prefix; - } } diff --git a/src/Symfony/Component/Translation/Formatter/FormatterInterface.php b/src/Symfony/Component/Translation/Formatter/FormatterInterface.php index 37de0ce16285b..e935b5d3a0d38 100644 --- a/src/Symfony/Component/Translation/Formatter/FormatterInterface.php +++ b/src/Symfony/Component/Translation/Formatter/FormatterInterface.php @@ -10,8 +10,8 @@ interface FormatterInterface /** * Generates a string representation of the message format. * - * @param $messages array + * @param array $messages * @return string */ - public function format(array $messages); + function format(array $messages); } diff --git a/src/Symfony/Component/Translation/Formatter/PotFormatter.php b/src/Symfony/Component/Translation/Formatter/PotFormatter.php index e8272c7af4d4c..ad14faf79e75b 100644 --- a/src/Symfony/Component/Translation/Formatter/PotFormatter.php +++ b/src/Symfony/Component/Translation/Formatter/PotFormatter.php @@ -34,10 +34,16 @@ public function format(array $messages) return implode("\n", $output) . "\n"; } - protected function clean($message) + /** + * Clean the given message to to make it pot compliant + * @param type $message + * @return string the cleaned message + */ + private function clean($message) { $message = strtr($message, array("\\'" => "'", "\\\\" => "\\", "\r\n" => "\n")); $message = addcslashes($message, "\0..\37\\\""); + return $message; } } diff --git a/src/Symfony/Component/Translation/Formatter/YamlFormatter.php b/src/Symfony/Component/Translation/Formatter/YamlFormatter.php index 0d55ee966e674..5c2960c7b193b 100644 --- a/src/Symfony/Component/Translation/Formatter/YamlFormatter.php +++ b/src/Symfony/Component/Translation/Formatter/YamlFormatter.php @@ -2,7 +2,7 @@ namespace Symfony\Component\Translation\Formatter; -use \Symfony\Component\Yaml\Yaml; +use Symfony\Component\Yaml\Yaml; class YamlFormatter implements FormatterInterface { From a61492fd3fcc42e0063d809854c8b9fbce4af83b Mon Sep 17 00:00:00 2001 From: Michel Salib Date: Mon, 13 Jun 2011 13:39:38 +0200 Subject: [PATCH 04/13] -- use transaltion writer/formatter with proper DI --- .../Command/TranslationUpdateCommand.php | 2 +- .../Compiler/TranslationExtractorPass.php | 33 +++++++++++++++++++ .../Compiler/TranslationWriterPass.php | 33 +++++++++++++++++++ .../TwigBundle/Resources/config/twig.xml | 24 ++++++++------ .../Translation/FileTranslationExtractor.php | 21 ++++++------ .../Translation/FileTranslationWriter.php | 22 ++++++++----- src/Symfony/Bundle/TwigBundle/TwigBundle.php | 4 +++ 7 files changed, 109 insertions(+), 30 deletions(-) create mode 100644 src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TranslationExtractorPass.php create mode 100644 src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TranslationWriterPass.php diff --git a/src/Symfony/Bundle/TwigBundle/Command/TranslationUpdateCommand.php b/src/Symfony/Bundle/TwigBundle/Command/TranslationUpdateCommand.php index 3b1ef702a4e68..6bf418f44ee0c 100644 --- a/src/Symfony/Bundle/TwigBundle/Command/TranslationUpdateCommand.php +++ b/src/Symfony/Bundle/TwigBundle/Command/TranslationUpdateCommand.php @@ -85,7 +85,7 @@ protected function execute(InputInterface $input, OutputInterface $output) // load any messages from templates $output->writeln('Parsing templates'); - $twigExtractor = $this->container->get('twig.translation.extractor.twig'); + $twigExtractor = $this->container->get('twig.translation.extractor'); $twigExtractor->setPrefix($input->getOption('prefix')); $twigExtractor->extractMessages($foundBundle->getPath() . '/Resources/views/', $catalogue); diff --git a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TranslationExtractorPass.php b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TranslationExtractorPass.php new file mode 100644 index 0000000000000..15b529ef7049d --- /dev/null +++ b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TranslationExtractorPass.php @@ -0,0 +1,33 @@ +hasDefinition('twig.translation.extractor.file')) { + return; + } + + $definition = $container->getDefinition('twig.translation.extractor.file'); + + // Extensions must always be registered before everything else. + // For instance, global variable definitions must be registered + // afterward. If not, the globals from the extensions will never + // be registered. + $calls = $definition->getMethodCalls(); + $definition->setMethodCalls(array()); + foreach ($container->findTaggedServiceIds('translation.loader') as $id => $attributes) { + $definition->addMethodCall('addLoader', array($attributes[0]['alias'] ,new Reference($id))); + } + $definition->setMethodCalls(array_merge($definition->getMethodCalls(), $calls)); + } +} diff --git a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TranslationWriterPass.php b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TranslationWriterPass.php new file mode 100644 index 0000000000000..021f6bdf4b5a8 --- /dev/null +++ b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TranslationWriterPass.php @@ -0,0 +1,33 @@ +hasDefinition('twig.translation.writer')) { + return; + } + + $definition = $container->getDefinition('twig.translation.writer'); + + // Extensions must always be registered before everything else. + // For instance, global variable definitions must be registered + // afterward. If not, the globals from the extensions will never + // be registered. + $calls = $definition->getMethodCalls(); + $definition->setMethodCalls(array()); + foreach ($container->findTaggedServiceIds('translation.formatter') as $id => $attributes) { + $definition->addMethodCall('addFormatter', array($attributes[0]['alias'] ,new Reference($id))); + } + $definition->setMethodCalls(array_merge($definition->getMethodCalls(), $calls)); + } +} diff --git a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml index ba2ed1e281a01..d81d3de77520d 100644 --- a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml +++ b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml @@ -88,24 +88,28 @@ - + + + - + + + - + + + - + + + - - - + - - - + diff --git a/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationExtractor.php b/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationExtractor.php index 19294db461204..de8110f8459c5 100644 --- a/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationExtractor.php +++ b/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationExtractor.php @@ -5,6 +5,7 @@ use Symfony\Component\DependencyInjection\Container; use Symfony\Component\Finder\Finder; use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Translation\Loader\LoaderInterface; /** * Extract translation messages from translation files @@ -16,29 +17,27 @@ class FileTranslationExtractor implements TranslationExtractorInterface * * @var array */ - private $supportedLoaders = array('yml', 'xliff', 'php'); - + private $loaders; + /** - * The container - * @var \Symfony\Component\DependencyInjection\ContainerInterface + * Add a loader to the translation extractor + * @param string $format The format of the loader + * @param LoaderInterface $loader */ - private $container; - - public function __construct(ContainerInterface $container) { - $this->container = $container; + public function addLoader($format, LoaderInterface $loader){ + $this->loaders[$format] = $loader; } /** * {@inheritDoc} */ public function extractMessages($directory, MessageCatalogue $catalogue) { - foreach($this->supportedLoaders as $format) { + foreach($this->loaders as $format => $loader) { // load any existing translation files $finder = new Finder(); $files = $finder->files()->name('*.' . $catalogue->getLocale() . $format)->in($directory); foreach ($files as $file) { - $domain = substr($file->getFileName(), 0, strrpos($file->getFileName(), $input->getArgument('locale') . $attributes[0]['alias']) - 1); - $loader = $this->container->get('translation.loader.' . $format); + $domain = substr($file->getFileName(), 0, strrpos($file->getFileName(), $input->getArgument('locale') . $format) - 1); $catalogue->addCatalogue($loader->load($file->getPathname(), $input->getArgument('locale'), $domain)); } } diff --git a/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationWriter.php b/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationWriter.php index b8247b7aad296..33f68579b81a4 100644 --- a/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationWriter.php +++ b/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationWriter.php @@ -3,6 +3,7 @@ namespace Symfony\Bundle\TwigBundle\Translation; use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Translation\Formatter\FormatterInterface; /** * Write translation messages to translation files @@ -10,20 +11,25 @@ class FileTranslationWriter { /** - * The container - * @var \Symfony\Component\DependencyInjection\ContainerInterface + * Supported formats for import + * + * @var array */ - private $container; - - public function __construct(ContainerInterface $container) - { - $this->container = $container; + private $formatters; + + /** + * Add a formatter to the translation extractor + * @param string $format The format of the loader + * @param FormatterInterface $formatter + */ + public function addLoader($format, FormatterInterface $formatter){ + $this->formatters[$format] = $formatters; } public function writeTranslations(MessageCatalogue $catalogue, $path, $format) { // get the right formatter - $formatter = $this->container->get('twig.translation.formatter.' . $format); + $formatter = $this->formatters[$format]; // save foreach ($catalogue->getDomains() as $domain) { diff --git a/src/Symfony/Bundle/TwigBundle/TwigBundle.php b/src/Symfony/Bundle/TwigBundle/TwigBundle.php index 46e30970670d4..ab1cc66112f3c 100644 --- a/src/Symfony/Bundle/TwigBundle/TwigBundle.php +++ b/src/Symfony/Bundle/TwigBundle/TwigBundle.php @@ -14,6 +14,8 @@ use Symfony\Component\HttpKernel\Bundle\Bundle; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Bundle\TwigBundle\DependencyInjection\Compiler\TwigEnvironmentPass; +use Symfony\Bundle\TwigBundle\DependencyInjection\Compiler\TranslationExtractorPass; +use Symfony\Bundle\TwigBundle\DependencyInjection\Compiler\TranslationWriterPass; /** * Bundle. @@ -27,5 +29,7 @@ public function build(ContainerBuilder $container) parent::build($container); $container->addCompilerPass(new TwigEnvironmentPass()); + $container->addCompilerPass(new TranslationExtractorPass()); + $container->addCompilerPass(new TranslationWriterPass()); } } From 44bccd998c8131b764a70f373a902b65c351081a Mon Sep 17 00:00:00 2001 From: Michel Salib Date: Mon, 13 Jun 2011 14:12:28 +0200 Subject: [PATCH 05/13] tweak the twig bundle --- .../Compiler/TranslationExtractorPass.php | 11 ++--------- .../Compiler/TranslationWriterPass.php | 11 ++--------- .../TwigBundle/Translation/FileTranslationWriter.php | 10 +++++----- .../Translation/TwigTranslationExtractor.php | 1 + 4 files changed, 10 insertions(+), 23 deletions(-) diff --git a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TranslationExtractorPass.php b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TranslationExtractorPass.php index 15b529ef7049d..bfcab011e3c5f 100644 --- a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TranslationExtractorPass.php +++ b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TranslationExtractorPass.php @@ -13,21 +13,14 @@ class TranslationExtractorPass implements CompilerPassInterface { public function process(ContainerBuilder $container) { - if (false === $container->hasDefinition('twig.translation.extractor.file')) { + if (!$container->hasDefinition('twig.translation.extractor.file')) { return; } $definition = $container->getDefinition('twig.translation.extractor.file'); - // Extensions must always be registered before everything else. - // For instance, global variable definitions must be registered - // afterward. If not, the globals from the extensions will never - // be registered. - $calls = $definition->getMethodCalls(); - $definition->setMethodCalls(array()); foreach ($container->findTaggedServiceIds('translation.loader') as $id => $attributes) { - $definition->addMethodCall('addLoader', array($attributes[0]['alias'] ,new Reference($id))); + $definition->addMethodCall('addLoader', array($attributes[0]['alias'], new Reference($id))); } - $definition->setMethodCalls(array_merge($definition->getMethodCalls(), $calls)); } } diff --git a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TranslationWriterPass.php b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TranslationWriterPass.php index 021f6bdf4b5a8..a407af4dc13c7 100644 --- a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TranslationWriterPass.php +++ b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TranslationWriterPass.php @@ -13,21 +13,14 @@ class TranslationWriterPass implements CompilerPassInterface { public function process(ContainerBuilder $container) { - if (false === $container->hasDefinition('twig.translation.writer')) { + if (!$container->hasDefinition('twig.translation.writer')) { return; } $definition = $container->getDefinition('twig.translation.writer'); - // Extensions must always be registered before everything else. - // For instance, global variable definitions must be registered - // afterward. If not, the globals from the extensions will never - // be registered. - $calls = $definition->getMethodCalls(); - $definition->setMethodCalls(array()); foreach ($container->findTaggedServiceIds('translation.formatter') as $id => $attributes) { - $definition->addMethodCall('addFormatter', array($attributes[0]['alias'] ,new Reference($id))); + $definition->addMethodCall('addFormatter', array($attributes[0]['alias'], new Reference($id))); } - $definition->setMethodCalls(array_merge($definition->getMethodCalls(), $calls)); } } diff --git a/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationWriter.php b/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationWriter.php index 33f68579b81a4..6a2d560d74d15 100644 --- a/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationWriter.php +++ b/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationWriter.php @@ -18,11 +18,11 @@ class FileTranslationWriter private $formatters; /** - * Add a formatter to the translation extractor + * Add a formatter to the writer * @param string $format The format of the loader * @param FormatterInterface $formatter */ - public function addLoader($format, FormatterInterface $formatter){ + public function addFormatter($format, FormatterInterface $formatter){ $this->formatters[$format] = $formatters; } @@ -33,11 +33,11 @@ public function writeTranslations(MessageCatalogue $catalogue, $path, $format) // save foreach ($catalogue->getDomains() as $domain) { - $file = $domain . '.' . $catalogue->getLocale() . '.' . $format; + $file = $domain.'.'.$catalogue->getLocale().'.'.$format; if (file_exists($path . $file)) { - copy($path . $file, $path . '~' . $file . '.bak'); + copy($path.$file, $path.'~'.$file.'.bak'); } - file_put_contents($path . '/' . $file, $formatter->format($catalogue->all($domain))); + file_put_contents($path.'/'.$file, $formatter->format($catalogue->all($domain))); } } } diff --git a/src/Symfony/Bundle/TwigBundle/Translation/TwigTranslationExtractor.php b/src/Symfony/Bundle/TwigBundle/Translation/TwigTranslationExtractor.php index a8873c6813b9a..cbea6c0d4e992 100644 --- a/src/Symfony/Bundle/TwigBundle/Translation/TwigTranslationExtractor.php +++ b/src/Symfony/Bundle/TwigBundle/Translation/TwigTranslationExtractor.php @@ -120,6 +120,7 @@ private function extractDomain(\Twig_Node $node) if ($node->getNode('arguments')->hasNode(1)) { return $node->getNode('arguments')->getNode(1)->getAttribute('value'); } + return $this->defaultDomain; } From b1efbb62e1cda03b5c38aeb95fac10f52f12deeb Mon Sep 17 00:00:00 2001 From: Michel Salib Date: Mon, 13 Jun 2011 14:32:41 +0200 Subject: [PATCH 06/13] tweak the twig bundle --- .../Command/TranslationUpdateCommand.php | 19 ++++++++----------- .../Translation/FileTranslationExtractor.php | 12 +++++++----- .../Translation/FileTranslationWriter.php | 18 ++++++++++++++---- .../Translation/TwigTranslationExtractor.php | 9 ++++++--- 4 files changed, 35 insertions(+), 23 deletions(-) diff --git a/src/Symfony/Bundle/TwigBundle/Command/TranslationUpdateCommand.php b/src/Symfony/Bundle/TwigBundle/Command/TranslationUpdateCommand.php index 6bf418f44ee0c..1170e7ac659d6 100644 --- a/src/Symfony/Bundle/TwigBundle/Command/TranslationUpdateCommand.php +++ b/src/Symfony/Bundle/TwigBundle/Command/TranslationUpdateCommand.php @@ -12,14 +12,7 @@ use Symfony\Component\Yaml\Yaml; class TranslationUpdateCommand extends Command -{ - /** - * Supported formats for output - * - * @var array - */ - private $supportedFormats = array('yml', 'xliff', 'php', 'pot'); - +{ /** * Compiled catalogue of messages * @var \Symfony\Component\Translation\MessageCatalogue @@ -43,7 +36,7 @@ protected function configure() ), new InputOption( 'output-format', null, InputOption::VALUE_OPTIONAL, - 'Override the default output format (' . implode(', ', $this->supportedFormats) . ')', 'yml' + 'Override the default output format', 'yml' ), new InputOption( 'source-lang', null, InputOption::VALUE_OPTIONAL, @@ -65,13 +58,18 @@ protected function configure() */ protected function execute(InputInterface $input, OutputInterface $output) { + // check presence of force or dump-message if ($input->getOption('force') !== true && $input->getOption('dump-messages') !== true) { $output->writeln('You must choose one of --force or --dump-messages'); return; } - if (!in_array($input->getOption('output-format'), $this->supportedFormats)) { + // check format + $fileWriter = $this->container->get('twig.translation.writer'); + $supportedFormats = $fileWriter->getFormats(); + if (!in_array($input->getOption('output-format'), $supportedFormats)) { $output->writeln('Wrong output format'); + $output->writeln('Supported formats are '.implode(', ', $supportedFormats).'.'); return; } @@ -107,7 +105,6 @@ protected function execute(InputInterface $input, OutputInterface $output) // save the files if($input->getOption('force') === true) { $output->writeln("Writing files"); - $fileWriter = $this->container->get('twig.translation.writer'); $fileWriter->writeTranslations($catalogue, $bundleTransPath, $input->getOption('output-format')); } } diff --git a/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationExtractor.php b/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationExtractor.php index de8110f8459c5..1a7dcd90031ab 100644 --- a/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationExtractor.php +++ b/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationExtractor.php @@ -17,27 +17,29 @@ class FileTranslationExtractor implements TranslationExtractorInterface * * @var array */ - private $loaders; + private $loaders = array(); /** * Add a loader to the translation extractor * @param string $format The format of the loader * @param LoaderInterface $loader */ - public function addLoader($format, LoaderInterface $loader){ + public function addLoader($format, LoaderInterface $loader) + { $this->loaders[$format] = $loader; } /** * {@inheritDoc} */ - public function extractMessages($directory, MessageCatalogue $catalogue) { + public function extractMessages($directory, MessageCatalogue $catalogue) + { foreach($this->loaders as $format => $loader) { // load any existing translation files $finder = new Finder(); - $files = $finder->files()->name('*.' . $catalogue->getLocale() . $format)->in($directory); + $files = $finder->files()->name('*.'.$catalogue->getLocale().$format)->in($directory); foreach ($files as $file) { - $domain = substr($file->getFileName(), 0, strrpos($file->getFileName(), $input->getArgument('locale') . $format) - 1); + $domain = substr($file->getFileName(), 0, strrpos($file->getFileName(), $input->getArgument('locale').$format) - 1); $catalogue->addCatalogue($loader->load($file->getPathname(), $input->getArgument('locale'), $domain)); } } diff --git a/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationWriter.php b/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationWriter.php index 6a2d560d74d15..d6c454de6675b 100644 --- a/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationWriter.php +++ b/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationWriter.php @@ -11,19 +11,29 @@ class FileTranslationWriter { /** - * Supported formats for import + * Supported formats for export * * @var array */ - private $formatters; + private $formatters = array(); /** * Add a formatter to the writer * @param string $format The format of the loader * @param FormatterInterface $formatter */ - public function addFormatter($format, FormatterInterface $formatter){ - $this->formatters[$format] = $formatters; + public function addFormatter($format, FormatterInterface $formatter) + { + $this->formatters[$format] = $formatter; + } + + /** + * Obtains the list of supported formats + * @return array + */ + public function getFormats() + { + return array_keys($this->formatters); } public function writeTranslations(MessageCatalogue $catalogue, $path, $format) diff --git a/src/Symfony/Bundle/TwigBundle/Translation/TwigTranslationExtractor.php b/src/Symfony/Bundle/TwigBundle/Translation/TwigTranslationExtractor.php index cbea6c0d4e992..19994090253f0 100644 --- a/src/Symfony/Bundle/TwigBundle/Translation/TwigTranslationExtractor.php +++ b/src/Symfony/Bundle/TwigBundle/Translation/TwigTranslationExtractor.php @@ -32,14 +32,16 @@ class TwigTranslationExtractor implements TranslationExtractorInterface */ private $twig; - public function __construct(Twig_Environment $twig) { + public function __construct(Twig_Environment $twig) + { $this->twig = $twig; } /** * {@inheritDoc} */ - public function extractMessages($directory, MessageCatalogue $catalogue) { + public function extractMessages($directory, MessageCatalogue $catalogue) + { $finder = new Finder(); $files = $finder->files()->name('*.html.twig')->in($directory); foreach ($files as $file) { @@ -52,7 +54,8 @@ public function extractMessages($directory, MessageCatalogue $catalogue) { * Set the prefix that should be used for new found messages * @param type $prefix The prefix */ - public function setPrefix($prefix) { + public function setPrefix($prefix) + { $this->prefix = $prefix; } From a8b8a8ac859f745185d3130a407927bfec8e587d Mon Sep 17 00:00:00 2001 From: Michel Salib Date: Mon, 13 Jun 2011 14:38:03 +0200 Subject: [PATCH 07/13] tweak the twig bundle --- .../Bundle/TwigBundle/Command/TranslationUpdateCommand.php | 2 +- .../Bundle/TwigBundle/Translation/FileTranslationExtractor.php | 2 +- .../Bundle/TwigBundle/Translation/FileTranslationWriter.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bundle/TwigBundle/Command/TranslationUpdateCommand.php b/src/Symfony/Bundle/TwigBundle/Command/TranslationUpdateCommand.php index 1170e7ac659d6..b1fa6ca693c6e 100644 --- a/src/Symfony/Bundle/TwigBundle/Command/TranslationUpdateCommand.php +++ b/src/Symfony/Bundle/TwigBundle/Command/TranslationUpdateCommand.php @@ -12,7 +12,7 @@ use Symfony\Component\Yaml\Yaml; class TranslationUpdateCommand extends Command -{ +{ /** * Compiled catalogue of messages * @var \Symfony\Component\Translation\MessageCatalogue diff --git a/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationExtractor.php b/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationExtractor.php index 1a7dcd90031ab..dbbf5aef72474 100644 --- a/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationExtractor.php +++ b/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationExtractor.php @@ -13,7 +13,7 @@ class FileTranslationExtractor implements TranslationExtractorInterface { /** - * Supported formats for import + * Loaders used for import * * @var array */ diff --git a/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationWriter.php b/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationWriter.php index d6c454de6675b..6fca505e262c3 100644 --- a/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationWriter.php +++ b/src/Symfony/Bundle/TwigBundle/Translation/FileTranslationWriter.php @@ -11,7 +11,7 @@ class FileTranslationWriter { /** - * Supported formats for export + * Formatters used for export * * @var array */ From b1021115908553b8c3f5b08e5e9b606e199da62f Mon Sep 17 00:00:00 2001 From: xaav Date: Mon, 13 Jun 2011 12:11:04 -0500 Subject: [PATCH 08/13] Added PHP Translation extractor. Change-Id: I82f982c43f7b781dd73ccd4cf5dbbb9f6917b4bb --- .../Translation/PhpTranslationExtractor.php | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/Symfony/Bundle/TwigBundle/Translation/PhpTranslationExtractor.php diff --git a/src/Symfony/Bundle/TwigBundle/Translation/PhpTranslationExtractor.php b/src/Symfony/Bundle/TwigBundle/Translation/PhpTranslationExtractor.php new file mode 100644 index 0000000000000..27e3a466d4ba0 --- /dev/null +++ b/src/Symfony/Bundle/TwigBundle/Translation/PhpTranslationExtractor.php @@ -0,0 +1,22 @@ +files()->name('*.php')->in($directory); + foreach ($files as $file) { + $this->parseTokens(token_get_all(file_get_contents($file)), $catalog); + } + } + + protected function parseTokens($tokens, $catalog) + { + + } +} \ No newline at end of file From fb2171d364ea14b3cb3f7949499b37c30d56b498 Mon Sep 17 00:00:00 2001 From: xaav Date: Mon, 13 Jun 2011 13:38:24 -0500 Subject: [PATCH 09/13] Updated extractor. Change-Id: I1e5fa125576451b4357aaf9b71f3186eb28c0ffd --- .../Translation/PhpTranslationExtractor.php | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/src/Symfony/Bundle/TwigBundle/Translation/PhpTranslationExtractor.php b/src/Symfony/Bundle/TwigBundle/Translation/PhpTranslationExtractor.php index 27e3a466d4ba0..c70f1ee3f7eaf 100644 --- a/src/Symfony/Bundle/TwigBundle/Translation/PhpTranslationExtractor.php +++ b/src/Symfony/Bundle/TwigBundle/Translation/PhpTranslationExtractor.php @@ -6,6 +6,23 @@ class PhpTranslationExtractor { + const MESSAGE_TOKEN = 300; + const IGNORE_TOKEN = 400; + + protected $sequences = array( + array( + '$view', + '[', + '\'translator\'', + ']', + '->', + 'trans', + '(', + self::MESSAGE_TOKEN, + ')', + ), + ); + public function extractMessages($directory, MessageCatalogue $catalog) { $finder = new Finder(); @@ -15,8 +32,50 @@ public function extractMessages($directory, MessageCatalogue $catalog) } } + protected function normalizeToken($token) + { + if(is_array($token)) { + + return $token[1]; + } + else { + + return $token; + } + } + protected function parseTokens($tokens, $catalog) { + foreach ($tokens as $key => $token) { + foreach ($this->sequences as $sequence) { + + $message = ''; + + foreach ($sequence as $id => $item) { + + if($this->normalizeToken($tokens[$key + $id]) == $item) { + continue; + } + elseif (self::MESSAGE_TOKEN == $item) { + + $message = $this->normalizeToken($tokens[$key + $id]); + } + elseif(self::IGNORE_TOKEN == $item) { + + continue; + } + else { + break; + } + } + + if($message) { + + $catalog->set($message, $message); + break; + } + } + } } } \ No newline at end of file From 6014581152b9b2dc164b9918657d26b765c67bfa Mon Sep 17 00:00:00 2001 From: Michel Salib Date: Mon, 13 Jun 2011 22:26:47 +0200 Subject: [PATCH 10/13] -- refactor the logic of translation:update command to use twig and php template loaders -- move some logic to the FrameworkBundle --- .../Command/TranslationUpdateCommand.php | 18 +-- .../TranslationFileExtractorPass.php} | 10 +- .../TranslationTemplateExtractorPass.php | 26 +++++ .../Compiler/TranslationWriterPass.php | 6 +- .../FrameworkBundle/FrameworkBundle.php | 6 + .../Resources/config/translation.xml | 34 ++++++ .../Translation/ExtractorInterface.php | 25 +++++ .../Translation/FileTranslationExtractor.php | 10 +- .../Translation/FileTranslationWriter.php | 2 +- .../Translation/PhpExtractor.php | 105 ++++++++++++++++++ .../TemplateTranslationExtractor.php | 57 ++++++++++ .../TwigBundle/Resources/config/twig.xml | 29 +---- .../Translation/PhpTranslationExtractor.php | 81 -------------- .../TranslationExtractorInterface.php | 19 ---- ...slationExtractor.php => TwigExtractor.php} | 31 +++--- src/Symfony/Bundle/TwigBundle/TwigBundle.php | 2 - 16 files changed, 293 insertions(+), 168 deletions(-) rename src/Symfony/Bundle/{TwigBundle => FrameworkBundle}/Command/TranslationUpdateCommand.php (87%) rename src/Symfony/Bundle/{TwigBundle/DependencyInjection/Compiler/TranslationExtractorPass.php => FrameworkBundle/DependencyInjection/Compiler/TranslationFileExtractorPass.php} (58%) create mode 100644 src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslationTemplateExtractorPass.php rename src/Symfony/Bundle/{TwigBundle => FrameworkBundle}/DependencyInjection/Compiler/TranslationWriterPass.php (75%) create mode 100644 src/Symfony/Bundle/FrameworkBundle/Translation/ExtractorInterface.php rename src/Symfony/Bundle/{TwigBundle => FrameworkBundle}/Translation/FileTranslationExtractor.php (82%) rename src/Symfony/Bundle/{TwigBundle => FrameworkBundle}/Translation/FileTranslationWriter.php (96%) create mode 100644 src/Symfony/Bundle/FrameworkBundle/Translation/PhpExtractor.php create mode 100644 src/Symfony/Bundle/FrameworkBundle/Translation/TemplateTranslationExtractor.php delete mode 100644 src/Symfony/Bundle/TwigBundle/Translation/PhpTranslationExtractor.php delete mode 100644 src/Symfony/Bundle/TwigBundle/Translation/TranslationExtractorInterface.php rename src/Symfony/Bundle/TwigBundle/Translation/{TwigTranslationExtractor.php => TwigExtractor.php} (77%) diff --git a/src/Symfony/Bundle/TwigBundle/Command/TranslationUpdateCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php similarity index 87% rename from src/Symfony/Bundle/TwigBundle/Command/TranslationUpdateCommand.php rename to src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php index b1fa6ca693c6e..d32ebac3fe684 100644 --- a/src/Symfony/Bundle/TwigBundle/Command/TranslationUpdateCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php @@ -1,6 +1,6 @@ setName('twig:translation:update') + ->setName('translation:update') ->setDescription('Update the translation file') ->setDefinition(array( new InputArgument('locale', InputArgument::REQUIRED, 'The locale'), @@ -65,7 +65,7 @@ protected function execute(InputInterface $input, OutputInterface $output) } // check format - $fileWriter = $this->container->get('twig.translation.writer'); + $fileWriter = $this->container->get('translation.writer'); $supportedFormats = $fileWriter->getFormats(); if (!in_array($input->getOption('output-format'), $supportedFormats)) { $output->writeln('Wrong output format'); @@ -83,13 +83,13 @@ protected function execute(InputInterface $input, OutputInterface $output) // load any messages from templates $output->writeln('Parsing templates'); - $twigExtractor = $this->container->get('twig.translation.extractor'); - $twigExtractor->setPrefix($input->getOption('prefix')); - $twigExtractor->extractMessages($foundBundle->getPath() . '/Resources/views/', $catalogue); + $templateExtractor = $this->container->get('translation.extractor.template'); + $templateExtractor->setPrefix($input->getOption('prefix')); + $templateExtractor->extractMessages($foundBundle->getPath() . '/Resources/views/', $catalogue); // load any existing messages from the translation files $output->writeln('Parsing translation files'); - $fileExtractor = $this->container->get('twig.translation.extractor.file'); + $fileExtractor = $this->container->get('translation.extractor.file'); $fileExtractor->extractMessages($bundleTransPath, $catalogue); // show compiled list of messages @@ -104,7 +104,7 @@ protected function execute(InputInterface $input, OutputInterface $output) // save the files if($input->getOption('force') === true) { - $output->writeln("Writing files"); + $output->writeln('Writing files'); $fileWriter->writeTranslations($catalogue, $bundleTransPath, $input->getOption('output-format')); } } diff --git a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TranslationExtractorPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslationFileExtractorPass.php similarity index 58% rename from src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TranslationExtractorPass.php rename to src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslationFileExtractorPass.php index bfcab011e3c5f..2942073d715d2 100644 --- a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TranslationExtractorPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslationFileExtractorPass.php @@ -1,23 +1,23 @@ hasDefinition('twig.translation.extractor.file')) { + if (!$container->hasDefinition('translation.extractor.file')) { return; } - $definition = $container->getDefinition('twig.translation.extractor.file'); + $definition = $container->getDefinition('translation.extractor.file'); foreach ($container->findTaggedServiceIds('translation.loader') as $id => $attributes) { $definition->addMethodCall('addLoader', array($attributes[0]['alias'], new Reference($id))); diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslationTemplateExtractorPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslationTemplateExtractorPass.php new file mode 100644 index 0000000000000..7403c38d89526 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslationTemplateExtractorPass.php @@ -0,0 +1,26 @@ +hasDefinition('translation.extractor.template')) { + return; + } + + $definition = $container->getDefinition('translation.extractor.template'); + + foreach ($container->findTaggedServiceIds('translation.extractor') as $id => $attributes) { + $definition->addMethodCall('addExtractor', array($attributes[0]['alias'], new Reference($id))); + } + } +} diff --git a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TranslationWriterPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslationWriterPass.php similarity index 75% rename from src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TranslationWriterPass.php rename to src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslationWriterPass.php index a407af4dc13c7..90a16ba015a06 100644 --- a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/TranslationWriterPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslationWriterPass.php @@ -1,6 +1,6 @@ hasDefinition('twig.translation.writer')) { + if (!$container->hasDefinition('translation.writer')) { return; } - $definition = $container->getDefinition('twig.translation.writer'); + $definition = $container->getDefinition('translation.writer'); foreach ($container->findTaggedServiceIds('translation.formatter') as $id => $attributes) { $definition->addMethodCall('addFormatter', array($attributes[0]['alias'], new Reference($id))); diff --git a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php index fd0e53cda0ba1..19bd5532380d8 100644 --- a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php +++ b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php @@ -21,6 +21,9 @@ use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddCacheWarmerPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ContainerBuilderDebugDumpPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\CompilerDebugDumpPass; +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslationTemplateExtractorPass; +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslationFileExtractorPass; +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslationWriterPass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Compiler\PassConfig; use Symfony\Component\DependencyInjection\Scope; @@ -48,6 +51,9 @@ public function build(ContainerBuilder $container) $container->addCompilerPass(new FormPass()); $container->addCompilerPass(new TranslatorPass()); $container->addCompilerPass(new AddCacheWarmerPass()); + $container->addCompilerPass(new TranslationTemplateExtractorPass()); + $container->addCompilerPass(new TranslationFileExtractorPass()); + $container->addCompilerPass(new TranslationWriterPass()); if ($container->getParameter('kernel.debug')) { $container->addCompilerPass(new ContainerBuilderDebugDumpPass(), PassConfig::TYPE_AFTER_REMOVING); diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml index f382ed06dbc08..82ca6ddb8c15c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml @@ -11,6 +11,14 @@ Symfony\Component\Translation\Loader\PhpFileLoader Symfony\Component\Translation\Loader\YamlFileLoader Symfony\Component\Translation\Loader\XliffFileLoader + Symfony\Component\Translation\Formatter\PhpFormatter + Symfony\Component\Translation\Formatter\PotFormatter + Symfony\Component\Translation\Formatter\XliffFormatter + Symfony\Component\Translation\Formatter\YamlFormatter + Symfony\Bundle\FrameworkBundle\Translation\PhpExtractor + Symfony\Bundle\FrameworkBundle\Translation\TemplateTranslationExtractor + Symfony\Bundle\FrameworkBundle\Translation\FileTranslationExtractor + Symfony\Bundle\FrameworkBundle\Translation\FileTranslationWriter @@ -42,5 +50,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Translation/ExtractorInterface.php b/src/Symfony/Bundle/FrameworkBundle/Translation/ExtractorInterface.php new file mode 100644 index 0000000000000..8ecc4c9029f27 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Translation/ExtractorInterface.php @@ -0,0 +1,25 @@ +', + 'trans', + '(', + self::MESSAGE_TOKEN, + ')', + ), + ); + + /** + * {@inheritDoc} + */ + public function load($file, MessageCatalogue $catalog) + { + $this->parseTokens(token_get_all(file_get_contents($file)), $catalog); + } + + /** + * {@inheritDoc} + */ + public function setPrefix($prefix) + { + $this->prefix = $prefix; + } + + /** + * Normalize a token + * + * @param mixed $token + * @return string + */ + protected function normalizeToken($token) + { + if(is_array($token)) + return $token[1]; + + return $token; + } + + /** + * Extract trans message from php tokens + * + * @param array $tokens + * @param MessageCatalogue $catalog + */ + protected function parseTokens($tokens, MessageCatalogue $catalog) + { + foreach ($tokens as $key => $token) { + foreach ($this->sequences as $sequence) { + $message = ''; + + foreach ($sequence as $id => $item) { + if($this->normalizeToken($tokens[$key + $id]) == $item) { + continue; + } + elseif (self::MESSAGE_TOKEN == $item) { + $message = $this->normalizeToken($tokens[$key + $id]); + } + elseif (self::IGNORE_TOKEN == $item) { + continue; + } + else { + break; + } + } + + if ($message) { + $catalog->set($message, $this->prefix.$message); + break; + } + } + } + } +} diff --git a/src/Symfony/Bundle/FrameworkBundle/Translation/TemplateTranslationExtractor.php b/src/Symfony/Bundle/FrameworkBundle/Translation/TemplateTranslationExtractor.php new file mode 100644 index 0000000000000..67e91bf4e57c8 --- /dev/null +++ b/src/Symfony/Bundle/FrameworkBundle/Translation/TemplateTranslationExtractor.php @@ -0,0 +1,57 @@ +extractors[$format] = $extactor; + } + + /** + * Set prefix applied for new found messages + */ + public function setPrefix($prefix) + { + foreach($this->extractors as $extractor){ + $extractor->setPrefix($prefix); + } + } + + /** + * Extract translation messages from a directory to the catalogue + * + * @param string $directory the directory to look into + * @param MessageCatalogue $catalogue the catalogue + */ + public function extractMessages($directory, MessageCatalogue $catalogue) + { + foreach($this->extractors as $format => $extactor) { + // load any existing translation files + $finder = new Finder(); + $files = $finder->files()->name('*.'.$format)->in($directory); + foreach ($files as $file) { + $extactor->load($file, $catalogue); + } + } + } +} diff --git a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml index d81d3de77520d..a568348112fee 100644 --- a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml +++ b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml @@ -18,13 +18,7 @@ Symfony\Bridge\Twig\Extension\FormExtension Twig_Extensions_Extension_Text Twig_Extensions_Extension_Debug - Symfony\Component\Translation\Formatter\PhpFormatter - Symfony\Component\Translation\Formatter\PotFormatter - Symfony\Component\Translation\Formatter\XliffFormatter - Symfony\Component\Translation\Formatter\YamlFormatter - Symfony\Bundle\TwigBundle\Translation\TwigTranslationExtractor - Symfony\Bundle\TwigBundle\Translation\FileTranslationExtractor - Symfony\Bundle\TwigBundle\Translation\FileTranslationWriter + Symfony\Bundle\TwigBundle\Translation\TwigExtractor @@ -88,28 +82,9 @@ - - - - - - - - - - - - - - - - + - - - - diff --git a/src/Symfony/Bundle/TwigBundle/Translation/PhpTranslationExtractor.php b/src/Symfony/Bundle/TwigBundle/Translation/PhpTranslationExtractor.php deleted file mode 100644 index c70f1ee3f7eaf..0000000000000 --- a/src/Symfony/Bundle/TwigBundle/Translation/PhpTranslationExtractor.php +++ /dev/null @@ -1,81 +0,0 @@ -', - 'trans', - '(', - self::MESSAGE_TOKEN, - ')', - ), - ); - - public function extractMessages($directory, MessageCatalogue $catalog) - { - $finder = new Finder(); - $files = $finder->files()->name('*.php')->in($directory); - foreach ($files as $file) { - $this->parseTokens(token_get_all(file_get_contents($file)), $catalog); - } - } - - protected function normalizeToken($token) - { - if(is_array($token)) { - - return $token[1]; - } - else { - - return $token; - } - } - - protected function parseTokens($tokens, $catalog) - { - foreach ($tokens as $key => $token) { - - foreach ($this->sequences as $sequence) { - - $message = ''; - - foreach ($sequence as $id => $item) { - - if($this->normalizeToken($tokens[$key + $id]) == $item) { - continue; - } - elseif (self::MESSAGE_TOKEN == $item) { - - $message = $this->normalizeToken($tokens[$key + $id]); - } - elseif(self::IGNORE_TOKEN == $item) { - - continue; - } - else { - break; - } - } - - if($message) { - - $catalog->set($message, $message); - break; - } - } - } - } -} \ No newline at end of file diff --git a/src/Symfony/Bundle/TwigBundle/Translation/TranslationExtractorInterface.php b/src/Symfony/Bundle/TwigBundle/Translation/TranslationExtractorInterface.php deleted file mode 100644 index 9b9d519a194b7..0000000000000 --- a/src/Symfony/Bundle/TwigBundle/Translation/TranslationExtractorInterface.php +++ /dev/null @@ -1,19 +0,0 @@ -files()->name('*.html.twig')->in($directory); - foreach ($files as $file) { - $tree = $this->twig->parse($this->twig->tokenize(file_get_contents($file->getPathname()))); - $this->crawlNode($tree, $catalogue); - } + $tree = $this->twig->parse($this->twig->tokenize(file_get_contents($file->getPathname()))); + $this->crawlNode($tree, $catalogue); } - + /** - * Set the prefix that should be used for new found messages - * @param type $prefix The prefix + * {@inheritDoc} */ public function setPrefix($prefix) { @@ -62,9 +57,10 @@ public function setPrefix($prefix) /** * Recursive function that extract trans message from a twig tree * - * @param \Twig_Node The twig tree root + * @param \Twig_Node $node The twig tree root + * @param MessageCatalogue $catalogue */ - private function crawlNode(\Twig_Node $node, $catalogue) + private function crawlNode(\Twig_Node $node, MessageCatalogue $catalogue) { if ($node instanceof TransNode && !$node->getNode('body') instanceof \Twig_Node_Expression_GetAttr) { // trans block @@ -130,3 +126,4 @@ private function extractDomain(\Twig_Node $node) return $this->extractDomain($node->getNode('node')); } } + diff --git a/src/Symfony/Bundle/TwigBundle/TwigBundle.php b/src/Symfony/Bundle/TwigBundle/TwigBundle.php index ab1cc66112f3c..52ed25fd2f65e 100644 --- a/src/Symfony/Bundle/TwigBundle/TwigBundle.php +++ b/src/Symfony/Bundle/TwigBundle/TwigBundle.php @@ -29,7 +29,5 @@ public function build(ContainerBuilder $container) parent::build($container); $container->addCompilerPass(new TwigEnvironmentPass()); - $container->addCompilerPass(new TranslationExtractorPass()); - $container->addCompilerPass(new TranslationWriterPass()); } } From 7c0329478bb273654bd28cc5763ac8c58ff0fc65 Mon Sep 17 00:00:00 2001 From: Michel Salib Date: Mon, 13 Jun 2011 23:30:38 +0200 Subject: [PATCH 11/13] -- tweak the translation loader, writer and extractor --- .../Command/TranslationUpdateCommand.php | 12 ++++----- ...rPass.php => TranslationExtractorPass.php} | 8 +++--- .../Compiler/TranslationFileExtractorPass.php | 26 ------------------- .../Compiler/TranslatorPass.php | 18 ++++++++----- .../FrameworkBundle/FrameworkBundle.php | 6 ++--- .../Resources/config/translation.xml | 10 +++---- .../Translation/PhpExtractor.php | 23 +++++++++------- ...ionExtractor.php => TranslationLoader.php} | 8 +++--- .../TwigBundle/Translation/TwigExtractor.php | 14 +++++++--- .../Extractor}/ExtractorInterface.php | 11 ++++---- .../Extractor/TranslationExtractor.php} | 22 ++++++---------- .../Translation/Writer/TranslationWriter.php} | 6 ++--- 12 files changed, 74 insertions(+), 90 deletions(-) rename src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/{TranslationTemplateExtractorPass.php => TranslationExtractorPass.php} (72%) delete mode 100644 src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslationFileExtractorPass.php rename src/Symfony/Bundle/FrameworkBundle/Translation/{FileTranslationExtractor.php => TranslationLoader.php} (85%) rename src/Symfony/{Bundle/FrameworkBundle/Translation => Component/Translation/Extractor}/ExtractorInterface.php (56%) rename src/Symfony/{Bundle/FrameworkBundle/Translation/TemplateTranslationExtractor.php => Component/Translation/Extractor/TranslationExtractor.php} (59%) rename src/Symfony/{Bundle/FrameworkBundle/Translation/FileTranslationWriter.php => Component/Translation/Writer/TranslationWriter.php} (93%) diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php index d32ebac3fe684..e58bd93e47869 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php @@ -83,14 +83,14 @@ protected function execute(InputInterface $input, OutputInterface $output) // load any messages from templates $output->writeln('Parsing templates'); - $templateExtractor = $this->container->get('translation.extractor.template'); - $templateExtractor->setPrefix($input->getOption('prefix')); - $templateExtractor->extractMessages($foundBundle->getPath() . '/Resources/views/', $catalogue); + $extractor = $this->container->get('translation.extractor'); + $extractor->setPrefix($input->getOption('prefix')); + $extractor->extractMessages($foundBundle->getPath() . '/Resources/views/', $catalogue); // load any existing messages from the translation files - $output->writeln('Parsing translation files'); - $fileExtractor = $this->container->get('translation.extractor.file'); - $fileExtractor->extractMessages($bundleTransPath, $catalogue); + $output->writeln('Loading translation files'); + $loader = $this->container->get('translation.loader'); + $loader->loadMessages($bundleTransPath, $catalogue); // show compiled list of messages if($input->getOption('dump-messages') === true){ diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslationTemplateExtractorPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslationExtractorPass.php similarity index 72% rename from src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslationTemplateExtractorPass.php rename to src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslationExtractorPass.php index 7403c38d89526..a03cecca7acd5 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslationTemplateExtractorPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslationExtractorPass.php @@ -7,17 +7,17 @@ use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; /** - * Adds tagged translation.extractor services to template translation extractor + * Adds tagged translation.extractor services to translation extractor */ -class TranslationTemplateExtractorPass implements CompilerPassInterface +class TranslationExtractorPass implements CompilerPassInterface { public function process(ContainerBuilder $container) { - if (!$container->hasDefinition('translation.extractor.template')) { + if (!$container->hasDefinition('translation.extractor')) { return; } - $definition = $container->getDefinition('translation.extractor.template'); + $definition = $container->getDefinition('translation.extractor'); foreach ($container->findTaggedServiceIds('translation.extractor') as $id => $attributes) { $definition->addMethodCall('addExtractor', array($attributes[0]['alias'], new Reference($id))); diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslationFileExtractorPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslationFileExtractorPass.php deleted file mode 100644 index 2942073d715d2..0000000000000 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslationFileExtractorPass.php +++ /dev/null @@ -1,26 +0,0 @@ -hasDefinition('translation.extractor.file')) { - return; - } - - $definition = $container->getDefinition('translation.extractor.file'); - - foreach ($container->findTaggedServiceIds('translation.loader') as $id => $attributes) { - $definition->addMethodCall('addLoader', array($attributes[0]['alias'], new Reference($id))); - } - } -} diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslatorPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslatorPass.php index 9220b5df5d13d..d25d793130585 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslatorPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslatorPass.php @@ -11,6 +11,7 @@ namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler; +use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; @@ -18,14 +19,19 @@ class TranslatorPass implements CompilerPassInterface { public function process(ContainerBuilder $container) { - if (!$container->hasDefinition('translator.real')) { - return; + if ($container->hasDefinition('translator.real')) { + $loaders = array(); + foreach ($container->findTaggedServiceIds('translation.loader') as $id => $attributes) { + $loaders[$id] = $attributes[0]['alias']; + } + $container->findDefinition('translator.real')->replaceArgument(2, $loaders); } - $loaders = array(); - foreach ($container->findTaggedServiceIds('translation.loader') as $id => $attributes) { - $loaders[$id] = $attributes[0]['alias']; + if ($container->hasDefinition('translation.loader')) { + $definition = $container->getDefinition('translation.loader'); + foreach ($container->findTaggedServiceIds('translation.loader') as $id => $attributes) { + $definition->addMethodCall('addLoader', array($attributes[0]['alias'], new Reference($id))); + } } - $container->findDefinition('translator.real')->replaceArgument(2, $loaders); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php index 19bd5532380d8..2e5be1eb7941f 100644 --- a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php +++ b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php @@ -21,8 +21,7 @@ use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddCacheWarmerPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ContainerBuilderDebugDumpPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\CompilerDebugDumpPass; -use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslationTemplateExtractorPass; -use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslationFileExtractorPass; +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslationExtractorPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslationWriterPass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Compiler\PassConfig; @@ -51,8 +50,7 @@ public function build(ContainerBuilder $container) $container->addCompilerPass(new FormPass()); $container->addCompilerPass(new TranslatorPass()); $container->addCompilerPass(new AddCacheWarmerPass()); - $container->addCompilerPass(new TranslationTemplateExtractorPass()); - $container->addCompilerPass(new TranslationFileExtractorPass()); + $container->addCompilerPass(new TranslationExtractorPass()); $container->addCompilerPass(new TranslationWriterPass()); if ($container->getParameter('kernel.debug')) { diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml index 82ca6ddb8c15c..ab6a7c17e738c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/translation.xml @@ -16,9 +16,9 @@ Symfony\Component\Translation\Formatter\XliffFormatter Symfony\Component\Translation\Formatter\YamlFormatter Symfony\Bundle\FrameworkBundle\Translation\PhpExtractor - Symfony\Bundle\FrameworkBundle\Translation\TemplateTranslationExtractor - Symfony\Bundle\FrameworkBundle\Translation\FileTranslationExtractor - Symfony\Bundle\FrameworkBundle\Translation\FileTranslationWriter + Symfony\Bundle\FrameworkBundle\Translation\TranslationLoader + Symfony\Component\Translation\Extractor\TranslationExtractor + Symfony\Component\Translation\Writer\TranslationWriter @@ -71,9 +71,9 @@ - + - + diff --git a/src/Symfony/Bundle/FrameworkBundle/Translation/PhpExtractor.php b/src/Symfony/Bundle/FrameworkBundle/Translation/PhpExtractor.php index d63f95a3c6c8c..18736a61ce99c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Translation/PhpExtractor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Translation/PhpExtractor.php @@ -2,7 +2,9 @@ namespace Symfony\Bundle\FrameworkBundle\Translation; +use Symfony\Component\Finder\Finder; use Symfony\Component\Translation\MessageCatalogue; +use Symfony\Component\Translation\Extractor\ExtractorInterface; /** * Extract translation messages from a php template @@ -41,9 +43,14 @@ class PhpExtractor implements ExtractorInterface /** * {@inheritDoc} */ - public function load($file, MessageCatalogue $catalog) + public function load($directory, MessageCatalogue $catalog) { - $this->parseTokens(token_get_all(file_get_contents($file)), $catalog); + // load any existing translation files + $finder = new Finder(); + $files = $finder->files()->name('*.php')->in($directory); + foreach ($files as $file) { + $this->parseTokens(token_get_all(file_get_contents($file)), $catalog); + } } /** @@ -62,8 +69,9 @@ public function setPrefix($prefix) */ protected function normalizeToken($token) { - if(is_array($token)) + if (is_array($token)) { return $token[1]; + } return $token; } @@ -83,14 +91,11 @@ protected function parseTokens($tokens, MessageCatalogue $catalog) foreach ($sequence as $id => $item) { if($this->normalizeToken($tokens[$key + $id]) == $item) { continue; - } - elseif (self::MESSAGE_TOKEN == $item) { + } elseif (self::MESSAGE_TOKEN == $item) { $message = $this->normalizeToken($tokens[$key + $id]); - } - elseif (self::IGNORE_TOKEN == $item) { + } elseif (self::IGNORE_TOKEN == $item) { continue; - } - else { + } else { break; } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Translation/FileTranslationExtractor.php b/src/Symfony/Bundle/FrameworkBundle/Translation/TranslationLoader.php similarity index 85% rename from src/Symfony/Bundle/FrameworkBundle/Translation/FileTranslationExtractor.php rename to src/Symfony/Bundle/FrameworkBundle/Translation/TranslationLoader.php index d515d3223ec97..2cc85c6cb04fe 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Translation/FileTranslationExtractor.php +++ b/src/Symfony/Bundle/FrameworkBundle/Translation/TranslationLoader.php @@ -7,9 +7,9 @@ use Symfony\Component\Translation\Loader\LoaderInterface; /** - * Extract translation messages from translation files + * Load translation messages from translation files */ -class FileTranslationExtractor +class TranslationLoader { /** * Loaders used for import @@ -29,12 +29,12 @@ public function addLoader($format, LoaderInterface $loader) } /** - * Extract translation messages from a directory to the catalogue + * Load translation messages from a directory to the catalogue * * @param string $directory the directory to look into * @param MessageCatalogue $catalogue the catalogue */ - public function extractMessages($directory, MessageCatalogue $catalogue) + public function loadMessages($directory, MessageCatalogue $catalogue) { foreach($this->loaders as $format => $loader) { // load any existing translation files diff --git a/src/Symfony/Bundle/TwigBundle/Translation/TwigExtractor.php b/src/Symfony/Bundle/TwigBundle/Translation/TwigExtractor.php index 9d83acbb526f2..bf98599007443 100644 --- a/src/Symfony/Bundle/TwigBundle/Translation/TwigExtractor.php +++ b/src/Symfony/Bundle/TwigBundle/Translation/TwigExtractor.php @@ -2,7 +2,8 @@ namespace Symfony\Bundle\TwigBundle\Translation; -use Symfony\Bundle\FrameworkBundle\Translation\ExtractorInterface; +use Symfony\Component\Finder\Finder; +use Symfony\Component\Translation\Extractor\ExtractorInterface; use Symfony\Component\Translation\MessageCatalogue; use Symfony\Bridge\Twig\Node\TransNode; use Twig_Environment; @@ -40,10 +41,15 @@ public function __construct(Twig_Environment $twig) /** * {@inheritDoc} */ - public function load($file, MessageCatalogue $catalogue) + public function load($directory, MessageCatalogue $catalogue) { - $tree = $this->twig->parse($this->twig->tokenize(file_get_contents($file->getPathname()))); - $this->crawlNode($tree, $catalogue); + // load any existing translation files + $finder = new Finder(); + $files = $finder->files()->name('*.twig')->in($directory); + foreach ($files as $file) { + $tree = $this->twig->parse($this->twig->tokenize(file_get_contents($file->getPathname()))); + $this->crawlNode($tree, $catalogue); + } } /** diff --git a/src/Symfony/Bundle/FrameworkBundle/Translation/ExtractorInterface.php b/src/Symfony/Component/Translation/Extractor/ExtractorInterface.php similarity index 56% rename from src/Symfony/Bundle/FrameworkBundle/Translation/ExtractorInterface.php rename to src/Symfony/Component/Translation/Extractor/ExtractorInterface.php index 8ecc4c9029f27..48f7dd2c18278 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Translation/ExtractorInterface.php +++ b/src/Symfony/Component/Translation/Extractor/ExtractorInterface.php @@ -1,20 +1,21 @@ extractors[$format] = $extactor; + $this->extractors[$format] = $extractor; } /** @@ -45,13 +44,8 @@ public function setPrefix($prefix) */ public function extractMessages($directory, MessageCatalogue $catalogue) { - foreach($this->extractors as $format => $extactor) { - // load any existing translation files - $finder = new Finder(); - $files = $finder->files()->name('*.'.$format)->in($directory); - foreach ($files as $file) { - $extactor->load($file, $catalogue); - } + foreach ($this->extractors as $extractor) { + $extractor->load($directory, $catalogue); } } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Translation/FileTranslationWriter.php b/src/Symfony/Component/Translation/Writer/TranslationWriter.php similarity index 93% rename from src/Symfony/Bundle/FrameworkBundle/Translation/FileTranslationWriter.php rename to src/Symfony/Component/Translation/Writer/TranslationWriter.php index 90472ad73482f..11f8b0837b9d9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Translation/FileTranslationWriter.php +++ b/src/Symfony/Component/Translation/Writer/TranslationWriter.php @@ -1,6 +1,6 @@ Date: Mon, 13 Jun 2011 23:36:27 +0200 Subject: [PATCH 12/13] tweak the TranslatorPass --- .../DependencyInjection/Compiler/TranslatorPass.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslatorPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslatorPass.php index d25d793130585..85cbd5a187f08 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslatorPass.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/TranslatorPass.php @@ -19,18 +19,19 @@ class TranslatorPass implements CompilerPassInterface { public function process(ContainerBuilder $container) { + $loaders = array(); + foreach ($container->findTaggedServiceIds('translation.loader') as $id => $attributes) { + $loaders[$id] = $attributes[0]['alias']; + } + if ($container->hasDefinition('translator.real')) { - $loaders = array(); - foreach ($container->findTaggedServiceIds('translation.loader') as $id => $attributes) { - $loaders[$id] = $attributes[0]['alias']; - } $container->findDefinition('translator.real')->replaceArgument(2, $loaders); } if ($container->hasDefinition('translation.loader')) { $definition = $container->getDefinition('translation.loader'); - foreach ($container->findTaggedServiceIds('translation.loader') as $id => $attributes) { - $definition->addMethodCall('addLoader', array($attributes[0]['alias'], new Reference($id))); + foreach ($loaders as $id => $format) { + $definition->addMethodCall('addLoader', array($format, new Reference($id))); } } } From 14b39844c4614d14f66dfdc1d71be1b15913718f Mon Sep 17 00:00:00 2001 From: Michel Salib Date: Sat, 2 Jul 2011 15:44:20 +0200 Subject: [PATCH 13/13] -- update the translation:update Command to ContainerAwareCommand --- .../Command/TranslationUpdateCommand.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php index e58bd93e47869..a59b6381e62c6 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php @@ -2,7 +2,7 @@ namespace Symfony\Bundle\FrameworkBundle\Command; -use Symfony\Bundle\FrameworkBundle\Command\Command; +use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Finder\Finder; @@ -11,7 +11,7 @@ use Symfony\Component\Translation\MessageCatalogue; use Symfony\Component\Yaml\Yaml; -class TranslationUpdateCommand extends Command +class TranslationUpdateCommand extends ContainerAwareCommand { /** * Compiled catalogue of messages @@ -65,7 +65,7 @@ protected function execute(InputInterface $input, OutputInterface $output) } // check format - $fileWriter = $this->container->get('translation.writer'); + $fileWriter = $this->getContainer()->get('translation.writer'); $supportedFormats = $fileWriter->getFormats(); if (!in_array($input->getOption('output-format'), $supportedFormats)) { $output->writeln('Wrong output format'); @@ -83,13 +83,13 @@ protected function execute(InputInterface $input, OutputInterface $output) // load any messages from templates $output->writeln('Parsing templates'); - $extractor = $this->container->get('translation.extractor'); + $extractor = $this->getContainer()->get('translation.extractor'); $extractor->setPrefix($input->getOption('prefix')); $extractor->extractMessages($foundBundle->getPath() . '/Resources/views/', $catalogue); // load any existing messages from the translation files $output->writeln('Loading translation files'); - $loader = $this->container->get('translation.loader'); + $loader = $this->getContainer()->get('translation.loader'); $loader->loadMessages($bundleTransPath, $catalogue); // show compiled list of messages