From 69ce151032bf2f69f68abb21909d172da916c341 Mon Sep 17 00:00:00 2001 From: Jim Schmid Date: Thu, 2 Jun 2016 14:10:16 +0200 Subject: [PATCH 01/18] Enables the usage of custom backend routes. --- .../CustomBackendViewListener.php | 32 +++++++++++++++++ src/Resources/config/listener.yml | 5 +++ src/Resources/contao/classes/BackendUser.php | 6 +++- .../contao/controllers/BackendRoute.php | 34 +++++++++++++++++++ src/Resources/views/Backend/be_page.html.twig | 17 ++++++++++ 5 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 src/EventListener/CustomBackendViewListener.php create mode 100644 src/Resources/contao/controllers/BackendRoute.php create mode 100644 src/Resources/views/Backend/be_page.html.twig diff --git a/src/EventListener/CustomBackendViewListener.php b/src/EventListener/CustomBackendViewListener.php new file mode 100644 index 0000000000..bd10e7d3f6 --- /dev/null +++ b/src/EventListener/CustomBackendViewListener.php @@ -0,0 +1,32 @@ +getRequest(); + + $scope = $request->attributes->get('_scope'); + $isCustomBackendView = $request->attributes->get('_custom_backend_view'); + + if ('backend' !== $scope) { + return; + } + + if (!$isCustomBackendView) { + return; + } + + $backendRoute = new BackendRoute(); + $backendTemplate = $backendRoute->getBaseTemplate(); + + $backendTemplate->main = $event->getResponse()->getContent(); + + $event->setResponse($backendRoute->run()); + } +} \ No newline at end of file diff --git a/src/Resources/config/listener.yml b/src/Resources/config/listener.yml index fc31733cdc..c7e8070cc7 100644 --- a/src/Resources/config/listener.yml +++ b/src/Resources/config/listener.yml @@ -149,3 +149,8 @@ services: tags: - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest } - { name: kernel.event_listener, event: kernel.response, method: onKernelResponse } + + contao.listener.custom_backend_view: + class: Contao\CoreBundle\EventListener\CustomBackendViewListener + tags: + - { name: kernel.event_listener, event: kernel.response, method: onKernelResponse } \ No newline at end of file diff --git a/src/Resources/contao/classes/BackendUser.php b/src/Resources/contao/classes/BackendUser.php index 7ff5cae167..5435f90194 100644 --- a/src/Resources/contao/classes/BackendUser.php +++ b/src/Resources/contao/classes/BackendUser.php @@ -13,6 +13,7 @@ use Contao\CoreBundle\Exception\RedirectResponseException; use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBagInterface; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; +use Symfony\Component\Routing\RouterInterface; /** @@ -459,6 +460,9 @@ public function navigation($blnShowAll=false) /** @var AttributeBagInterface $objSessionBag */ $objSessionBag = \System::getContainer()->get('session')->getBag('contao_backend'); + /** @var RouterInterface $router */ + $router = \System::getContainer()->get('router'); + $arrModules = array(); $session = $objSessionBag->all(); @@ -497,7 +501,7 @@ public function navigation($blnShowAll=false) $arrModules[$strGroupName]['modules'][$strModuleName]['title'] = \StringUtil::specialchars($GLOBALS['TL_LANG']['MOD'][$strModuleName][1]); $arrModules[$strGroupName]['modules'][$strModuleName]['label'] = (($label = is_array($GLOBALS['TL_LANG']['MOD'][$strModuleName]) ? $GLOBALS['TL_LANG']['MOD'][$strModuleName][0] : $GLOBALS['TL_LANG']['MOD'][$strModuleName]) != false) ? $label : $strModuleName; $arrModules[$strGroupName]['modules'][$strModuleName]['class'] = 'navigation ' . $strModuleName; - $arrModules[$strGroupName]['modules'][$strModuleName]['href'] = TL_SCRIPT . '?do=' . $strModuleName . '&ref=' . TL_REFERER_ID; + $arrModules[$strGroupName]['modules'][$strModuleName]['href'] = $router->generate('contao_backend', ['do' => $strModuleName, 'ref' => TL_REFERER_ID]); // Mark the active module and its group if (\Input::get('do') == $strModuleName) diff --git a/src/Resources/contao/controllers/BackendRoute.php b/src/Resources/contao/controllers/BackendRoute.php new file mode 100644 index 0000000000..6e5c352ed7 --- /dev/null +++ b/src/Resources/contao/controllers/BackendRoute.php @@ -0,0 +1,34 @@ +Template = new \BackendTemplate('be_main'); + } + + public function run() + { + $packages = $this->getContainer()->getParameter('kernel.packages'); + + $this->Template->version = $packages['contao/core-bundle']; + + // Ajax request + if ($_POST && \Environment::get('isAjaxRequest')) + { + $this->objAjax = new \Ajax(\Input::post('action')); + $this->objAjax->executePreActions(); + } + + return $this->output(); + } + + public function getBaseTemplate() + { + return $this->Template; + } +} \ No newline at end of file diff --git a/src/Resources/views/Backend/be_page.html.twig b/src/Resources/views/Backend/be_page.html.twig new file mode 100644 index 0000000000..26f1917d85 --- /dev/null +++ b/src/Resources/views/Backend/be_page.html.twig @@ -0,0 +1,17 @@ +{% set _panel = block('panel') %} +{% set _errors = block('errors') %} + +{% if _panel is not empty %} +
+ {{ _panel | raw }} +
+{% endif %} + +{% if _errors is not empty %} +

{{ _errors | raw }}

