diff --git a/docs/images/locale_switcher.png b/docs/images/locale_switcher.png new file mode 100644 index 00000000..066ff8cf Binary files /dev/null and b/docs/images/locale_switcher.png differ diff --git a/docs/index.rst b/docs/index.rst index 825f2e2d..35fe2b2c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,7 +1,8 @@ Translation Bundle ================== -SonataTranslationBundle allows you to easily translate your models in SonataAdmin in every locales you need on your frontend. +SonataTranslationBundle allows you to easily translate your models in SonataAdmin +in every locales you need on your frontend. This bundle adds a locale switcher block in : @@ -14,6 +15,8 @@ This bundle adds a locale switcher block in : * **ORM** : integrates Doctrine ORM entities with Gedmo extensions * **PHPCR**: integrates Doctrine PHPCR ODM +In addition, it provides a nice global locale switcher for your admin. + .. toctree:: :caption: Reference Guide :name: reference-guide @@ -25,3 +28,4 @@ This bundle adds a locale switcher block in : reference/orm reference/phpcr reference/custom_action + reference/global_locale_switcher diff --git a/docs/reference/global_locale_switcher.rst b/docs/reference/global_locale_switcher.rst new file mode 100644 index 00000000..a2ab9c55 --- /dev/null +++ b/docs/reference/global_locale_switcher.rst @@ -0,0 +1,62 @@ +Global locale switcher +====================== + +``SonataTranslationBundle`` also provides a nice global locale switcher +for your admin. + +Prerequisites +------------- + +Install the following Sonata dependencies: + +* `Sonata Intl Bundle`_ + +Configuration +------------- + +Override standard layout template with the one from the bundle: + +.. code-block:: yaml + + # app/config/packages/sonata_admin.yaml + + sonata_admin: + ... + templates: + layout: '@SonataTranslation/standard_layout.html.twig' + +Configure locale subscriber and user locale subscriber services: + +.. code-block:: yaml + + # app/config/services.yaml + + services: + ... + Sonata\TranslationBundle\EventSubscriber\LocaleSubscriber: + arguments: ['%kernel.default_locale%'] + Sonata\TranslationBundle\EventSubscriber\UserLocaleSubscriber: + arguments: ~ + +Configure route: + +.. code-block:: yaml + + # app/config/routes.yaml + + ... + sonata_translation: + resource: '@SonataTranslationBundle/Resources/config/routes.yaml' + +How it looks +------------ + +You are done and you probably want to know how this looks like in the admin +interface. Well, let's find out by going to /admin + +.. image:: ../images/locale_switcher.png + :align: center + :alt: Sonata Dashboard with locale switcher + :width: 700px + +.. _`Sonata Intl Bundle`: https://sonata-project.org/bundles/intl diff --git a/src/Action/LocaleAction.php b/src/Action/LocaleAction.php new file mode 100644 index 00000000..4b21bc91 --- /dev/null +++ b/src/Action/LocaleAction.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Sonata\TranslationBundle\Action; + +use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\RedirectResponse; + +/** + * Locale action. + * + * @author Jonathan Vautrin + */ +final class LocaleAction +{ + /** + * Switch current locale. + * + * @return RedirectResponse + */ + public function index(Request $request, $locale) + { + $request->getSession()->set('_locale', $locale); + return new RedirectResponse($request->headers->get('referer', '/')); + } +} diff --git a/src/EventSubscriber/LocaleSubscriber.php b/src/EventSubscriber/LocaleSubscriber.php new file mode 100644 index 00000000..a62fc684 --- /dev/null +++ b/src/EventSubscriber/LocaleSubscriber.php @@ -0,0 +1,68 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Sonata\TranslationBundle\EventSubscriber; + +use Symfony\Component\HttpKernel\Event\GetResponseEvent; +use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +/** + * Locale subscriber. + * + * @author Jonathan Vautrin + */ +final class LocaleSubscriber implements EventSubscriberInterface +{ + /** + * @var string + */ + private $defaultLocale; + + /** + * @param string $defaultLocale + */ + public function __construct($defaultLocale = 'en') + { + $this->defaultLocale = $defaultLocale; + } + + /** + * @param GetResponseEvent $event + */ + public function onKernelRequest(GetResponseEvent $event) + { + $request = $event->getRequest(); + if (!$request->hasPreviousSession()) { + return; + } + + // try to see if the locale has been set as a _locale routing parameter + if ($locale = $request->attributes->get('_locale')) { + $request->getSession()->set('_locale', $locale); + return; + } + + // if no explicit locale has been set on this request, use one from the session + $request->setLocale($request->getSession()->get('_locale', $this->defaultLocale)); + } + + /** + * @return array + */ + public static function getSubscribedEvents() + { + return array( + // must be registered before (i.e. with a higher priority than) the default Locale listener + KernelEvents::REQUEST => [['onKernelRequest', 20]], + ); + } +} diff --git a/src/EventSubscriber/UserLocaleSubscriber.php b/src/EventSubscriber/UserLocaleSubscriber.php new file mode 100644 index 00000000..276b4244 --- /dev/null +++ b/src/EventSubscriber/UserLocaleSubscriber.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Sonata\TranslationBundle\EventSubscriber; + +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\HttpFoundation\Session\SessionInterface; +use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; +use Symfony\Component\Security\Http\SecurityEvents; + +/** + * Stores the locale of the user in the session after the + * login. This can be used by the LocaleSubscriber afterwards. + * + * @author Jonathan Vautrin + */ +final class UserLocaleSubscriber implements EventSubscriberInterface +{ + /** + * @var SessionInterface + */ + private $session; + + /** + * @param SessionInterface $session + */ + public function __construct(SessionInterface $session) + { + $this->session = $session; + } + + /** + * @param InteractiveLoginEvent $event + */ + public function onInteractiveLogin(InteractiveLoginEvent $event) + { + $user = $event->getAuthenticationToken()->getUser(); + + if (null !== $user->getLocale()) { + $this->session->set('_locale', $user->getLocale()); + } + } + + /** + * @return array + */ + public static function getSubscribedEvents() + { + return [ + SecurityEvents::INTERACTIVE_LOGIN => 'onInteractiveLogin', + ]; + } +} diff --git a/src/Resources/config/routes.yaml b/src/Resources/config/routes.yaml new file mode 100644 index 00000000..a4497dc4 --- /dev/null +++ b/src/Resources/config/routes.yaml @@ -0,0 +1,4 @@ +sonata.translation.locale: + path: /locale/{locale} + defaults: + _controller: Sonata\TranslationBundle\Action\LocaleAction::index diff --git a/src/Resources/translations/SonataAdminBundle.de.xlf b/src/Resources/translations/SonataAdminBundle.de.xlf new file mode 100644 index 00000000..668f2860 --- /dev/null +++ b/src/Resources/translations/SonataAdminBundle.de.xlf @@ -0,0 +1,11 @@ + + + + + + languages_title + Sprachen + + + + diff --git a/src/Resources/translations/SonataAdminBundle.en.xlf b/src/Resources/translations/SonataAdminBundle.en.xlf new file mode 100644 index 00000000..55c45c41 --- /dev/null +++ b/src/Resources/translations/SonataAdminBundle.en.xlf @@ -0,0 +1,11 @@ + + + + + + languages_title + Languages + + + + diff --git a/src/Resources/translations/SonataAdminBundle.es.xlf b/src/Resources/translations/SonataAdminBundle.es.xlf new file mode 100644 index 00000000..148010a4 --- /dev/null +++ b/src/Resources/translations/SonataAdminBundle.es.xlf @@ -0,0 +1,11 @@ + + + + + + languages_title + Idiomas + + + + diff --git a/src/Resources/translations/SonataAdminBundle.fr.xlf b/src/Resources/translations/SonataAdminBundle.fr.xlf new file mode 100644 index 00000000..565358cf --- /dev/null +++ b/src/Resources/translations/SonataAdminBundle.fr.xlf @@ -0,0 +1,11 @@ + + + + + + languages_title + Langues + + + + diff --git a/src/Resources/translations/SonataAdminBundle.hu.xlf b/src/Resources/translations/SonataAdminBundle.hu.xlf new file mode 100644 index 00000000..9ecab2c9 --- /dev/null +++ b/src/Resources/translations/SonataAdminBundle.hu.xlf @@ -0,0 +1,11 @@ + + + + + + languages_title + Nyelvek + + + + diff --git a/src/Resources/translations/SonataAdminBundle.it.xlf b/src/Resources/translations/SonataAdminBundle.it.xlf new file mode 100644 index 00000000..d05d43bc --- /dev/null +++ b/src/Resources/translations/SonataAdminBundle.it.xlf @@ -0,0 +1,11 @@ + + + + + + languages_title + Le lingue + + + + diff --git a/src/Resources/translations/SonataAdminBundle.pl.xlf b/src/Resources/translations/SonataAdminBundle.pl.xlf new file mode 100644 index 00000000..47a2b6cf --- /dev/null +++ b/src/Resources/translations/SonataAdminBundle.pl.xlf @@ -0,0 +1,11 @@ + + + + + + languages_title + Języki + + + + diff --git a/src/Resources/translations/SonataAdminBundle.ru.xlf b/src/Resources/translations/SonataAdminBundle.ru.xlf new file mode 100644 index 00000000..ae317af7 --- /dev/null +++ b/src/Resources/translations/SonataAdminBundle.ru.xlf @@ -0,0 +1,11 @@ + + + + + + languages_title + Языки + + + + diff --git a/src/Resources/views/standard_layout.html.twig b/src/Resources/views/standard_layout.html.twig new file mode 100644 index 00000000..a1bb6b16 --- /dev/null +++ b/src/Resources/views/standard_layout.html.twig @@ -0,0 +1,47 @@ +{# + +This file is part of the Sonata package. + +(c) Thomas Rabaix + +For the full copyright and license information, please view the LICENSE +file that was distributed with this source code. + +#} + +{% extends '@SonataAdmin/standard_layout.html.twig' %} + +{% block sonata_top_nav_menu %} + {{ parent() }} + +{% endblock %}