【问题标题】:Check if template exists before rendering渲染前检查模板是否存在
【发布时间】:2013-05-21 00:35:53
【问题描述】:

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

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

【问题讨论】:

    标签: symfony twig transclusion


    【解决方案1】:

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

    在您的 Controller 中执行以下操作:

    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。

    【讨论】:

    • 这不再是推荐的答案,请查看下面的哈维尔答案。
    • 这适用于 Symfony 3.4。* $this->container->get('templating')->exists('@YourBundle/..Path../twigName.html.twig') 如果没有 $this->container,请改用 $this->getContainer()->...。
    【解决方案2】:

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

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

    【讨论】:

    • 您是否有任何参考来支持您的声明,即templating 服务将在未来的 Symfony 版本中被删除?
    • 哈维尔在为 SensioLabs 工作应该是一个参考 ;)
    • 关于弃用模板的公告:symfony.com/blog/…
    【解决方案3】:

    如果您需要从 twig 模板中检查模板是否存在,您必须使用数组包含方法,如 documentation 中所述:

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

    【讨论】:

    • 这在模板端非常方便。当 tempate 不存在时,可以有一个空模板来安全地什么都不做{% include ['page_detailed.html', 'page.html', 'empty-catch-all.html'] %}
    • 如果模板已经不存在,有没有办法只包含模板?
    【解决方案4】:

    也许也是一种选择:

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

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

    【讨论】:

    • 我无法想象这会有用的情况,但它仍然是一件非常有趣的事情。
    • 这是在动态加载模板的情况下。就像如果您想通过给定名称包含特定模板并且该名称的模板不存在并且您不希望出现 500 比这是一个可能的选项
    • 谢谢 - 根据上面的评论,使用它来动态加载模板。
    【解决方案5】:

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

    use Symfony\Component\Templating\EngineInterface;
    
    public function fooAction(EngineInterface $templeEngine)
    {
        if ($templeEngine->exists("@App/bar/foo.html.twig")) {
            // ...
        }
        // ...
    }
    

    使用 Symfony 3.4 测试。

    【讨论】:

    • 以我在最新 flex 中看到的方式,您不需要 @App 引用,如果模板位于其默认位置,则相对路径就足够了,即我有模板/电子邮件/campaign.html。 twig 和 @App/Email/campaign.html.twig 不工作只是 Email/campaign.html.twig 工作
    【解决方案6】:

    您可以使用依赖注入来获取存储 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');
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-09-07
      • 1970-01-01
      • 1970-01-01
      • 2021-08-18
      • 2021-02-13
      • 1970-01-01
      • 2014-12-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多