+{% endif %} + +
+ {% block content %} + {% endblock %} +
\ No newline at end of file From 5fea667a347c0646920e76d1384705ffb418028d Mon Sep 17 00:00:00 2001 From: Jim Schmid Date: Thu, 2 Jun 2016 14:15:44 +0200 Subject: [PATCH 02/18] CS Fixes. (Newlines) --- src/EventListener/CustomBackendViewListener.php | 2 +- src/Resources/config/listener.yml | 2 +- src/Resources/contao/controllers/BackendRoute.php | 2 +- src/Resources/views/Backend/be_page.html.twig | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/EventListener/CustomBackendViewListener.php b/src/EventListener/CustomBackendViewListener.php index bd10e7d3f6..c652d3f1fe 100644 --- a/src/EventListener/CustomBackendViewListener.php +++ b/src/EventListener/CustomBackendViewListener.php @@ -29,4 +29,4 @@ public function onKernelResponse(FilterResponseEvent $event) $event->setResponse($backendRoute->run()); } -} \ No newline at end of file +} diff --git a/src/Resources/config/listener.yml b/src/Resources/config/listener.yml index c7e8070cc7..1fd12b0bf2 100644 --- a/src/Resources/config/listener.yml +++ b/src/Resources/config/listener.yml @@ -153,4 +153,4 @@ services: contao.listener.custom_backend_view: class: Contao\CoreBundle\EventListener\CustomBackendViewListener tags: - - { name: kernel.event_listener, event: kernel.response, method: onKernelResponse } \ No newline at end of file + - { name: kernel.event_listener, event: kernel.response, method: onKernelResponse } diff --git a/src/Resources/contao/controllers/BackendRoute.php b/src/Resources/contao/controllers/BackendRoute.php index 6e5c352ed7..1d8e36a5c8 100644 --- a/src/Resources/contao/controllers/BackendRoute.php +++ b/src/Resources/contao/controllers/BackendRoute.php @@ -31,4 +31,4 @@ public function getBaseTemplate() { return $this->Template; } -} \ No newline at end of file +} diff --git a/src/Resources/views/Backend/be_page.html.twig b/src/Resources/views/Backend/be_page.html.twig index 26f1917d85..4969987a70 100644 --- a/src/Resources/views/Backend/be_page.html.twig +++ b/src/Resources/views/Backend/be_page.html.twig @@ -14,4 +14,4 @@
{% block content %} {% endblock %} -
\ No newline at end of file + From 0e861939d80fcb047a5dc4fd521d555d41fcb602 Mon Sep 17 00:00:00 2001 From: Jim Schmid Date: Mon, 23 Jan 2017 13:48:47 +0100 Subject: [PATCH 03/18] Refactored custom backend view implementations. This implementation gets rid of the route attribute 'custom_backend_view = true'. It introduces a new twig function to wrap specific content blocks with the be_main template of the Contao backend. This way is more intuitive and a less explicit approach. --- .../CustomBackendViewListener.php | 32 ------------ src/Resources/config/listener.yml | 5 -- src/Resources/config/services.yml | 8 +++ src/Resources/views/Backend/be_page.html.twig | 24 +++------ .../Extension/ContaoBaseTemplateExtension.php | 49 +++++++++++++++++++ 5 files changed, 65 insertions(+), 53 deletions(-) delete mode 100644 src/EventListener/CustomBackendViewListener.php create mode 100644 src/Twig/Extension/ContaoBaseTemplateExtension.php diff --git a/src/EventListener/CustomBackendViewListener.php b/src/EventListener/CustomBackendViewListener.php deleted file mode 100644 index c652d3f1fe..0000000000 --- a/src/EventListener/CustomBackendViewListener.php +++ /dev/null @@ -1,32 +0,0 @@ -getRequest(); - - $scope = $request->attributes->get('_scope'); - $isCustomBackendView = $request->attributes->get('_custom_backend_view'); - - if ('backend' !== $scope) { - return; - } - - if (!$isCustomBackendView) { - return; - } - - $backendRoute = new BackendRoute(); - $backendTemplate = $backendRoute->getBaseTemplate(); - - $backendTemplate->main = $event->getResponse()->getContent(); - - $event->setResponse($backendRoute->run()); - } -} diff --git a/src/Resources/config/listener.yml b/src/Resources/config/listener.yml index 1fd12b0bf2..fc31733cdc 100644 --- a/src/Resources/config/listener.yml +++ b/src/Resources/config/listener.yml @@ -149,8 +149,3 @@ services: tags: - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest } - { name: kernel.event_listener, event: kernel.response, method: onKernelResponse } - - contao.listener.custom_backend_view: - class: Contao\CoreBundle\EventListener\CustomBackendViewListener - tags: - - { name: kernel.event_listener, event: kernel.response, method: onKernelResponse } diff --git a/src/Resources/config/services.yml b/src/Resources/config/services.yml index f734a1a95d..7ed5b9f487 100644 --- a/src/Resources/config/services.yml +++ b/src/Resources/config/services.yml @@ -202,3 +202,11 @@ services: - "_contao_fe_attributes" calls: - ["setName", ["contao_frontend"]] + + contao.twig.base_template_wrapper: + class: Contao\CoreBundle\Twig\Extension\ContaoBaseTemplateExtension + arguments: + - "@request_stack" + public: false + tags: + - { name: twig.extension } diff --git a/src/Resources/views/Backend/be_page.html.twig b/src/Resources/views/Backend/be_page.html.twig index 4969987a70..7d97f12b3a 100644 --- a/src/Resources/views/Backend/be_page.html.twig +++ b/src/Resources/views/Backend/be_page.html.twig @@ -1,17 +1,9 @@ -{% set _panel = block('panel') %} -{% set _errors = block('errors') %} +{% set _main = block('main') %} +{% set _headline = block('headline') %} +{% set _error = block('error') %} -{% if _panel is not empty %} -
- {{ _panel | raw }} -
-{% endif %} - -{% if _errors is not empty %} -

{{ _errors | raw }}

