Twig Loader 命名空间

Twig Loader Namespacing

我正在慢慢重构我的代码,我在 PHP 中使用 TWIG 作为模板 "engine"。我的应用程序中的当前目录结构如下 (PSR-4) -

src/ 
    Test/
        User/
            Resources/
                views/
     Test/
        Core/
            Resources/
                views/

我正在使用以下代码加载 TWIG -

Twig_Autoloader::register();
$loader = new Twig_Loader_Filesystem(array(
    dirname(__DIR__). '/src/Test'
));
$twig = new Twig_Environment($loader, array(
    'cache' => dirname(__DIR__). '/app/storage/cache',
    'debug' => true,
));

目前,它工作正常并允许我调用每个 TWIG 文件,如 -

echo $twig->render('User\Resources\views\partials\sidebar.html.twig', $data);

不过,输入所有这些内容很耗时,我想简化它。无论如何,Symfony 如何自动加载捆绑包?

我也尝试在我的加载器中使用它,但是如果视图文件夹中有类似的目录,所有内容都会被找到的第一个视图覆盖。例如 - Core/Resources/views/partials/sidebar.twig 将被用来代替 User/Resources/views/partials/sidebar.twig

$loader = new Twig_Loader_Filesystem(array(
            dirname(__DIR__). '/src/Test/Core/Resources/views',
            dirname(__DIR__). '/src/Test/User/Resources/views',
    ));

想法?

谢谢!

有,叫做Twig命名空间:http://twig.sensiolabs.org/doc/api.html#built-in-loaders

$loader->addPath(dirname(__DIR__).'/src/Test/Core/Resources/views', 'core');
$loader->addPath( dirname(__DIR__). '/src/Test/User/Resources/views', 'user');

现在你的路径是 @user/partials/sidebar.html.twig@core/...

该死。 @Wouter J 又打败了我!好吧。

Twig 命名空间将允许您缩写模板路径。同一个命名空间可以指向多个目录,因此您可以控制搜索目录的顺序。 http://symfony.com/doc/current/cookbook/templating/namespaced_paths.html

这里是 app/config/config.yml

的例子
twig:
paths:
    "%kernel.root_dir%/../src/Cerad/Bundle/AppBundle/Resources/views/CeradGame": CeradGame
    "%kernel.root_dir%/../../cerad2/src/Cerad/Bundle/GameBundle/Action":         CeradGame

所以会在以上两个目录中查找以@CeradGame开头的模板。

如果您需要比配置文件提供更多的控制权,那么您还可以使用编译器传递(http://symfony.com/doc/current/cookbook/service_container/compiler_passes.html) 来设置:

class Pass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
    $bundleDirAction = $container->getParameter('cerad_api01__bundle_dir') . '/Action';

    $twigFilesystemLoaderDefinition = $container->getDefinition('twig.loader.filesystem');

    $twigFilesystemLoaderDefinition->addMethodCall('addPath', array($bundleDirAction, 'CeradApi01'));        
}

最后,确定确切的树枝路径可能有点困难。这是从命令行转储它们的命令:

class TwigCommand extends ContainerAwareCommand
{
protected function configure()
{
    $this
        ->setName       ('twig:paths')
        ->setDescription('Twig Paths')
   ;
}
protected function getService($id)     { return $this->getContainer()->get($id); }
protected function getParameter($name) { return $this->getContainer()->getParameter($name); }

protected function execute(InputInterface $input, OutputInterface $output)
{
    $loader = $this->getService('twig.loader');
    $namespaces = $loader->getNamespaces();
    foreach($namespaces as $namespace)
    {
        $paths = $loader->getPaths($namespace);
        foreach($paths as $path)
        {
          //if (substr($namespace,0,5) == 'Cerad') echo sprintf("NS %-12s %s\n",$namespace,$path);
            echo sprintf("NS %-12s %s\n",$namespace,$path);
        }
    }
    return;

    $exists = $loader->exists('@CeradTourn/Tourn/Welcome/TournWelcomeInde.html.twig');
    if ($exists) echo "Found it\n";
    else         echo "Not found\n";
}   

我前段时间写了命令。树枝包中可能有类似的东西。