【问题标题】:Sonata Admin Override template depend of userSonata Admin Override 模板取决于用户
【发布时间】:2019-08-27 01:40:09
【问题描述】:

我尝试在 Sonata Admin 中覆盖布局模板,但取决于登录用户。如果登录的用户属于组客户有一些角色 - 显示其他布局。

我想要改变 -

layout" => "@SonataAdmin/standard_layout.html.twig" 

最好的地方在哪里?

我发现我可以在管理类中做到这一点 - 覆盖 getTemplate。

但是有可能做到这一点是一些监听器并在不编辑管理类的情况下全局切换?

更新 1

我创建类

class SonataTemplateRegistry implements MutableTemplateRegistryInterface
{

    /**
     * @var string[]
     */
    private $templates = [];

    /**
     * @param string[] $templates
     * @param ContactService $contactService
     */
    public function __construct(array $templates = [], ContactService $contactService)
    {

        $templates['layout']= '@SonataAdmin/layout1.html.twig';
//        $templates['layout']= '@SonataAdmin/standard_layout.html.twig';

//        echo '<pre>'; var_dump($templates); die();

        $this->templates = $templates;

    }

注册

 sonata.admin.global_template_registry:
        class: App\Service\SonataTemplateRegistry
        public: true
        arguments: ['%sonata.admin.configuration.templates%', '@mea.contact']

类被触发 - die() 显示模板,但当我在这里更改时主模板没有更改。

更新 2

在管理类中,当我获得布局模板时,我得到了正确的@SonataAdmin/layout1.html.twig

protected function configureListFields(ListMapper $listMapper)
    {

        var_dump($this->configurationPool->getTemplate('layout'));

但是没有加载,还是看@SonataAdmin/standard_layout.html.twig

更新 3

我发现了一个奇怪的行为 - 主页奏鸣曲管理员 - 切换模板有效,但页面下已经使用默认模板

更新 4 我发现了一些有趣的东西,每个管理面板都有像这里这样的子服务:

php bin/console debug:container |grep app.admin.social
  app.admin.social.accounts                                                                     App\SocialManager\Admin\SocialAccountAdmin                                                      
  app.admin.social.accounts.template_registry                                                   Sonata\AdminBundle\Templating\TemplateRegistry                                                  
  app.admin.social.order                                                                        App\SocialManager\Admin\SocialManagementOrderAdmin                                              
  app.admin.social.order.template_registry                                                      Sonata\AdminBundle\Templating\TemplateRegistry    

我覆盖参数:

parameters:
    sonata.admin.global_template_registry: App\Service\SonataTemplateRegistry

和服务

sonata.admin.global_template_registry:
    class: App\Service\SonataTemplateRegistry
    public: true
    arguments: ['%sonata.admin.configuration.templates%', '@mea.contact']

为什么奏鸣曲仍然使用 Sonata\AdminBundle\Templating\TemplateRegistry

protected function configureListFields(ListMapper $listMapper)
    {


$this->getTemplateRegistry()

给 Sonata\AdminBundle\Templating\TemplateRegistry

【问题讨论】:

  • “但取决于登录用户”是什么意思?你能举个例子说明你想做什么吗?
  • 如果登录的用户属于组客户有一些角色 - 显示其他布局

标签: symfony sonata-admin sonata


【解决方案1】:

您可以通过服务标签使用解决方法。 首先创建自己的模板注册表并实现 MutableTemplateRegistryInterface。 然后创建编译器通道。

<?php

namespace App\DependencyInjection\Compiler;

use App\Registry\TemplateRegistry;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

/**
 * Class SonataAdminTemplateRegistryPass
 * @package App\DependencyInjection\Compiler
 */
class SonataAdminTemplateRegistryPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container)
    {
        foreach ($container->findTaggedServiceIds('sonata.admin.template_registry') as $id => $tags)
        {
            //because @see src/vendor/sonata-project/admin-bundle/src/DependencyInjection/Compiler/AddDependencyCallsCompilerPass.php:405
            $adminServiceId = str_replace(".template_registry", "", $id);
            $def            = $container->getDefinition($adminServiceId);
            $def->removeMethodCall('setTemplateRegistry');
            $def->addMethodCall('setTemplateRegistry', [new Reference(TemplateRegistry::class)]);
        }
    }

}

然后像这样将编译器传递添加到 src/Kernel.php

protected function build(ContainerBuilder $container)
{
    $container->addCompilerPass(new SonataAdminTemplateRegistryPass());
}

并且您将始终在任何管理类中覆盖 TemplateRegistry。 所以你可以在你自己的 TemplateRegistry 中实现你自己的逻辑:)

【讨论】:

    【解决方案2】:

    您可以使用单个 Twig 模板执行此操作:

    {# layout.html.twig #}
    {# mutatis mutandis #}
    
    {% extends app.user ?
        ('ROLE_ADMIN' in app.user.role ?
            'admin_layout.html.twig' :
            'customer_layout.html.twig'
        ) :
        'fallback.html.twig'
    %}
    

    【讨论】:

      猜你喜欢
      • 2013-09-06
      • 2018-04-13
      • 2018-07-22
      • 1970-01-01
      • 1970-01-01
      • 2016-04-07
      • 2011-04-23
      • 2016-06-25
      • 2014-06-01
      相关资源
      最近更新 更多