-{% endif %} - -
- {% block content %} - {% endblock %} -
+{{ contao_base_template_wrapper({ + main: _main, + error: _error, + headline: _headline +}) | raw }} diff --git a/src/Twig/Extension/ContaoBaseTemplateExtension.php b/src/Twig/Extension/ContaoBaseTemplateExtension.php new file mode 100644 index 0000000000..e133b21d96 --- /dev/null +++ b/src/Twig/Extension/ContaoBaseTemplateExtension.php @@ -0,0 +1,49 @@ +requestStack = $requestStack; + } + + public function getFunctions() + { + return [ + new \Twig_SimpleFunction('contao_base_template_wrapper', [$this, 'wrapWithBaseTemplate']) + ]; + } + + public function wrapWithBaseTemplate(array $blocks = []) + { + $scope = $this->requestStack->getCurrentRequest()->attributes->get('_scope'); + + if ('backend' !== $scope) { + return ''; + } + + $backendRoute = new BackendRoute(); + $backendTemplate = $backendRoute->getBaseTemplate(); + + foreach ($blocks as $key => $content) { + $backendTemplate->{$key} = $content; + } + + $response = $backendRoute->run(); + + return $response->getContent(); + } + + public function getName() + { + return 'base_template_wrapper'; + } + +} \ No newline at end of file From c793c88a82270368291326617f04112afffbd57f Mon Sep 17 00:00:00 2001 From: Jim Schmid Date: Mon, 23 Jan 2017 13:58:20 +0100 Subject: [PATCH 04/18] Renamed twig function to 'surround' content with the Contao base template. --- src/Resources/views/Backend/be_page.html.twig | 2 +- src/Twig/Extension/ContaoBaseTemplateExtension.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Resources/views/Backend/be_page.html.twig b/src/Resources/views/Backend/be_page.html.twig index 7d97f12b3a..e89fecd084 100644 --- a/src/Resources/views/Backend/be_page.html.twig +++ b/src/Resources/views/Backend/be_page.html.twig @@ -2,7 +2,7 @@ {% set _headline = block('headline') %} {% set _error = block('error') %} -{{ contao_base_template_wrapper({ +{{ contao_base_template({ main: _main, error: _error, headline: _headline diff --git a/src/Twig/Extension/ContaoBaseTemplateExtension.php b/src/Twig/Extension/ContaoBaseTemplateExtension.php index e133b21d96..691ffc7002 100644 --- a/src/Twig/Extension/ContaoBaseTemplateExtension.php +++ b/src/Twig/Extension/ContaoBaseTemplateExtension.php @@ -17,11 +17,11 @@ public function __construct(RequestStack $requestStack) public function getFunctions() { return [ - new \Twig_SimpleFunction('contao_base_template_wrapper', [$this, 'wrapWithBaseTemplate']) + new \Twig_SimpleFunction('contao_base_template', [$this, 'contaoBaseTemplate']) ]; } - public function wrapWithBaseTemplate(array $blocks = []) + public function contaoBaseTemplate(array $blocks = []) { $scope = $this->requestStack->getCurrentRequest()->attributes->get('_scope'); @@ -43,7 +43,7 @@ public function wrapWithBaseTemplate(array $blocks = []) public function getName() { - return 'base_template_wrapper'; + return 'contao_base_template'; } } \ No newline at end of file From f04644e5cb13909cabb3d4c99c91999e38df2670 Mon Sep 17 00:00:00 2001 From: Jim Schmid Date: Mon, 23 Jan 2017 15:09:31 +0100 Subject: [PATCH 05/18] Tested contao backend template twig extension. --- src/Resources/config/services.yml | 3 +- .../Extension/ContaoBaseTemplateExtension.php | 10 +++- .../ContaoBaseTemplateExtensionTest.php | 57 +++++++++++++++++++ 3 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 tests/Twig/Extension/ContaoBaseTemplateExtensionTest.php diff --git a/src/Resources/config/services.yml b/src/Resources/config/services.yml index 7ed5b9f487..e82f6117f6 100644 --- a/src/Resources/config/services.yml +++ b/src/Resources/config/services.yml @@ -206,7 +206,8 @@ services: contao.twig.base_template_wrapper: class: Contao\CoreBundle\Twig\Extension\ContaoBaseTemplateExtension arguments: - - "@request_stack" + - "@request_stack", + - "@contao.framework" public: false tags: - { name: twig.extension } diff --git a/src/Twig/Extension/ContaoBaseTemplateExtension.php b/src/Twig/Extension/ContaoBaseTemplateExtension.php index 691ffc7002..6f30ddc6dc 100644 --- a/src/Twig/Extension/ContaoBaseTemplateExtension.php +++ b/src/Twig/Extension/ContaoBaseTemplateExtension.php @@ -3,15 +3,18 @@ namespace Contao\CoreBundle\Twig\Extension; use Contao\BackendRoute; +use Contao\CoreBundle\Framework\ContaoFrameworkInterface; use Symfony\Component\HttpFoundation\RequestStack; class ContaoBaseTemplateExtension extends \Twig_Extension { - protected $requestStack; + private $requestStack; + private $contaoFramework; - public function __construct(RequestStack $requestStack) + public function __construct(RequestStack $requestStack, ContaoFrameworkInterface $contaoFramework) { $this->requestStack = $requestStack; + $this->contaoFramework = $contaoFramework; } public function getFunctions() @@ -29,7 +32,8 @@ public function contaoBaseTemplate(array $blocks = []) return ''; } - $backendRoute = new BackendRoute(); + /** @var BackendRoute $backendRoute */ + $backendRoute = $this->contaoFramework->createInstance(BackendRoute::class); $backendTemplate = $backendRoute->getBaseTemplate(); foreach ($blocks as $key => $content) { diff --git a/tests/Twig/Extension/ContaoBaseTemplateExtensionTest.php b/tests/Twig/Extension/ContaoBaseTemplateExtensionTest.php new file mode 100644 index 0000000000..2360146407 --- /dev/null +++ b/tests/Twig/Extension/ContaoBaseTemplateExtensionTest.php @@ -0,0 +1,57 @@ +getMockBuilder(BackendRoute::class) + ->setMethods(['getBaseTemplate', 'run']) + ->disableOriginalConstructor() + ->getMock() + ; + + $template = new \stdClass(); + + $backendRoute + ->expects($this->once()) + ->method('getBaseTemplate') + ->willReturn($template) + ; + + $backendRoute + ->expects($this->once()) + ->method('run') + ->willReturn(new Response()) + ; + + $request = new Request(); + $request->attributes->set('_scope', 'backend'); + + $requestStack = new RequestStack(); + $requestStack->push($request); + + $contaoFramework = $this->mockContaoFramework(null, null, [], [ + BackendRoute::class => $backendRoute + ]); + + $extension = new ContaoBaseTemplateExtension($requestStack, $contaoFramework); + $extension->contaoBaseTemplate([ + 'a' => 'a', + 'b' => 'b', + 'c' => 'c' + ]); + + $this->assertSame('a', $template->a); + $this->assertSame('b', $template->b); + $this->assertSame('c', $template->c); + } +} \ No newline at end of file From dcb9fdb7c912ecfb32d5dca883874fec726ce727 Mon Sep 17 00:00:00 2001 From: Jim Schmid Date: Mon, 23 Jan 2017 15:12:23 +0100 Subject: [PATCH 06/18] Test if backend template only returns something if _scope is backend. --- .../Extension/ContaoBaseTemplateExtensionTest.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/Twig/Extension/ContaoBaseTemplateExtensionTest.php b/tests/Twig/Extension/ContaoBaseTemplateExtensionTest.php index 2360146407..2cc1a6e861 100644 --- a/tests/Twig/Extension/ContaoBaseTemplateExtensionTest.php +++ b/tests/Twig/Extension/ContaoBaseTemplateExtensionTest.php @@ -11,6 +11,20 @@ class ContaoBaseTemplateExtensionTest extends TestCase { + public function testContaoBaseTemplateScopeRestriction() + { + $request = new Request(); + $request->attributes->set('_scope', 'frontend'); + + $requestStack = new RequestStack(); + $requestStack->push($request); + + $contaoFramework = $this->mockContaoFramework(null, null, [], []); + + $extension = new ContaoBaseTemplateExtension($requestStack, $contaoFramework); + $this->assertEmpty($extension->contaoBaseTemplate()); + } + public function testContaoBaseTemplate() { $backendRoute = $this->getMockBuilder(BackendRoute::class) From 921dedbd5fc42e56ef9ca9b058223aaab3a0a67f Mon Sep 17 00:00:00 2001 From: Jim Schmid Date: Mon, 23 Jan 2017 15:29:20 +0100 Subject: [PATCH 07/18] Fixed a bug in the service configuration. --- src/Resources/config/services.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Resources/config/services.yml b/src/Resources/config/services.yml index e82f6117f6..f3710e8e73 100644 --- a/src/Resources/config/services.yml +++ b/src/Resources/config/services.yml @@ -206,8 +206,9 @@ services: contao.twig.base_template_wrapper: class: Contao\CoreBundle\Twig\Extension\ContaoBaseTemplateExtension arguments: - - "@request_stack", + - "@request_stack" - "@contao.framework" + public: false tags: - { name: twig.extension } From ba7d4a5725cd8d9b16432051d30a2e2c60817247 Mon Sep 17 00:00:00 2001 From: Jim Schmid Date: Mon, 23 Jan 2017 18:19:16 +0100 Subject: [PATCH 08/18] Fixed toggleNavigation by setting an explicit url. --- src/Resources/contao/classes/BackendUser.php | 2 +- src/Resources/public/core.js | 5 +++-- src/Resources/public/mootao.js | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Resources/contao/classes/BackendUser.php b/src/Resources/contao/classes/BackendUser.php index 5435f90194..0c699d0404 100644 --- a/src/Resources/contao/classes/BackendUser.php +++ b/src/Resources/contao/classes/BackendUser.php @@ -481,7 +481,7 @@ public function navigation($blnShowAll=false) $arrModules[$strGroupName]['class'] = ' node-expanded'; $arrModules[$strGroupName]['title'] = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['collapseNode']); $arrModules[$strGroupName]['label'] = (($label = is_array($GLOBALS['TL_LANG']['MOD'][$strGroupName]) ? $GLOBALS['TL_LANG']['MOD'][$strGroupName][0] : $GLOBALS['TL_LANG']['MOD'][$strGroupName]) != false) ? $label : $strGroupName; - $arrModules[$strGroupName]['href'] = \Controller::addToUrl('mtg=' . $strGroupName); + $arrModules[$strGroupName]['href'] = $router->generate('contao_backend', ['do' => \Input::get('do'), 'mtg' => $strGroupName]); // Do not show the modules if the group is closed if (!$blnShowAll && isset($session['backend_modules'][$strGroupName]) && $session['backend_modules'][$strGroupName] < 1) diff --git a/src/Resources/public/core.js b/src/Resources/public/core.js index 33f374d7be..97383dc3f0 100644 --- a/src/Resources/public/core.js +++ b/src/Resources/public/core.js @@ -39,17 +39,18 @@ var AjaxRequest = item.setStyle('display', null); parent.removeClass('node-collapsed').addClass('node-expanded'); $(el).store('tip:title', Contao.lang.collapse); - new Request.Contao().post({'action':'toggleNavigation', 'id':id, 'state':1, 'REQUEST_TOKEN':Contao.request_token}); + new Request.Contao({ url: el.href }).post({'action':'toggleNavigation', 'id':id, 'state':1, 'REQUEST_TOKEN':Contao.request_token}); } else { item.setStyle('display', 'none'); parent.removeClass('node-expanded').addClass('node-collapsed'); $(el).store('tip:title', Contao.lang.expand); - new Request.Contao().post({'action':'toggleNavigation', 'id':id, 'state':0, 'REQUEST_TOKEN':Contao.request_token}); + new Request.Contao({ url: el.href }).post({'action':'toggleNavigation', 'id':id, 'state':0, 'REQUEST_TOKEN':Contao.request_token}); } return false; } new Request.Contao({ + url: el.href, evalScripts: true, onRequest: AjaxRequest.displayBox(Contao.lang.loading + ' …'), onSuccess: function(txt) { diff --git a/src/Resources/public/mootao.js b/src/Resources/public/mootao.js index b7053db7d9..8e7aabc3df 100644 --- a/src/Resources/public/mootao.js +++ b/src/Resources/public/mootao.js @@ -36,7 +36,7 @@ Request.Contao = new Class( }, initialize: function(options) { - if (options) { + if (options && !options.url) { // Try to replace the URL with the form action try { this.options.url = options.field.getParent('form').getAttribute('action'); From a556133ddfd534552693b07aec2dbfa9963d7d94 Mon Sep 17 00:00:00 2001 From: Jim Schmid Date: Mon, 23 Jan 2017 18:52:30 +0100 Subject: [PATCH 09/18] Use a different toggleNavigationUrl than the href, as it only works if it lacks the mtg parameter. --- src/Resources/contao/classes/BackendUser.php | 3 ++- src/Resources/contao/templates/backend/be_main.html5 | 2 +- src/Resources/public/core.js | 8 ++++---- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Resources/contao/classes/BackendUser.php b/src/Resources/contao/classes/BackendUser.php index 0c699d0404..f807e6c8d0 100644 --- a/src/Resources/contao/classes/BackendUser.php +++ b/src/Resources/contao/classes/BackendUser.php @@ -481,7 +481,8 @@ public function navigation($blnShowAll=false) $arrModules[$strGroupName]['class'] = ' node-expanded'; $arrModules[$strGroupName]['title'] = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['collapseNode']); $arrModules[$strGroupName]['label'] = (($label = is_array($GLOBALS['TL_LANG']['MOD'][$strGroupName]) ? $GLOBALS['TL_LANG']['MOD'][$strGroupName][0] : $GLOBALS['TL_LANG']['MOD'][$strGroupName]) != false) ? $label : $strGroupName; - $arrModules[$strGroupName]['href'] = $router->generate('contao_backend', ['do' => \Input::get('do'), 'mtg' => $strGroupName]); + $arrModules[$strGroupName]['href'] = $router->generate('contao_backend', ['do' => \Input::get('do'), 'mtg' => $strGroupName, 'ref' => TL_REFERER_ID]); + $arrModules[$strGroupName]['toggleNavigationUrl'] = $router->generate('contao_backend'); // Do not show the modules if the group is closed if (!$blnShowAll && isset($session['backend_modules'][$strGroupName]) && $session['backend_modules'][$strGroupName] < 1) diff --git a/src/Resources/contao/templates/backend/be_main.html5 b/src/Resources/contao/templates/backend/be_main.html5 index 96e2d69e5c..75f1013b69 100644 --- a/src/Resources/contao/templates/backend/be_main.html5 +++ b/src/Resources/contao/templates/backend/be_main.html5 @@ -57,7 +57,7 @@
    modules as $strGroup=>$arrModules): ?> -
  • +
    • diff --git a/src/Resources/public/core.js b/src/Resources/public/core.js index 97383dc3f0..ee2b5325de 100644 --- a/src/Resources/public/core.js +++ b/src/Resources/public/core.js @@ -28,7 +28,7 @@ var AjaxRequest = * * @returns {boolean} */ - toggleNavigation: function(el, id) { + toggleNavigation: function(el, id, url) { el.blur(); var item = $(id), @@ -39,18 +39,18 @@ var AjaxRequest = item.setStyle('display', null); parent.removeClass('node-collapsed').addClass('node-expanded'); $(el).store('tip:title', Contao.lang.collapse); - new Request.Contao({ url: el.href }).post({'action':'toggleNavigation', 'id':id, 'state':1, 'REQUEST_TOKEN':Contao.request_token}); + new Request.Contao({ url: url }).post({'action':'toggleNavigation', 'id':id, 'state':1, 'REQUEST_TOKEN':Contao.request_token}); } else { item.setStyle('display', 'none'); parent.removeClass('node-expanded').addClass('node-collapsed'); $(el).store('tip:title', Contao.lang.expand); - new Request.Contao({ url: el.href }).post({'action':'toggleNavigation', 'id':id, 'state':0, 'REQUEST_TOKEN':Contao.request_token}); + new Request.Contao({ url: url }).post({'action':'toggleNavigation', 'id':id, 'state':0, 'REQUEST_TOKEN':Contao.request_token}); } return false; } new Request.Contao({ - url: el.href, + url: url, evalScripts: true, onRequest: AjaxRequest.displayBox(Contao.lang.loading + ' …'), onSuccess: function(txt) { From 203d710cc11a5e9ee3228e4fed13a302bb4518c0 Mon Sep 17 00:00:00 2001 From: Jim Schmid Date: Tue, 24 Jan 2017 09:42:02 +0100 Subject: [PATCH 10/18] Renamed service contao.twig.base_template_wrapper to contao.twig.base_template_extension. --- src/Resources/config/services.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Resources/config/services.yml b/src/Resources/config/services.yml index f3710e8e73..7bcdd3695a 100644 --- a/src/Resources/config/services.yml +++ b/src/Resources/config/services.yml @@ -203,12 +203,11 @@ services: calls: - ["setName", ["contao_frontend"]] - contao.twig.base_template_wrapper: + contao.twig.base_template_extension: class: Contao\CoreBundle\Twig\Extension\ContaoBaseTemplateExtension + public: false arguments: - "@request_stack" - "@contao.framework" - - public: false tags: - { name: twig.extension } From 20d70b7ef0a861d817ca0649b7052b1fc2e31660 Mon Sep 17 00:00:00 2001 From: Jim Schmid Date: Tue, 24 Jan 2017 09:44:05 +0100 Subject: [PATCH 11/18] CS Fixes. --- src/Twig/Extension/ContaoBaseTemplateExtension.php | 2 +- tests/Twig/Extension/ContaoBaseTemplateExtensionTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Twig/Extension/ContaoBaseTemplateExtension.php b/src/Twig/Extension/ContaoBaseTemplateExtension.php index 6f30ddc6dc..5ede2f8a45 100644 --- a/src/Twig/Extension/ContaoBaseTemplateExtension.php +++ b/src/Twig/Extension/ContaoBaseTemplateExtension.php @@ -50,4 +50,4 @@ public function getName() return 'contao_base_template'; } -} \ No newline at end of file +} diff --git a/tests/Twig/Extension/ContaoBaseTemplateExtensionTest.php b/tests/Twig/Extension/ContaoBaseTemplateExtensionTest.php index 2cc1a6e861..4f1ac336c6 100644 --- a/tests/Twig/Extension/ContaoBaseTemplateExtensionTest.php +++ b/tests/Twig/Extension/ContaoBaseTemplateExtensionTest.php @@ -68,4 +68,4 @@ public function testContaoBaseTemplate() $this->assertSame('b', $template->b); $this->assertSame('c', $template->c); } -} \ No newline at end of file +} From da6b56f0aa05755309ce984f20ee89936e65b5fa Mon Sep 17 00:00:00 2001 From: Leo Feyer Date: Tue, 24 Jan 2017 18:44:54 +0100 Subject: [PATCH 12/18] Change stuff as discussed with @sheeep. --- src/Resources/config/services.yml | 4 +- src/Resources/contao/classes/BackendUser.php | 6 +- .../contao/controllers/BackendCustom.php | 53 ++++++++++++ .../contao/controllers/BackendRoute.php | 34 -------- .../contao/templates/backend/be_main.html5 | 2 +- src/Resources/views/Backend/be_page.html.twig | 12 +-- .../Extension/ContaoBaseTemplateExtension.php | 53 ------------ .../Extension/ContaoTemplateExtension.php | 83 +++++++++++++++++++ ...st.php => ContaoTemplateExtensionTest.php} | 67 ++++++++++----- 9 files changed, 190 insertions(+), 124 deletions(-) create mode 100644 src/Resources/contao/controllers/BackendCustom.php delete mode 100644 src/Resources/contao/controllers/BackendRoute.php delete mode 100644 src/Twig/Extension/ContaoBaseTemplateExtension.php create mode 100644 src/Twig/Extension/ContaoTemplateExtension.php rename tests/Twig/Extension/{ContaoBaseTemplateExtensionTest.php => ContaoTemplateExtensionTest.php} (58%) diff --git a/src/Resources/config/services.yml b/src/Resources/config/services.yml index 7bcdd3695a..a680a3600d 100644 --- a/src/Resources/config/services.yml +++ b/src/Resources/config/services.yml @@ -203,8 +203,8 @@ services: calls: - ["setName", ["contao_frontend"]] - contao.twig.base_template_extension: - class: Contao\CoreBundle\Twig\Extension\ContaoBaseTemplateExtension + contao.twig.template_extension: + class: Contao\CoreBundle\Twig\Extension\ContaoTemplateExtension public: false arguments: - "@request_stack" diff --git a/src/Resources/contao/classes/BackendUser.php b/src/Resources/contao/classes/BackendUser.php index f807e6c8d0..380b2d17b7 100644 --- a/src/Resources/contao/classes/BackendUser.php +++ b/src/Resources/contao/classes/BackendUser.php @@ -481,8 +481,8 @@ public function navigation($blnShowAll=false) $arrModules[$strGroupName]['class'] = ' node-expanded'; $arrModules[$strGroupName]['title'] = \StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['collapseNode']); $arrModules[$strGroupName]['label'] = (($label = is_array($GLOBALS['TL_LANG']['MOD'][$strGroupName]) ? $GLOBALS['TL_LANG']['MOD'][$strGroupName][0] : $GLOBALS['TL_LANG']['MOD'][$strGroupName]) != false) ? $label : $strGroupName; - $arrModules[$strGroupName]['href'] = $router->generate('contao_backend', ['do' => \Input::get('do'), 'mtg' => $strGroupName, 'ref' => TL_REFERER_ID]); - $arrModules[$strGroupName]['toggleNavigationUrl'] = $router->generate('contao_backend'); + $arrModules[$strGroupName]['href'] = $router->generate('contao_backend', array('do'=>\Input::get('do'), 'mtg'=>$strGroupName, 'ref'=>TL_REFERER_ID)); + $arrModules[$strGroupName]['ajaxUrl'] = $router->generate('contao_backend'); // Do not show the modules if the group is closed if (!$blnShowAll && isset($session['backend_modules'][$strGroupName]) && $session['backend_modules'][$strGroupName] < 1) @@ -502,7 +502,7 @@ public function navigation($blnShowAll=false) $arrModules[$strGroupName]['modules'][$strModuleName]['title'] = \StringUtil::specialchars($GLOBALS['TL_LANG']['MOD'][$strModuleName][1]); $arrModules[$strGroupName]['modules'][$strModuleName]['label'] = (($label = is_array($GLOBALS['TL_LANG']['MOD'][$strModuleName]) ? $GLOBALS['TL_LANG']['MOD'][$strModuleName][0] : $GLOBALS['TL_LANG']['MOD'][$strModuleName]) != false) ? $label : $strModuleName; $arrModules[$strGroupName]['modules'][$strModuleName]['class'] = 'navigation ' . $strModuleName; - $arrModules[$strGroupName]['modules'][$strModuleName]['href'] = $router->generate('contao_backend', ['do' => $strModuleName, 'ref' => TL_REFERER_ID]); + $arrModules[$strGroupName]['modules'][$strModuleName]['href'] = $router->generate('contao_backend', array('do'=>$strModuleName, 'ref'=>TL_REFERER_ID)); // Mark the active module and its group if (\Input::get('do') == $strModuleName) diff --git a/src/Resources/contao/controllers/BackendCustom.php b/src/Resources/contao/controllers/BackendCustom.php new file mode 100644 index 0000000000..b0755583c3 --- /dev/null +++ b/src/Resources/contao/controllers/BackendCustom.php @@ -0,0 +1,53 @@ + + */ +class BackendCustom extends BackendMain +{ + + /** + * Return the template object + * + * @return BackendTemplate|object + */ + public function getTemplateObject() + { + return $this->Template; + } + + + /** + * Run the controller and parse the template + * + * @return Response + */ + public function run() + { + $packages = $this->getContainer()->getParameter('kernel.packages'); + + $this->Template = new \BackendTemplate('be_main'); + $this->Template->version = $packages['contao/core-bundle']; + + // Ajax request + if ($_POST && \Environment::get('isAjaxRequest')) + { + $this->objAjax = new \Ajax(\Input::post('action')); + $this->objAjax->executePreActions(); + } + + return $this->output(); + } +} diff --git a/src/Resources/contao/controllers/BackendRoute.php b/src/Resources/contao/controllers/BackendRoute.php deleted file mode 100644 index 1d8e36a5c8..0000000000 --- a/src/Resources/contao/controllers/BackendRoute.php +++ /dev/null @@ -1,34 +0,0 @@ -Template = new \BackendTemplate('be_main'); - } - - public function run() - { - $packages = $this->getContainer()->getParameter('kernel.packages'); - - $this->Template->version = $packages['contao/core-bundle']; - - // Ajax request - if ($_POST && \Environment::get('isAjaxRequest')) - { - $this->objAjax = new \Ajax(\Input::post('action')); - $this->objAjax->executePreActions(); - } - - return $this->output(); - } - - public function getBaseTemplate() - { - return $this->Template; - } -} diff --git a/src/Resources/contao/templates/backend/be_main.html5 b/src/Resources/contao/templates/backend/be_main.html5 index 75f1013b69..e34f3dec3c 100644 --- a/src/Resources/contao/templates/backend/be_main.html5 +++ b/src/Resources/contao/templates/backend/be_main.html5 @@ -57,7 +57,7 @@
        modules as $strGroup=>$arrModules): ?> -
      • +
        • diff --git a/src/Resources/views/Backend/be_page.html.twig b/src/Resources/views/Backend/be_page.html.twig index e89fecd084..b24bbfc3f4 100644 --- a/src/Resources/views/Backend/be_page.html.twig +++ b/src/Resources/views/Backend/be_page.html.twig @@ -1,9 +1,5 @@ -{% set _main = block('main') %} -{% set _headline = block('headline') %} -{% set _error = block('error') %} - -{{ contao_base_template({ - main: _main, - error: _error, - headline: _headline +{{ render_contao_backend_template({ + main: block('main'), + error: block('headline'), + headline: block('error') }) | raw }} diff --git a/src/Twig/Extension/ContaoBaseTemplateExtension.php b/src/Twig/Extension/ContaoBaseTemplateExtension.php deleted file mode 100644 index 5ede2f8a45..0000000000 --- a/src/Twig/Extension/ContaoBaseTemplateExtension.php +++ /dev/null @@ -1,53 +0,0 @@ -requestStack = $requestStack; - $this->contaoFramework = $contaoFramework; - } - - public function getFunctions() - { - return [ - new \Twig_SimpleFunction('contao_base_template', [$this, 'contaoBaseTemplate']) - ]; - } - - public function contaoBaseTemplate(array $blocks = []) - { - $scope = $this->requestStack->getCurrentRequest()->attributes->get('_scope'); - - if ('backend' !== $scope) { - return ''; - } - - /** @var BackendRoute $backendRoute */ - $backendRoute = $this->contaoFramework->createInstance(BackendRoute::class); - $backendTemplate = $backendRoute->getBaseTemplate(); - - foreach ($blocks as $key => $content) { - $backendTemplate->{$key} = $content; - } - - $response = $backendRoute->run(); - - return $response->getContent(); - } - - public function getName() - { - return 'contao_base_template'; - } - -} diff --git a/src/Twig/Extension/ContaoTemplateExtension.php b/src/Twig/Extension/ContaoTemplateExtension.php new file mode 100644 index 0000000000..46cc5d97d4 --- /dev/null +++ b/src/Twig/Extension/ContaoTemplateExtension.php @@ -0,0 +1,83 @@ + + */ +class ContaoTemplateExtension extends \Twig_Extension +{ + /** + * @var RequestStack + */ + private $requestStack; + + /** + * @var ContaoFrameworkInterface + */ + private $contaoFramework; + + /** + * Constructor. + * + * @param RequestStack $requestStack + * @param ContaoFrameworkInterface $contaoFramework + */ + public function __construct(RequestStack $requestStack, ContaoFrameworkInterface $contaoFramework) + { + $this->requestStack = $requestStack; + $this->contaoFramework = $contaoFramework; + } + + /** + * {@inheritdoc} + */ + public function getFunctions() + { + return [ + new \Twig_SimpleFunction('render_contao_backend_template', [$this, 'renderContaoBackendTemplate']) + ]; + } + + /** + * Renders a Contao back end template with the given blocks. + * + * @param array $blocks + * + * @return string + */ + public function renderContaoBackendTemplate(array $blocks = []) + { + $scope = $this->requestStack->getCurrentRequest()->attributes->get('_scope'); + + if ('backend' !== $scope) { + return ''; + } + + /** @var BackendCustom $controller */ + $controller = $this->contaoFramework->createInstance(BackendCustom::class); + $template = $controller->getBaseTemplate(); + + foreach ($blocks as $key => $content) { + $template->{$key} = $content; + } + + $response = $controller->run(); + + return $response->getContent(); + } +} diff --git a/tests/Twig/Extension/ContaoBaseTemplateExtensionTest.php b/tests/Twig/Extension/ContaoTemplateExtensionTest.php similarity index 58% rename from tests/Twig/Extension/ContaoBaseTemplateExtensionTest.php rename to tests/Twig/Extension/ContaoTemplateExtensionTest.php index 4f1ac336c6..adc48fa8d6 100644 --- a/tests/Twig/Extension/ContaoBaseTemplateExtensionTest.php +++ b/tests/Twig/Extension/ContaoTemplateExtensionTest.php @@ -1,35 +1,38 @@ + */ +class ContaoTemplateExtensionTest extends TestCase { - public function testContaoBaseTemplateScopeRestriction() - { - $request = new Request(); - $request->attributes->set('_scope', 'frontend'); - - $requestStack = new RequestStack(); - $requestStack->push($request); - - $contaoFramework = $this->mockContaoFramework(null, null, [], []); - - $extension = new ContaoBaseTemplateExtension($requestStack, $contaoFramework); - $this->assertEmpty($extension->contaoBaseTemplate()); - } - - public function testContaoBaseTemplate() + /** + * Tests the renderContaoBackendTemplate() method. + */ + public function testRenderContaoBackendTemplate() { - $backendRoute = $this->getMockBuilder(BackendRoute::class) - ->setMethods(['getBaseTemplate', 'run']) + $backendRoute = $this + ->getMockBuilder(BackendCustom::class) ->disableOriginalConstructor() + ->setMethods(['getTemplateObject', 'run']) ->getMock() ; @@ -37,7 +40,7 @@ public function testContaoBaseTemplate() $backendRoute ->expects($this->once()) - ->method('getBaseTemplate') + ->method('getTemplateObject') ->willReturn($template) ; @@ -54,11 +57,12 @@ public function testContaoBaseTemplate() $requestStack->push($request); $contaoFramework = $this->mockContaoFramework(null, null, [], [ - BackendRoute::class => $backendRoute + BackendCustom::class => $backendRoute ]); - $extension = new ContaoBaseTemplateExtension($requestStack, $contaoFramework); - $extension->contaoBaseTemplate([ + $extension = new ContaoTemplateExtension($requestStack, $contaoFramework); + + $extension->renderContaoBackendTemplate([ 'a' => 'a', 'b' => 'b', 'c' => 'c' @@ -68,4 +72,21 @@ public function testContaoBaseTemplate() $this->assertSame('b', $template->b); $this->assertSame('c', $template->c); } + + /** + * Tests the scope restriction. + */ + public function testScopeRestriction() + { + $request = new Request(); + $request->attributes->set('_scope', 'frontend'); + + $requestStack = new RequestStack(); + $requestStack->push($request); + + $contaoFramework = $this->mockContaoFramework(null, null, [], []); + $extension = new ContaoTemplateExtension($requestStack, $contaoFramework); + + $this->assertEmpty($extension->renderContaoBackendTemplate()); + } } From bd61ca4aff963ff55c965e0422d9565c40ed3fa6 Mon Sep 17 00:00:00 2001 From: Leo Feyer Date: Tue, 24 Jan 2017 19:06:12 +0100 Subject: [PATCH 13/18] Fix some things. --- src/Resources/contao/controllers/BackendCustom.php | 13 ++++++++++++- src/Resources/public/core.js | 5 +++-- src/Resources/public/core.min.js | 4 ++-- src/Twig/Extension/ContaoTemplateExtension.php | 2 +- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/Resources/contao/controllers/BackendCustom.php b/src/Resources/contao/controllers/BackendCustom.php index b0755583c3..6c9eebb834 100644 --- a/src/Resources/contao/controllers/BackendCustom.php +++ b/src/Resources/contao/controllers/BackendCustom.php @@ -18,6 +18,18 @@ class BackendCustom extends BackendMain { + /** + * Constructor. + */ + public function __construct() + { + parent::__construct(); + + // Initialize the template in the constructor so it is available in the getTemplateObject() method + $this->Template = new \BackendTemplate('be_main'); + } + + /** * Return the template object * @@ -38,7 +50,6 @@ public function run() { $packages = $this->getContainer()->getParameter('kernel.packages'); - $this->Template = new \BackendTemplate('be_main'); $this->Template->version = $packages['contao/core-bundle']; // Ajax request diff --git a/src/Resources/public/core.js b/src/Resources/public/core.js index ee2b5325de..4cdba8c9c9 100644 --- a/src/Resources/public/core.js +++ b/src/Resources/public/core.js @@ -23,8 +23,9 @@ var AjaxRequest = /** * Toggle the navigation menu * - * @param {object} el The DOM element - * @param {string} id The ID of the menu item + * @param {object} el The DOM element + * @param {string} id The ID of the menu item + * @param {string} url The Ajax URL * * @returns {boolean} */ diff --git a/src/Resources/public/core.min.js b/src/Resources/public/core.min.js index 3afb882b4d..78a78a969c 100644 --- a/src/Resources/public/core.min.js +++ b/src/Resources/public/core.min.js @@ -1,2 +1,2 @@ -var AjaxRequest={themePath:Contao.script_url+"system/themes/"+Contao.theme+"/",toggleNavigation:function(e,t){e.blur();var n=$(t),a=$(e).getParent("li");return n?(a.hasClass("node-collapsed")?(n.setStyle("display",null),a.removeClass("node-collapsed").addClass("node-expanded"),$(e).store("tip:title",Contao.lang.collapse),(new Request.Contao).post({action:"toggleNavigation",id:t,state:1,REQUEST_TOKEN:Contao.request_token})):(n.setStyle("display","none"),a.removeClass("node-expanded").addClass("node-collapsed"),$(e).store("tip:title",Contao.lang.expand),(new Request.Contao).post({action:"toggleNavigation",id:t,state:0,REQUEST_TOKEN:Contao.request_token})),!1):(new Request.Contao({evalScripts:!0,onRequest:AjaxRequest.displayBox(Contao.lang.loading+" …"),onSuccess:function(e){var n=new Element("li",{id:t,class:"tl_parent",html:e}).inject(a,"after");n.getElements("a").each(function(e){e.href=e.href.replace(/&ref=[a-f0-9]+/,"&ref="+Contao.referer_id)}),a.removeClass("node-collapsed").addClass("node-expanded"),AjaxRequest.hideBox(),window.fireEvent("ajax_change")}}).post({action:"loadNavigation",id:t,state:1,REQUEST_TOKEN:Contao.request_token}),!1)},toggleStructure:function(e,t,n,a){e.blur();var o=$(t),i=$(e).getFirst("img");return o?("none"==o.getStyle("display")?(o.setStyle("display",null),i.src=AjaxRequest.themePath+"icons/folMinus.svg",$(e).store("tip:title",Contao.lang.collapse),new Request.Contao({field:e}).post({action:"toggleStructure",id:t,state:1,REQUEST_TOKEN:Contao.request_token})):(o.setStyle("display","none"),i.src=AjaxRequest.themePath+"icons/folPlus.svg",$(e).store("tip:title",Contao.lang.expand),new Request.Contao({field:e}).post({action:"toggleStructure",id:t,state:0,REQUEST_TOKEN:Contao.request_token})),!1):(new Request.Contao({field:e,evalScripts:!0,onRequest:AjaxRequest.displayBox(Contao.lang.loading+" …"),onSuccess:function(o){var l=new Element("li",{id:t,class:"parent",styles:{display:"inline"}});if(new Element("ul",{class:"level_"+n,html:o}).inject(l,"bottom"),5==a)l.inject($(e).getParent("li"),"after");else{for(var s,c=!1,r=$(e).getParent("li");"element"==typeOf(r)&&(s=r.getNext("li"));)if(r=s,r.hasClass("tl_folder")){c=!0;break}c?l.inject(r,"before"):l.inject(r,"after")}l.getElements("a").each(function(e){e.href=e.href.replace(/&ref=[a-f0-9]+/,"&ref="+Contao.referer_id)}),$(e).store("tip:title",Contao.lang.collapse),i.src=AjaxRequest.themePath+"icons/folMinus.svg",window.fireEvent("structure"),AjaxRequest.hideBox(),window.fireEvent("ajax_change")}}).post({action:"loadStructure",id:t,level:n,state:1,REQUEST_TOKEN:Contao.request_token}),!1)},toggleFileManager:function(e,t,n,a){e.blur();var o=$(t),i=$(e).getFirst("img");return o?("none"==o.getStyle("display")?(o.setStyle("display",null),i.src=AjaxRequest.themePath+"icons/folMinus.svg",$(e).store("tip:title",Contao.lang.collapse),new Request.Contao({field:e}).post({action:"toggleFileManager",id:t,state:1,REQUEST_TOKEN:Contao.request_token})):(o.setStyle("display","none"),i.src=AjaxRequest.themePath+"icons/folPlus.svg",$(e).store("tip:title",Contao.lang.expand),new Request.Contao({field:e}).post({action:"toggleFileManager",id:t,state:0,REQUEST_TOKEN:Contao.request_token})),!1):(new Request.Contao({field:e,evalScripts:!0,onRequest:AjaxRequest.displayBox(Contao.lang.loading+" …"),onSuccess:function(n){var o=new Element("li",{id:t,class:"parent",styles:{display:"inline"}});new Element("ul",{class:"level_"+a,html:n}).inject(o,"bottom"),o.inject($(e).getParent("li"),"after"),o.getElements("a").each(function(e){e.href=e.href.replace(/&ref=[a-f0-9]+/,"&ref="+Contao.referer_id)}),$(e).store("tip:title",Contao.lang.collapse),i.src=AjaxRequest.themePath+"icons/folMinus.svg",AjaxRequest.hideBox(),window.fireEvent("ajax_change")}}).post({action:"loadFileManager",id:t,level:a,folder:n,state:1,REQUEST_TOKEN:Contao.request_token}),!1)},togglePagetree:function(e,t,n,a,o){e.blur(),Backend.getScrollOffset();var i=$(t),l=$(e).getFirst("img");return i?("none"==i.getStyle("display")?(i.setStyle("display",null),l.src=AjaxRequest.themePath+"icons/folMinus.svg",$(e).store("tip:title",Contao.lang.collapse),new Request.Contao({field:e}).post({action:"togglePagetree",id:t,state:1,REQUEST_TOKEN:Contao.request_token})):(i.setStyle("display","none"),l.src=AjaxRequest.themePath+"icons/folPlus.svg",$(e).store("tip:title",Contao.lang.expand),new Request.Contao({field:e}).post({action:"togglePagetree",id:t,state:0,REQUEST_TOKEN:Contao.request_token})),!1):(new Request.Contao({field:e,evalScripts:!0,onRequest:AjaxRequest.displayBox(Contao.lang.loading+" …"),onSuccess:function(n){var a=new Element("li",{id:t,class:"parent",styles:{display:"inline"}});new Element("ul",{class:"level_"+o,html:n}).inject(a,"bottom"),a.inject($(e).getParent("li"),"after"),a.getElements("a").each(function(e){e.href=e.href.replace(/&ref=[a-f0-9]+/,"&ref="+Contao.referer_id)}),$(e).store("tip:title",Contao.lang.collapse),l.src=AjaxRequest.themePath+"icons/folMinus.svg",AjaxRequest.hideBox(),window.fireEvent("ajax_change")}}).post({action:"loadPagetree",id:t,level:o,field:n,name:a,state:1,REQUEST_TOKEN:Contao.request_token}),!1)},toggleFiletree:function(e,t,n,a,o,i){e.blur(),Backend.getScrollOffset();var l=$(t),s=$(e).getFirst("img");return l?("none"==l.getStyle("display")?(l.setStyle("display",null),s.src=AjaxRequest.themePath+"icons/folMinus.svg",$(e).store("tip:title",Contao.lang.collapse),new Request.Contao({field:e}).post({action:"toggleFiletree",id:t,state:1,REQUEST_TOKEN:Contao.request_token})):(l.setStyle("display","none"),s.src=AjaxRequest.themePath+"icons/folPlus.svg",$(e).store("tip:title",Contao.lang.expand),new Request.Contao({field:e}).post({action:"toggleFiletree",id:t,state:0,REQUEST_TOKEN:Contao.request_token})),!1):(new Request.Contao({field:e,evalScripts:!0,onRequest:AjaxRequest.displayBox(Contao.lang.loading+" …"),onSuccess:function(n){var a=new Element("li",{id:t,class:"parent",styles:{display:"inline"}});new Element("ul",{class:"level_"+i,html:n}).inject(a,"bottom"),a.inject($(e).getParent("li"),"after"),a.getElements("a").each(function(e){e.href=e.href.replace(/&ref=[a-f0-9]+/,"&ref="+Contao.referer_id)}),$(e).store("tip:title",Contao.lang.collapse),s.src=AjaxRequest.themePath+"icons/folMinus.svg",AjaxRequest.hideBox(),window.fireEvent("ajax_change")}}).post({action:"loadFiletree",id:t,folder:n,level:i,field:a,name:o,state:1,REQUEST_TOKEN:Contao.request_token}),!1)},toggleSubpalette:function(e,t,n){e.blur();var a=$(t);return a?void(e.value?(e.value="",e.checked="",a.setStyle("display","none"),a.getElements("[required]").each(function(e){e.set("required",null).set("data-required","")}),new Request.Contao({field:e}).post({action:"toggleSubpalette",id:t,field:n,state:0,REQUEST_TOKEN:Contao.request_token})):(e.value=1,e.checked="checked",a.setStyle("display",null),a.getElements("[data-required]").each(function(e){e.set("required","").set("data-required",null)}),new Request.Contao({field:e}).post({action:"toggleSubpalette",id:t,field:n,state:1,REQUEST_TOKEN:Contao.request_token}))):void new Request.Contao({field:e,evalScripts:!1,onRequest:AjaxRequest.displayBox(Contao.lang.loading+" …"),onSuccess:function(n,a){var o=new Element("div",{id:t,html:n,styles:{display:"block"}}).inject($(e).getParent("div").getParent("div"),"after");a.javascript&&(document.write=function(e){var t="";e.replace(/