Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swichable layouts #8191

Draft
wants to merge 1 commit into
base: 4.x
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 28 additions & 7 deletions docs/reference/templates.rst
Original file line number Diff line number Diff line change
Expand Up @@ -94,22 +94,42 @@ There are several other templates that can be customized, enabling you to fine-t
* ``pager_results`` : renders the dropdown that lets you choose the number of
elements per page on list views

Configuring templates
---------------------
Configuring layouts and templates
---------------------------------

The main goal of this template structure is to make it comfortable for you
The main goal of this layout/template structure is to make it comfortable for you
to customize the ones you need. You can extend the ones you want in your own bundle, and
tell ``SonataAdminBundle`` to use your templates instead of the default ones. You can do so
tell ``SonataAdminBundle`` to use your layouts/templates instead of the default ones. You can do so
in several ways.

You can specify your templates in the config file:
You can specify your layouts/templates in the config file:

.. code-block:: yaml

# config/packages/sonata_admin.yaml

sonata_admin:
templates:
use_layouts: false
allow_layouts: [default] # [custom, default] - the first defined layout will be used as default
layouts:
default:
name: 'Sonata Admin - AdminLTE 2'
templates:
layout: '@SonataAdmin/standard_layout.html.twig'
...
button_show: '@SonataAdmin/Button/show_button.html.twig'
form_theme: []
filter_theme: []
custom_layout:
name: 'Sonata Admin - AdminLTE 3'
templates:
layout: '@SonataAdmin/AdminLTE3/standard_layout.html.twig'
...
button_show: '@SonataAdmin/AdminLTE3/Button/show_button.html.twig'
form_theme: []
filter_theme: []

templates: # it is "default" layout
layout: '@SonataAdmin/standard_layout.html.twig'
ajax: '@SonataAdmin/ajax_layout.html.twig'
list: '@SonataAdmin/CRUD/list.html.twig'
Expand Down Expand Up @@ -167,12 +187,13 @@ can specify the templates to use in the ``Admin`` service definition:
class: App\Admin\PostAdmin
calls:
- [setTemplate, ['edit', 'PostAdmin/edit.html.twig']]
- [setTemplate, ['edit', 'PostAdmin/edit.html.twig', 'custom_layout']]
tags:
- { name: sonata.admin, model_class: App\Entity\Post, manager_type: orm, group: 'Content', label: 'Post' }

.. note::

A ``setTemplates(array $templates)`` (notice the plural) method also
A ``setTemplates(array $templates, string $layout = 'default')`` (notice the plural) method also
exists, that allows you to set multiple templates at once.

Changes made using the ``setTemplate()`` and ``setTemplates()`` methods
Expand Down
38 changes: 24 additions & 14 deletions src/Controller/CRUDController.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
use Sonata\AdminBundle\Form\FormErrorIteratorToConstraintViolationList;
use Sonata\AdminBundle\Model\AuditManagerInterface;
use Sonata\AdminBundle\Request\AdminFetcherInterface;
use Sonata\AdminBundle\Templating\LayoutStorage\CookieLayoutStorage;
use Sonata\AdminBundle\Templating\LayoutStorage\LayoutStorageInterface;
use Sonata\AdminBundle\Templating\TemplateRegistryInterface;
use Sonata\AdminBundle\Util\AdminAclUserManagerInterface;
use Sonata\AdminBundle\Util\AdminObjectAclData;
Expand Down Expand Up @@ -94,6 +96,7 @@
'sonata.exporter.exporter' => '?'.ExporterInterface::class,
'sonata.admin.admin_exporter' => '?'.AdminExporter::class,
'sonata.admin.security.acl_user_manager' => '?'.AdminAclUserManagerInterface::class,
'sonata.admin.layout_cookie_storage' => LayoutStorageInterface::class,

'controller_resolver' => 'controller_resolver',
'http_kernel' => HttpKernelInterface::class,
Expand Down Expand Up @@ -127,7 +130,7 @@
// set the theme for the current Admin Form
$this->setFormTheme($formView, $this->admin->getFilterTheme());

$template = $this->templateRegistry->getTemplate('list');
$template = $this->getTemplate('list');

