Ver código fonte

make the tab menu translation easier to customize

Having a huge messages catalog is a bad idea. Moreover, having the
option to use translation parameters can be a real plus.
Grégoire Paris 9 anos atrás
pai
commit
d85339fb20

+ 23 - 0
Resources/doc/reference/advanced_configuration.rst

@@ -282,6 +282,29 @@ If you want to use the Tab Menu in a different way, you can replace the Menu Tem
             templates:
                 tab_menu_template:  AppBundle:Admin:own_tab_menu_template.html.twig
 
+Translations
+^^^^^^^^^^^^
+
+The translation parameters and domain can be customised by using the
+``translation_domain`` and ``translation_parameters`` keys of the extra array
+of data associated with the item, respectively.
+
+.. code-block:: php
+
+    <?php
+    $menuItem->setExtras(array(
+        'translation_parameters' => array('myparam' => 'myvalue'),
+        'translation_domain' => 'My domain',
+    ));
+
+You can also set the translation domain on the menu root, and children will
+inherit it :
+
+.. code-block:: php
+
+    <?php
+    $menu->setExtra('translation_domain', 'My domain');
+
 Disable content stretching
 --------------------------
 

+ 11 - 1
Resources/views/Core/tab_menu_template.html.twig

@@ -115,4 +115,14 @@
     </a>
 {% endblock %}
 
-{% block label %}{{ item.label|trans }}{% endblock %}
+{% block label %}
+{{-
+    item.label|trans(
+        item.getExtra('translation_params', {}),
+        item.getExtra(
+            'translation_domain',
+            item.getParent() ? item.getParent().getExtra('translation_domain') : null
+        )
+    )
+-}}
+{% endblock %}

+ 74 - 0
Tests/Menu/Integration/BaseMenuTest.php

@@ -0,0 +1,74 @@
+<?php
+
+/*
+ * This file is part of the Sonata Project package.
+ *
+ * (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Sonata\AdminBundle\Tests\Menu\Integration;
+
+use Knp\Menu\ItemInterface;
+use Knp\Menu\Renderer\TwigRenderer;
+use Symfony\Bridge\Twig\Extension\TranslationExtension;
+use Symfony\Bridge\Twig\Tests\Extension\Fixtures\StubFilesystemLoader;
+use Symfony\Bundle\FrameworkBundle\Tests\Templating\Helper\Fixtures\StubTranslator;
+
+/**
+ * Class BaseTemplateTest.
+ *
+ * Base class for tests checking rendering of twig templates
+ */
+abstract class BaseMenuTest extends \PHPUnit_Framework_TestCase
+{
+    abstract protected function getTemplate();
+
+    protected function getTranslator()
+    {
+        return new StubTranslator();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setUp()
+    {
+        $twigPaths = array(
+            __DIR__.'/../../../vendor/knplabs/knp-menu/src/Knp/Menu/Resources/views',
+            __DIR__.'/../../../Resources/views',
+        );
+        $loader = new StubFilesystemLoader($twigPaths);
+        $this->environment = new \Twig_Environment($loader, array('strict_variables' => true));
+    }
+
+    protected function renderMenu(ItemInterface $item, array $options = array())
+    {
+        $this->environment->addExtension(new TranslationExtension($this->getTranslator()));
+        $this->renderer = new TwigRenderer(
+            $this->environment,
+            $this->getTemplate(),
+            $this->getMock('Knp\Menu\Matcher\MatcherInterface')
+        );
+
+        return $this->renderer->render($item, $options);
+    }
+
+    /**
+     * Helper method to strip newline and space characters from html string to make comparing easier.
+     *
+     * @param string $html
+     *
+     * @return string
+     */
+    protected function cleanHtmlWhitespace($html)
+    {
+        $html = preg_replace_callback('/>([^<]+)</', function ($value) {
+            return '>'.trim($value[1]).'<';
+        }, $html);
+
+        return $html;
+    }
+}

+ 105 - 0
Tests/Menu/Integration/TabMenuTest.php

@@ -0,0 +1,105 @@
+<?php
+
+/*
+ * This file is part of the Sonata Project package.
+ *
+ * (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Sonata\AdminBundle\Tests\Menu\Integration;
+
+use Knp\Menu\MenuFactory;
+use Knp\Menu\MenuItem;
+use Prophecy\Argument;
+
+class TabMenuTest extends BaseMenuTest
+{
+    protected $translator;
+
+    protected function getTemplate()
+    {
+        return 'Core/tab_menu_template.html.twig';
+    }
+
+    public function getTranslator()
+    {
+        if (isset($this->translator)) {
+            return $this->translator;
+        }
+
+        return parent::getTranslator();
+    }
+
+    public function testLabelTranslationNominalCase()
+    {
+        $translatorProphecy = $this->prophesize(
+            'Symfony\Component\Translation\TranslatorInterface'
+        );
+        $translatorProphecy
+            ->trans(
+                'some-label',
+                array(),
+                Argument::any(), //messages or null
+                null
+            )
+            ->willReturn('my-translation');
+
+        $this->translator = $translatorProphecy->reveal();
+        $factory = new MenuFactory();
+        $menu = new MenuItem('test-menu', $factory);
+        $menu->addChild('some-label', array('uri' => '/whatever'));
+        $this->assertContains('my-translation', $this->renderMenu($menu));
+    }
+
+    public function testLabelTranslationWithParameters()
+    {
+        $params = array('my' => 'param');
+        $translatorProphecy = $this->prophesize(
+            'Symfony\Component\Translation\TranslatorInterface'
+        );
+        $translatorProphecy
+            ->trans(
+                'some-label',
+                $params,
+                Argument::any(), // messages or null
+                null
+            )
+            ->willReturn('my-translation');
+
+        $this->translator = $translatorProphecy->reveal();
+        $factory = new MenuFactory();
+        $menu = new MenuItem('test-menu', $factory);
+        $menu->addChild('some-label', array('uri' => '/whatever'))
+            ->setExtra('translation_params', $params);
+
+        $this->assertContains('my-translation', $this->renderMenu($menu));
+    }
+
+    public function testLabelTranslationDomainOverride()
+    {
+        $translatorProphecy = $this->prophesize(
+            'Symfony\Component\Translation\TranslatorInterface'
+        );
+        $translatorProphecy
+            ->trans('some-label', array(), 'my_local_domain', null)
+            ->willReturn('my-translation');
+        $translatorProphecy
+            ->trans('some-other-label', array(), 'my_global_domain', null)
+            ->willReturn('my-other-translation');
+
+        $this->translator = $translatorProphecy->reveal();
+        $factory = new MenuFactory();
+        $menu = new MenuItem('test-menu', $factory);
+        $menu->setExtra('translation_domain', 'my_global_domain');
+        $menu->addChild('some-label', array('uri' => '/whatever'))
+            ->setExtra('translation_domain', 'my_local_domain');
+        $menu->addChild('some-other-label', array('uri' => '/whatever'));
+
+        $html = $this->renderMenu($menu);
+        $this->assertContains('my-translation', $html);
+        $this->assertContains('my-other-translation', $html);
+    }
+}