diff --git a/README.md b/README.md index 08f3540..6b52ff8 100644 --- a/README.md +++ b/README.md @@ -170,6 +170,20 @@ menu: include: '^Book\:[a-zA-Z]+$' ``` +or with array of included targets. + +``` +menu: + + default: + + Books settings: + target: Book:default + include: + - Book:add + - Book:edit +``` + ## Custom templates ``` @@ -184,6 +198,16 @@ menu: items: [] ``` +## Translated titles + +``` +menu: + + default: + + translator: true +``` + ## More menus Lets say that we want base menu and menu just for users in `admin` role. @@ -310,5 +334,9 @@ class BookPresenter extends BasePresenter ## Changelog +* 1.0.1 + + Include option can be array of targets [https://github.com/sakren/nette-menu/issues/1](#1) + + Added support for translatable titles [https://github.com/sakren/nette-menu/issues/2](#2) + * 1.0.0 + First version \ No newline at end of file diff --git a/src/DK/Menu/DI/Extension.php b/src/DK/Menu/DI/Extension.php index bf278ba..7dbb5e4 100644 --- a/src/DK/Menu/DI/Extension.php +++ b/src/DK/Menu/DI/Extension.php @@ -28,6 +28,7 @@ class Extension extends CompilerExtension private $menuDefaults = array( 'controlClass' => 'DK\Menu\UI\Control', 'controlInterface' => 'DK\Menu\UI\IControlFactory', + 'translator' => false, 'template' => array( 'menu' => null, // see constructor 'breadcrumb' => null, @@ -64,7 +65,7 @@ public function __construct() public function loadConfiguration() { - $config = $this->getConfig($this->defaults); + $config = $this->getConfig($this->defaults) ; $builder = $this->getContainerBuilder(); $autowired = count($config) === 1; @@ -76,11 +77,19 @@ public function loadConfiguration() $data['items'] = $this->parseItems($data['items']); - $builder->addDefinition($this->prefix($name)) + $menu = $builder->addDefinition($this->prefix($name)) ->setClass('DK\Menu\Menu') ->setFactory('DK\Menu\DI\Extension::createMenu', array($name, $data['items'])) ->setAutowired($autowired); + if (($translator = $data['translator']) !== false) { + if ($translator === true) { + $translator = '@Nette\Localization\ITranslator'; + } + + $menu->addSetup('setTranslator', array($translator)); + } + $builder->addDefinition($this->prefix($name. 'Control')) ->setClass($data['controlClass'], array('@'. $this->prefix($name))) ->addSetup('setMenuTemplate', array($data['template']['menu'])) diff --git a/src/DK/Menu/Item.php b/src/DK/Menu/Item.php index a207e03..7d48bbc 100644 --- a/src/DK/Menu/Item.php +++ b/src/DK/Menu/Item.php @@ -86,7 +86,7 @@ public function getMenu() /** - * @return \DK\Menu\Item + * @return string */ public function getTitle() { @@ -105,6 +105,20 @@ public function setTitle($title) } + /** + * @return string + */ + public function getTranslatedTitle() + { + $title = $this->getTitle(); + if (($translator = $this->getMenu()->getTranslator()) !== null) { + $title = $translator->translate($title); + } + + return $title; + } + + /** * @return string */ @@ -462,7 +476,13 @@ public function isActive() } if ($this->active === null && $this->hasInclude()) { - if (preg_match('~'. $this->getInclude(). '~', $presenter->getName(). ':'. $presenter->getAction())) { + $include = $this->getInclude(); + $name = $presenter->getName(). ':'. $presenter->getAction(); + + if (is_string($include) && preg_match('~'. $this->getInclude(). '~', $name)) { + $this->active = true; + + } elseif (is_array($include) && in_array($name, $include)) { $this->active = true; } } diff --git a/src/DK/Menu/Menu.php b/src/DK/Menu/Menu.php index 1e28289..5ed7e9a 100644 --- a/src/DK/Menu/Menu.php +++ b/src/DK/Menu/Menu.php @@ -5,6 +5,7 @@ use Nette\Application\Application; use Nette\Application\UI\Presenter; use Nette\Security\User; +use Nette\Localization\ITranslator; /** * @@ -20,6 +21,9 @@ class Menu extends Container /** @var \Nette\Security\User */ private $user; + /** @var \Nette\Localization\ITranslator */ + private $translator; + /** * @param \Nette\Security\User $user @@ -53,6 +57,26 @@ public function init(Application $application) } + /** + * @return \Nette\Localization\ITranslator + */ + public function getTranslator() + { + return $this->translator; + } + + + /** + * @param \Nette\Localization\ITranslator $translator + * @return \DK\Menu\Menu + */ + public function setTranslator(ITranslator $translator) + { + $this->translator = $translator; + return $this; + } + + /** * @return \DK\Menu\Menu */ diff --git a/src/DK/Menu/UI/breadcrumb.latte b/src/DK/Menu/UI/breadcrumb.latte index f3b819d..209e40a 100644 --- a/src/DK/Menu/UI/breadcrumb.latte +++ b/src/DK/Menu/UI/breadcrumb.latte @@ -1,3 +1,3 @@ {foreach $menu->getPath() as $item} - {$item->getTitle()}{sep} / {/sep} + {$item->getTranslatedTitle()}{sep} / {/sep} {/foreach} \ No newline at end of file diff --git a/src/DK/Menu/UI/menu.latte b/src/DK/Menu/UI/menu.latte index 17fb8a6..6954d37 100644 --- a/src/DK/Menu/UI/menu.latte +++ b/src/DK/Menu/UI/menu.latte @@ -4,7 +4,7 @@ \ No newline at end of file diff --git a/tests/DKTests/Menu/Menu.phpt b/tests/DKTests/Menu/Menu.phpt index 26a0e47..e3fa8b0 100644 --- a/tests/DKTests/Menu/Menu.phpt +++ b/tests/DKTests/Menu/Menu.phpt @@ -29,6 +29,7 @@ use Nette\Application\Responses\TextResponse; use Nette\Application\UI\Presenter; use Nette\Security\IAuthenticator; use Nette\Security\Identity; +use Nette\Localization\ITranslator; use DK\Menu\DI\Extension; use DK\Menu\Item; @@ -161,7 +162,7 @@ class MenuTest extends TestCase } - public function testCurrentIncluded() + public function testCurrentIncludedRegexp() { $container = $this->createContainer('menu'); $presenter = $this->createPresenter($container, 'User'); @@ -177,6 +178,34 @@ class MenuTest extends TestCase } + public function testCurrentIncludedArray() + { + $container = $this->createContainer('menu'); + $presenter = $this->createPresenter($container, 'About'); + $request = $this->createRequest('About', 'terms'); + + $presenter->run($request); + + $menu = $presenter->getMenu(); + $current = $menu->getLastCurrentItem(); + + Assert::same('About us', $current->getTitle()); + Assert::same('About:default', $current->getTarget()); + } + + + public function testTranslator() + { + $container = $this->createContainer('translated'); + $menu = $container->getByType('DK\Menu\Menu'); /** @var $menu \DK\Menu\Menu */ + + $item = $menu->getItem('home'); + + Assert::same('menu.homepage', $item->getTitle()); + Assert::same('Homepage', $item->getTranslatedTitle()); + } + + public function testPath() { $container = $this->createContainer('menu'); @@ -318,4 +347,25 @@ class Authenticator implements IAuthenticator } +class Translator implements ITranslator +{ + + + /** + * @param string $message + * @param int|null $count + * @return string + */ + public function translate($message, $count = null) + { + if ($message === 'menu.homepage') { + return 'Homepage'; + } + + return null; + } + +} + + \run(new MenuTest); \ No newline at end of file diff --git a/tests/DKTests/app/config/menu.neon b/tests/DKTests/app/config/menu.neon index c8b3679..dd22b4f 100644 --- a/tests/DKTests/app/config/menu.neon +++ b/tests/DKTests/app/config/menu.neon @@ -46,4 +46,7 @@ menu: about: title: About us - target: About:default \ No newline at end of file + target: About:default + include: + - About:terms + - About:priceList \ No newline at end of file diff --git a/tests/DKTests/app/config/translated.neon b/tests/DKTests/app/config/translated.neon new file mode 100644 index 0000000..bcdb643 --- /dev/null +++ b/tests/DKTests/app/config/translated.neon @@ -0,0 +1,14 @@ +services: + + - DKTests\Menu\Translator + +menu: + + default: + + translator: true + + items: + home: + title: menu.homepage + target: Homepage:default \ No newline at end of file diff --git a/tests/DKTests/app/templates/About/terms.latte b/tests/DKTests/app/templates/About/terms.latte new file mode 100644 index 0000000..3fe203d --- /dev/null +++ b/tests/DKTests/app/templates/About/terms.latte @@ -0,0 +1 @@ +{layout ../@layout.latte} \ No newline at end of file