if ($this->container->has('sonata.admin.admin_exporter')) {
$exporter = $this->container->get('sonata.admin.admin_exporter');
Expand Down Expand Up @@ -262,7 +265,7 @@
return $this->redirectTo($request, $object);
}

$template = $this->templateRegistry->getTemplate('delete');
$template = $this->getTemplate('delete');

/**
* @psalm-suppress DeprecatedMethod
Expand Down Expand Up @@ -373,7 +376,7 @@
// set the theme for the current Admin Form
$this->setFormTheme($formView, $this->admin->getFormTheme());

$template = $this->templateRegistry->getTemplate($templateKey);
$template = $this->getTemplate($templateKey);

/**
* @psalm-suppress DeprecatedMethod
Expand Down Expand Up @@ -496,7 +499,7 @@
$formView = $datagrid->getForm()->createView();
$this->setFormTheme($formView, $this->admin->getFilterTheme());

$template = $batchAction['template'] ?? $this->templateRegistry->getTemplate('batch_confirmation');
$template = $batchAction['template'] ?? $this->getTemplate('batch_confirmation');

/**
* @psalm-suppress DeprecatedMethod
Expand Down Expand Up @@ -645,7 +648,7 @@
// set the theme for the current Admin Form
$this->setFormTheme($formView, $this->admin->getFormTheme());

$template = $this->templateRegistry->getTemplate($templateKey);
$template = $this->getTemplate($templateKey);

/**
* @psalm-suppress DeprecatedMethod
Expand Down Expand Up @@ -680,7 +683,7 @@

$fields = $this->admin->getShow();

$template = $this->templateRegistry->getTemplate('show');
$template = $this->getTemplate('show');

/**
* @psalm-suppress DeprecatedMethod
Expand Down Expand Up @@ -721,7 +724,7 @@

$revisions = $reader->findRevisions($this->admin->getClass(), $objectId);

$template = $this->templateRegistry->getTemplate('history');
$template = $this->getTemplate('history');

/**
* @psalm-suppress DeprecatedMethod
Expand Down Expand Up @@ -775,7 +778,7 @@

$this->admin->setSubject($object);

$template = $this->templateRegistry->getTemplate('show');
$template = $this->getTemplate('show');

/**
* @psalm-suppress DeprecatedMethod
Expand Down Expand Up @@ -838,7 +841,7 @@

$this->admin->setSubject($baseObject);

$template = $this->templateRegistry->getTemplate('show_compare');
$template = $this->getTemplate('show_compare');

/**
* @psalm-suppress DeprecatedMethod
Expand Down Expand Up @@ -949,7 +952,7 @@
}
}

$template = $this->templateRegistry->getTemplate('acl');
$template = $this->getTemplate('acl');

/**
* @psalm-suppress DeprecatedMethod
Expand Down Expand Up @@ -997,9 +1000,9 @@
$this->setTwigGlobal('admin', $this->admin);

if ($this->isXmlHttpRequest($request)) {
$baseTemplate = $this->templateRegistry->getTemplate('ajax');
$baseTemplate = $this->getTemplate('ajax');
} else {
$baseTemplate = $this->templateRegistry->getTemplate('layout');
$baseTemplate = $this->getTemplate('layout');
}

$this->setTwigGlobal('base_template', $baseTemplate);
Expand Down Expand Up @@ -1096,10 +1099,10 @@
\assert(null !== $request);

if ($this->isXmlHttpRequest($request)) {
return $this->templateRegistry->getTemplate('ajax');
return $this->getTemplate('ajax');
}

return $this->templateRegistry->getTemplate('layout');
return $this->getTemplate('layout');
}

/**
Expand Down Expand Up @@ -1613,4 +1616,11 @@

return false;
}

private function getTemplate(string $name): string
{
$cookieLayoutStorage = $this->container->get('sonata.admin.layout_cookie_storage');

return $this->templateRegistry->getTemplate($name, $cookieLayoutStorage->get());

Check failure on line 1624 in src/Controller/CRUDController.php

View workflow job for this annotation

GitHub Actions / Psalm

TooManyArguments

src/Controller/CRUDController.php:1624:41: TooManyArguments: Too many arguments for method Sonata\AdminBundle\Templating\TemplateRegistryInterface::gettemplate - saw 2 (see https://psalm.dev/026)

Check failure on line 1624 in src/Controller/CRUDController.php

View workflow job for this annotation

GitHub Actions / PHPStan

Method Sonata\AdminBundle\Templating\TemplateRegistryInterface::getTemplate() invoked with 2 parameters, 1 required.
}
}
34 changes: 30 additions & 4 deletions src/DependencyInjection/Admin/AbstractTaggedAdmin.php
Original file line number Diff line number Diff line change
Expand Up @@ -524,13 +524,39 @@
$this->templateRegistry = $templateRegistry;
}

final public function setTemplates(array $templates): void
final public function setTemplates(array $templates, /* string $layout = 'default' */): void
{
$this->getTemplateRegistry()->setTemplates($templates);
if (\func_num_args() < 2) {
@trigger_error(
'Not passing the "string $layout" argument explicitly is deprecated since sonata-project/admin-bundle x.y and will be required in 5.0.',
\E_USER_DEPRECATED
);

$this->getTemplateRegistry()->setTemplates($templates, 'default');

Check failure on line 535 in src/DependencyInjection/Admin/AbstractTaggedAdmin.php

View workflow job for this annotation

GitHub Actions / Psalm

TooManyArguments

src/DependencyInjection/Admin/AbstractTaggedAdmin.php:535:43: TooManyArguments: Too many arguments for method Sonata\AdminBundle\Templating\MutableTemplateRegistryInterface::settemplates - saw 2 (see https://psalm.dev/026)

Check failure on line 535 in src/DependencyInjection/Admin/AbstractTaggedAdmin.php

View workflow job for this annotation

GitHub Actions / PHPStan

Method Sonata\AdminBundle\Templating\MutableTemplateRegistryInterface::setTemplates() invoked with 2 parameters, 1 required.
}

$layout = \func_get_arg(1);

// NEXT_MAJOR: Remove code before this comment

$this->getTemplateRegistry()->setTemplates($templates, $layout);

Check failure on line 542 in src/DependencyInjection/Admin/AbstractTaggedAdmin.php

View workflow job for this annotation

GitHub Actions / Psalm

TooManyArguments

src/DependencyInjection/Admin/AbstractTaggedAdmin.php:542:39: TooManyArguments: Too many arguments for method Sonata\AdminBundle\Templating\MutableTemplateRegistryInterface::settemplates - saw 2 (see https://psalm.dev/026)

Check failure on line 542 in src/DependencyInjection/Admin/AbstractTaggedAdmin.php

View workflow job for this annotation

GitHub Actions / PHPStan

Method Sonata\AdminBundle\Templating\MutableTemplateRegistryInterface::setTemplates() invoked with 2 parameters, 1 required.
}

final public function setTemplate(string $name, string $template): void
final public function setTemplate(string $name, string $template, /* string $layout = 'default' */): void
{
$this->getTemplateRegistry()->setTemplate($name, $template);
if (\func_num_args() < 2) {
@trigger_error(
'Not passing the "string $layout" argument explicitly is deprecated since sonata-project/admin-bundle x.y and will be required in 5.0.',
\E_USER_DEPRECATED
);

$this->getTemplateRegistry()->setTemplate($name, $template, 'default');

Check failure on line 553 in src/DependencyInjection/Admin/AbstractTaggedAdmin.php

View workflow job for this annotation

GitHub Actions / Psalm

TooManyArguments

src/DependencyInjection/Admin/AbstractTaggedAdmin.php:553:43: TooManyArguments: Too many arguments for method Sonata\AdminBundle\Templating\MutableTemplateRegistryInterface::settemplate - saw 3 (see https://psalm.dev/026)

Check failure on line 553 in src/DependencyInjection/Admin/AbstractTaggedAdmin.php

View workflow job for this annotation

GitHub Actions / PHPStan

Method Sonata\AdminBundle\Templating\MutableTemplateRegistryInterface::setTemplate() invoked with 3 parameters, 2 required.
}

$layout = \func_get_arg(1);

// NEXT_MAJOR: Remove code before this comment

$this->getTemplateRegistry()->setTemplate($name, $template, $layout);

Check failure on line 560 in src/DependencyInjection/Admin/AbstractTaggedAdmin.php

View workflow job for this annotation

GitHub Actions / Psalm

TooManyArguments

src/DependencyInjection/Admin/AbstractTaggedAdmin.php:560:39: TooManyArguments: Too many arguments for method Sonata\AdminBundle\Templating\MutableTemplateRegistryInterface::settemplate - saw 3 (see https://psalm.dev/026)

Check failure on line 560 in src/DependencyInjection/Admin/AbstractTaggedAdmin.php

View workflow job for this annotation

GitHub Actions / PHPStan

Method Sonata\AdminBundle\Templating\MutableTemplateRegistryInterface::setTemplate() invoked with 3 parameters, 2 required.
}
}
109 changes: 109 additions & 0 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,54 @@
* },
* search: bool,
* show_mosaic_button: bool,
* use_layouts: bool,
* allow_layouts: list<string>,
* layouts: array{
* name: string,
* templates: array{
* acl: string,
* action: string,
* action_create: string,
* add_block: string,
* ajax: string,
* base_list_field: string,
* batch: string,
* batch_confirmation: string,
* button_acl: string,
* button_create: string,
* button_edit: string,
* button_history: string,
* button_list: string,
* button_show: string,
* dashboard: string,
* delete: string,
* edit: string,
* filter: string,
* filter_theme: list<string>,
* form_theme: list<string>,
* history: string,
* history_revision_timestamp: string,
* inner_list_row: string,
* knp_menu_template: string,
* layout: string,
* list: string,
* list_block: string,
* outer_list_rows_list: string,
* outer_list_rows_mosaic: string,
* outer_list_rows_tree: string,
* pager_links: string,
* pager_results: string,
* preview: string,
* search: string,
* search_result_block: string,
* select: string,
* short_object_description: string,
* show: string,
* show_compare: string,
* tab_menu_template: string,
* user_block: string,
* },
* },
* templates: array{
* acl: string,
* action: string,
Expand Down Expand Up @@ -560,6 +608,67 @@ public function getConfigTreeBuilder(): TreeBuilder
->end()
->end()

->booleanNode('use_layouts')->defaultFalse()->end()
->arrayNode('allow_layouts')
->prototype('scalar')->defaultValue(['default'])->end()
->end()
->arrayNode('layouts')
->prototype('array')
->children()
->scalarNode('name')->cannotBeEmpty()->end()
->arrayNode('templates')
->addDefaultsIfNotSet()
->children()
->scalarNode('user_block')->defaultValue('@SonataAdmin/Core/user_block.html.twig')->cannotBeEmpty()->end()
->scalarNode('add_block')->defaultValue('@SonataAdmin/Core/add_block.html.twig')->cannotBeEmpty()->end()
->scalarNode('layout')->defaultValue('@SonataAdmin/standard_layout.html.twig')->cannotBeEmpty()->end()
->scalarNode('ajax')->defaultValue('@SonataAdmin/ajax_layout.html.twig')->cannotBeEmpty()->end()
->scalarNode('dashboard')->defaultValue('@SonataAdmin/Core/dashboard.html.twig')->cannotBeEmpty()->end()
->scalarNode('search')->defaultValue('@SonataAdmin/Core/search.html.twig')->cannotBeEmpty()->end()
->scalarNode('list')->defaultValue('@SonataAdmin/CRUD/list.html.twig')->cannotBeEmpty()->end()
->scalarNode('filter')->defaultValue('@SonataAdmin/Form/filter_admin_fields.html.twig')->cannotBeEmpty()->end()
->scalarNode('show')->defaultValue('@SonataAdmin/CRUD/show.html.twig')->cannotBeEmpty()->end()
->scalarNode('show_compare')->defaultValue('@SonataAdmin/CRUD/show_compare.html.twig')->cannotBeEmpty()->end()
->scalarNode('edit')->defaultValue('@SonataAdmin/CRUD/edit.html.twig')->cannotBeEmpty()->end()
->scalarNode('preview')->defaultValue('@SonataAdmin/CRUD/preview.html.twig')->cannotBeEmpty()->end()
->scalarNode('history')->defaultValue('@SonataAdmin/CRUD/history.html.twig')->cannotBeEmpty()->end()
->scalarNode('acl')->defaultValue('@SonataAdmin/CRUD/acl.html.twig')->cannotBeEmpty()->end()
->scalarNode('history_revision_timestamp')->defaultValue('@SonataAdmin/CRUD/history_revision_timestamp.html.twig')->cannotBeEmpty()->end()
->scalarNode('action')->defaultValue('@SonataAdmin/CRUD/action.html.twig')->cannotBeEmpty()->end()
->scalarNode('select')->defaultValue('@SonataAdmin/CRUD/list__select.html.twig')->cannotBeEmpty()->end()
->scalarNode('list_block')->defaultValue('@SonataAdmin/Block/block_admin_list.html.twig')->cannotBeEmpty()->end()
->scalarNode('search_result_block')->defaultValue('@SonataAdmin/Block/block_search_result.html.twig')->cannotBeEmpty()->end()
->scalarNode('short_object_description')->defaultValue('@SonataAdmin/Helper/short-object-description.html.twig')->cannotBeEmpty()->end()
->scalarNode('delete')->defaultValue('@SonataAdmin/CRUD/delete.html.twig')->cannotBeEmpty()->end()
->scalarNode('batch')->defaultValue('@SonataAdmin/CRUD/list__batch.html.twig')->cannotBeEmpty()->end()
->scalarNode('batch_confirmation')->defaultValue('@SonataAdmin/CRUD/batch_confirmation.html.twig')->cannotBeEmpty()->end()
->scalarNode('inner_list_row')->defaultValue('@SonataAdmin/CRUD/list_inner_row.html.twig')->cannotBeEmpty()->end()
->scalarNode('outer_list_rows_mosaic')->defaultValue('@SonataAdmin/CRUD/list_outer_rows_mosaic.html.twig')->cannotBeEmpty()->end()
->scalarNode('outer_list_rows_list')->defaultValue('@SonataAdmin/CRUD/list_outer_rows_list.html.twig')->cannotBeEmpty()->end()
->scalarNode('outer_list_rows_tree')->defaultValue('@SonataAdmin/CRUD/list_outer_rows_tree.html.twig')->cannotBeEmpty()->end()
->scalarNode('base_list_field')->defaultValue('@SonataAdmin/CRUD/base_list_field.html.twig')->cannotBeEmpty()->end()
->scalarNode('pager_links')->defaultValue('@SonataAdmin/Pager/links.html.twig')->cannotBeEmpty()->end()
->scalarNode('pager_results')->defaultValue('@SonataAdmin/Pager/results.html.twig')->cannotBeEmpty()->end()
->scalarNode('tab_menu_template')->defaultValue('@SonataAdmin/Core/tab_menu_template.html.twig')->cannotBeEmpty()->end()
->scalarNode('knp_menu_template')->defaultValue('@SonataAdmin/Menu/sonata_menu.html.twig')->cannotBeEmpty()->end()
->scalarNode('action_create')->defaultValue('@SonataAdmin/CRUD/dashboard__action_create.html.twig')->cannotBeEmpty()->end()
->scalarNode('button_acl')->defaultValue('@SonataAdmin/Button/acl_button.html.twig')->cannotBeEmpty()->end()
->scalarNode('button_create')->defaultValue('@SonataAdmin/Button/create_button.html.twig')->cannotBeEmpty()->end()
->scalarNode('button_edit')->defaultValue('@SonataAdmin/Button/edit_button.html.twig')->cannotBeEmpty()->end()
->scalarNode('button_history')->defaultValue('@SonataAdmin/Button/history_button.html.twig')->cannotBeEmpty()->end()
->scalarNode('button_list')->defaultValue('@SonataAdmin/Button/list_button.html.twig')->cannotBeEmpty()->end()
->scalarNode('button_show')->defaultValue('@SonataAdmin/Button/show_button.html.twig')->cannotBeEmpty()->end()
->arrayNode('form_theme')
->prototype('scalar')->end()
->end()
->arrayNode('filter_theme')
->prototype('scalar')->end()
->end()
->end()
->end()
->end()
->end()
->end()
->arrayNode('templates')
->addDefaultsIfNotSet()
->children()
Expand Down
Loading
Loading