Twig Loader命名空间

时间:2015-02-26 18:45:01

标签: php symfony twig

我正在慢慢地重构我的代码,而我正在使用TWIG作为我的模板"引擎"用PHP。我应用程序中的当前目录结构如下(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如何自动加载捆绑包?

我也尝试在我的加载器中使用它,但如果views文件夹中有类似的目录,则所有内容都会被找到的第一个视图覆盖。例如 - 将使用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',
    ));

思想?

谢谢!

2 个答案:

答案 0 :(得分:4)

有,它被称为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/...

答案 1 :(得分:1)

认真。 @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";
}   

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