渲染前检查模板是否存在

问题描述 投票:0回答:7

有没有办法在调用渲染之前检查树枝模板是否存在? try catch 块似乎不起作用,至少在开发环境中是这样,而且,我更喜欢检查而不是异常的成本。

这个类TwigEngine有一个exists()方法,但没有找到使用示例。

symfony twig transclusion
7个回答
68
投票

如果配置为默认,则持有 twig 引擎的服务是“模板”。

在控制器内执行以下操作:

if ( $this->get('templating')->exists('AcmeDemoBundle:Foo:bar.html.twig') ) {
     // ...
}

另一种方法是捕获 render() 方法抛出的异常,如下所示:

 try {
      $this->get('templating')->render('AcmeDemoBundle:Foo:bar.html.twig')
  } catch (\Exception $ex) {
     // your conditional code here.
  }

在普通控制器中...

$this->render('...')

只是...的别名

$this->container->get('templating')->renderResponse($view, $parameters, $response);

...同时...

$this->get('...') 

... 是

的别名
$this->container->get('...')

看看 Symfony\FrameworkBundle\Controller\Controller


40
投票

templating
服务将在未来的 Symfony 版本中删除。基于
twig
服务的面向未来的解决方案是:

if ($this->get('twig')->getLoader()->exists('AcmeDemoBundle:Foo:bar.html.twig')) {
    // ...
}

28
投票

如果您需要从树枝模板内部检查模板是否存在,则必须使用数组包含方法,如文档中所述:

{% include ['page_detailed.html', 'page.html'] %}

25
投票

也许还有一个选择:

{% include 'AcmeDemoBundle:Foo:bar.html.twig' ignore missing %}

当找不到模板时,忽略缺失的添加告诉 twig 什么也不做。


2
投票

您可以使用依赖注入来做到这一点:

use Symfony\Component\Templating\EngineInterface;

public function fooAction(EngineInterface $templeEngine)
{
    if ($templeEngine->exists("@App/bar/foo.html.twig")) {
        // ...
    }
    // ...
}

使用 Symfony 3.4 进行测试。


2
投票

您可以使用依赖注入来获取存储Twig配置的环境。像这样(在控制器中):

/**
 * @Route("/{path}")
 */
public function index($path, Twig\Environment $env)
{
    if (!$env->getLoader()->exists('pages/'.$path.'.html.twig')) {
        return $this->render('pages/404.html.twig');
    }
}

0
投票

我经常创建控制器的抽象,因为我需要模板覆盖。对我来说最简单的方法是重写渲染模板以允许数组:

    /**
     * @param array<int,string>|string $view
     * @param array<string,mixed> $parameters
     *
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    protected function render(array|string $view, array $parameters = [], Response $response = null): Response
    {
        if (!$this->container->has('twig')) {
            throw new \LogicException(
                'You cannot use the "renderView" method if the Twig Bundle is not available. Try running "composer require symfony/twig-bundle".'
            );
        }
        /**
         * @var Environment $twig
         */
        $twig = $this->container->get('twig');

        if (\is_array($view)) {
            foreach ($view as $template) {
                if ($twig->getLoader()->exists($template)) {
                    return parent::render($template, $parameters, $response);
                }
            }
            throw new \BadMethodCallException(sprintf('Templates %s don\'t exist.', implode(' and ', $view)));
        }

        return parent::render($view, $parameters, $response); // TODO: Change the autogenerated stub
    }
© www.soinside.com 2019 - 2024. All rights reserved.