Symfony 在细枝模板中切换主题

Symfony 在细枝模板中切换主题,symfony,twig,Symfony,Twig,我有一个功能齐全的网站与Symfony和细枝 现在我想这样做:在src/AppBundle/Resources/views文件夹中放置两个或多个主题,比如theme1和theme2,放在两个不同的目录下:theme1和theme2,这样我就可以以某种方式快速更改我网站的主题 我从以下位置将模板引用放在我的小树枝模板中: return $this->render('AppBundle:default:index.html.twig'... 例如: return $this->rend

我有一个功能齐全的网站与Symfony和细枝

现在我想这样做:在
src/AppBundle/Resources/views
文件夹中放置两个或多个主题,比如
theme1
theme2
,放在两个不同的目录下:
theme1
theme2
,这样我就可以以某种方式快速更改我网站的主题

我从以下位置将模板引用放在我的小树枝模板中:

return $this->render('AppBundle:default:index.html.twig'...
例如:

return $this->render('AppBundle:theme1:default:index.html.twig'...
但它不起作用:找不到模板


这方面有什么帮助吗?

我已经在我的Symfony项目中完成了这项工作,这取决于我从哪个域查看我的站点。您可能有一个不同的用例,但下面是一个我如何实现结果的示例

将以下函数添加到src/YourBundle/DependencyInjection/Configuration.php

public function getConfigTreeBuilder()
{
    $treeBuilder = new TreeBuilder();
    $rootNode = $treeBuilder->root('bundle_name');

    $rootNode
            ->children()
                ->arrayNode('sites')
                ->prototype('array')
                    ->children()
                        ->scalarNode('domain')->isRequired()->cannotBeEmpty()->validate()->ifNull()->thenInValid("Domain name must be set")->end()->end()
                        ->scalarNode('template_directory')->isRequired()->cannotBeEmpty()->validate()->ifNull()->thenInValid("Template Directory must be set")->end()->end()
                    ->end()
                ->end()
            ->end()
    ;

    return $treeBuilder;
}
<?php

    namespace YourBundle\EventListener;

    use Symfony\Component\HttpKernel\Event\FilterControllerEvent;

    class TemplateListener
    {

        /** @var \Twig_Environment */
        private $twig;

        /**
         * @var array
         */
        private $hostsConfig;

        public function __construct(\Twig_Environment $twig, $hostsConfig) {
            $this->twig = $twig;
            $this->hostsConfig = $hostsConfig;
        }

        public function onKernelController(FilterControllerEvent $event) {
            $currentHost = $event->getRequest()->getHost();

            if(isset($this->hostsConfig[$currentHost])) {
                $templateDirectory = $this->hostsConfig[$currentHost]['template_directory'];    
            } else {
                $templateDirectory = 'theme1';
            }

            $this->twig->getLoader()->prependPath(dirname(__DIR__) . '/../YourBundle/Resources/views/' . $this->hostsConfig[$currentHost]['template_directory']);
        }
    }
    public function load(array $configs, ContainerBuilder $container)
    {
        //...

        $sites = array();

        //Re arrange the sites configuration to be easily accessed by domain as index
        foreach ($config['sites'] as $siteConfig) {
            $sites[$siteConfig['domain']]['template_directory'] = $siteConfig['template_directory'];
        }

        $container->setParameter('hosts.config', $sites);

        //...
    }
将bundle_name替换为您选择的名称

将以下内容添加到app/config/parameters.yml

bundle_name:
    sites:
        site1:
            domain: first-domain.tld
            template_directory: theme1
        site2:
            domain: second-domain.tld
            template_directory: theme2
您可以添加任意数量的网站,只要您有主题设置

创建一个事件监听器src/YourBundle/EventListener/TemplateListener.php

public function getConfigTreeBuilder()
{
    $treeBuilder = new TreeBuilder();
    $rootNode = $treeBuilder->root('bundle_name');

    $rootNode
            ->children()
                ->arrayNode('sites')
                ->prototype('array')
                    ->children()
                        ->scalarNode('domain')->isRequired()->cannotBeEmpty()->validate()->ifNull()->thenInValid("Domain name must be set")->end()->end()
                        ->scalarNode('template_directory')->isRequired()->cannotBeEmpty()->validate()->ifNull()->thenInValid("Template Directory must be set")->end()->end()
                    ->end()
                ->end()
            ->end()
    ;

    return $treeBuilder;
}
<?php

    namespace YourBundle\EventListener;

    use Symfony\Component\HttpKernel\Event\FilterControllerEvent;

    class TemplateListener
    {

        /** @var \Twig_Environment */
        private $twig;

        /**
         * @var array
         */
        private $hostsConfig;

        public function __construct(\Twig_Environment $twig, $hostsConfig) {
            $this->twig = $twig;
            $this->hostsConfig = $hostsConfig;
        }

        public function onKernelController(FilterControllerEvent $event) {
            $currentHost = $event->getRequest()->getHost();

            if(isset($this->hostsConfig[$currentHost])) {
                $templateDirectory = $this->hostsConfig[$currentHost]['template_directory'];    
            } else {
                $templateDirectory = 'theme1';
            }

            $this->twig->getLoader()->prependPath(dirname(__DIR__) . '/../YourBundle/Resources/views/' . $this->hostsConfig[$currentHost]['template_directory']);
        }
    }
    public function load(array $configs, ContainerBuilder $container)
    {
        //...

        $sites = array();

        //Re arrange the sites configuration to be easily accessed by domain as index
        foreach ($config['sites'] as $siteConfig) {
            $sites[$siteConfig['domain']]['template_directory'] = $siteConfig['template_directory'];
        }

        $container->setParameter('hosts.config', $sites);

        //...
    }
您需要更新所有控制器(或用于渲染视图的任何控制器)

您不需要使用常规的Class:Bundle:Folder方法,只需要使用相对路径,就像您在视图/theme1(或)theme2/

return $this->render(
    'default/index.html.twig',
    array(
        ...
    )
)
这将检查
src/YourBundle/Resources/views/theme1/default/index.html.twig


src/YourBundle/Resources/views/theme2/default/index.html.twig

取决于您访问的域


我已经在我的Symfony项目中完成了这项工作,这取决于我从哪个域查看我的站点将使用flick模板。您可能有一个不同的用例,但下面是一个我如何实现结果的示例

将以下函数添加到src/YourBundle/DependencyInjection/Configuration.php

public function getConfigTreeBuilder()
{
    $treeBuilder = new TreeBuilder();
    $rootNode = $treeBuilder->root('bundle_name');

    $rootNode
            ->children()
                ->arrayNode('sites')
                ->prototype('array')
                    ->children()
                        ->scalarNode('domain')->isRequired()->cannotBeEmpty()->validate()->ifNull()->thenInValid("Domain name must be set")->end()->end()
                        ->scalarNode('template_directory')->isRequired()->cannotBeEmpty()->validate()->ifNull()->thenInValid("Template Directory must be set")->end()->end()
                    ->end()
                ->end()
            ->end()
    ;

    return $treeBuilder;
}
<?php

    namespace YourBundle\EventListener;

    use Symfony\Component\HttpKernel\Event\FilterControllerEvent;

    class TemplateListener
    {

        /** @var \Twig_Environment */
        private $twig;

        /**
         * @var array
         */
        private $hostsConfig;

        public function __construct(\Twig_Environment $twig, $hostsConfig) {
            $this->twig = $twig;
            $this->hostsConfig = $hostsConfig;
        }

        public function onKernelController(FilterControllerEvent $event) {
            $currentHost = $event->getRequest()->getHost();

            if(isset($this->hostsConfig[$currentHost])) {
                $templateDirectory = $this->hostsConfig[$currentHost]['template_directory'];    
            } else {
                $templateDirectory = 'theme1';
            }

            $this->twig->getLoader()->prependPath(dirname(__DIR__) . '/../YourBundle/Resources/views/' . $this->hostsConfig[$currentHost]['template_directory']);
        }
    }
    public function load(array $configs, ContainerBuilder $container)
    {
        //...

        $sites = array();

        //Re arrange the sites configuration to be easily accessed by domain as index
        foreach ($config['sites'] as $siteConfig) {
            $sites[$siteConfig['domain']]['template_directory'] = $siteConfig['template_directory'];
        }

        $container->setParameter('hosts.config', $sites);

        //...
    }
将bundle_name替换为您选择的名称

将以下内容添加到app/config/parameters.yml

bundle_name:
    sites:
        site1:
            domain: first-domain.tld
            template_directory: theme1
        site2:
            domain: second-domain.tld
            template_directory: theme2
您可以添加任意数量的网站,只要您有主题设置

创建一个事件监听器src/YourBundle/EventListener/TemplateListener.php

public function getConfigTreeBuilder()
{
    $treeBuilder = new TreeBuilder();
    $rootNode = $treeBuilder->root('bundle_name');

    $rootNode
            ->children()
                ->arrayNode('sites')
                ->prototype('array')
                    ->children()
                        ->scalarNode('domain')->isRequired()->cannotBeEmpty()->validate()->ifNull()->thenInValid("Domain name must be set")->end()->end()
                        ->scalarNode('template_directory')->isRequired()->cannotBeEmpty()->validate()->ifNull()->thenInValid("Template Directory must be set")->end()->end()
                    ->end()
                ->end()
            ->end()
    ;

    return $treeBuilder;
}
<?php

    namespace YourBundle\EventListener;

    use Symfony\Component\HttpKernel\Event\FilterControllerEvent;

    class TemplateListener
    {

        /** @var \Twig_Environment */
        private $twig;

        /**
         * @var array
         */
        private $hostsConfig;

        public function __construct(\Twig_Environment $twig, $hostsConfig) {
            $this->twig = $twig;
            $this->hostsConfig = $hostsConfig;
        }

        public function onKernelController(FilterControllerEvent $event) {
            $currentHost = $event->getRequest()->getHost();

            if(isset($this->hostsConfig[$currentHost])) {
                $templateDirectory = $this->hostsConfig[$currentHost]['template_directory'];    
            } else {
                $templateDirectory = 'theme1';
            }

            $this->twig->getLoader()->prependPath(dirname(__DIR__) . '/../YourBundle/Resources/views/' . $this->hostsConfig[$currentHost]['template_directory']);
        }
    }
    public function load(array $configs, ContainerBuilder $container)
    {
        //...

        $sites = array();

        //Re arrange the sites configuration to be easily accessed by domain as index
        foreach ($config['sites'] as $siteConfig) {
            $sites[$siteConfig['domain']]['template_directory'] = $siteConfig['template_directory'];
        }

        $container->setParameter('hosts.config', $sites);

        //...
    }
您需要更新所有控制器(或用于渲染视图的任何控制器)

您不需要使用常规的Class:Bundle:Folder方法,只需要使用相对路径,就像您在视图/theme1(或)theme2/

return $this->render(
    'default/index.html.twig',
    array(
        ...
    )
)
这将检查
src/YourBundle/Resources/views/theme1/default/index.html.twig


src/YourBundle/Resources/views/theme2/default/index.html.twig

取决于您访问的域

而不是这个:

return $this->render('AppBundle:theme1:default:index.html.twig'...
您应该使用以下选项:

return $this->render('AppBundle:theme1/default:index.html.twig'...
或者这个:

return $this->render('AppBundle:theme1:default/index.html.twig'...
与此相反:

return $this->render('AppBundle:theme1:default:index.html.twig'...
您应该使用以下选项:

return $this->render('AppBundle:theme1/default:index.html.twig'...
或者这个:

return $this->render('AppBundle:theme1:default/index.html.twig'...

我认为在两个冒号之后需要使用斜杠:
AppBundle:theme1:default/index.html.twig
,更深一层:
AppBundle:theme1:default/front/panel/advert.html.twig
等等。我认为在两个冒号之后需要使用斜杠:
AppBundle:theme1:default/index.html.twig
,更深层:
AppBundle:theme1:default/front/panel/advert.html.twig
等等。为了提供更多上下文:
BundleName:ActionName:TemplateName
符号在Symfony中由一个特殊的语法解析,该语法只处理只包含两个冒号的模板名称。其他一切都像往常一样处理,这意味着找不到模板。是的,就是这样。谢谢。在任何情况下,引用模板的现代推荐方法是
return$this->render(“@App/theme1/default/index.html.twig”…
。如您所见,使用此符号,无论创建多少文件夹,您都不会遇到任何问题。为了提供更多上下文:
BundleName:ActionName:TemplateName
符号在Symfony中由一个特殊的语法解析,该语法只处理正好包含两个冒号的模板名称。每个其他事情照常处理,这意味着找不到模板。是的,就是这样。谢谢。在任何情况下,引用模板的现代推荐方法是
return$this->render(“@App/theme1/default/index.html.twig”…
。正如您所见,使用此符号,无论创建多少文件夹,您都不会遇到任何问题。