Check if template exists before rendering
Solution 1
The service holding the twig engine if configured as default is 'templating'.
Inside your Controller do the following:
if ( $this->get('templating')->exists('AcmeDemoBundle:Foo:bar.html.twig') ) {
// ...
}
The alternative would be catching exception the render() method throws like this:
try {
$this->get('templating')->render('AcmeDemoBundle:Foo:bar.html.twig')
} catch (\Exception $ex) {
// your conditional code here.
}
In a normal controller ...
$this->render('...')
is only an alias for ...
$this->container->get('templating')->renderResponse($view, $parameters, $response);
... while ...
$this->get('...')
... is an alias for
$this->container->get('...')
Have a look at Symfony\FrameworkBundle\Controller\Controller.
Solution 2
The templating
service will be removed in future Symfony versions. The future-proof solution based on the twig
service is:
if ($this->get('twig')->getLoader()->exists('AcmeDemoBundle:Foo:bar.html.twig')) {
// ...
}
Solution 3
In case you need to check for template existance from inside twig templates you have to use the array include methods, as described in the documentation:
{% include ['page_detailed.html', 'page.html'] %}
Solution 4
Maybe also an option:
{% include 'AcmeDemoBundle:Foo:bar.html.twig' ignore missing %}
The ignore missing addition tells twig to simply do nothing, when the template is not found.
Solution 5
You can do it this way using dependency injection:
use Symfony\Component\Templating\EngineInterface;
public function fooAction(EngineInterface $templeEngine)
{
if ($templeEngine->exists("@App/bar/foo.html.twig")) {
// ...
}
// ...
}
Tested with Symfony 3.4.
Related videos on Youtube
K. Weber
Updated on September 19, 2020Comments
-
K. Weber almost 4 years
is there a way to check if twig template exists before calling to render? A try catch block seems not to work, at least in dev environment, and plus, I prefer a check than the cost of an exception.
This class TwigEngine has an exists() method, but didn't find examples on use.
-
yuvilio about 9 yearsThis is pretty handy on the template end. Can have an empty template to safely do nothing when tempate is not there
{% include ['page_detailed.html', 'page.html', 'empty-catch-all.html'] %}
-
Radhakrishna over 7 yearsIs there a way to include the template if already not exists only ?
-
aalaap over 7 yearsI can't imagine a situation where this would be useful, but it's still a very interesting thing to know of.
-
Admin over 7 yearsit is in cases of dynamically loaded templates. Like if you want to include a specific template by a given name and this template with that name doesnt exist and you don't want a 500 come up than this is a possible option
-
Michael about 7 yearsThanks - using this to load in templates dynamically as per comment above.
-
dezlov about 6 yearsDo you have any reference to support your statement that the
templating
service will be removed in future Symfony versions? -
Bizmate over 5 yearsin the way i have seen with latest flex you dont need the @App reference, if the templates are in their default location just the relative path is enough ie i have templates/Email/campaign.html.twig and @App/Email/campaign.html.twig does not work just Email/campaign.html.twig works
-
Nico Haase over 5 yearsIt should be reference enouhh that Javier is working for SensioLabs ;)
-
rrehbein about 5 yearsAn announcement about deprecating templating: symfony.com/blog/…
-
Anyone about 5 yearsThis is no longer the recommended answer, please check javiers answer below.
-
ali6p almost 4 yearsThis works for Symfony 3.4.*
$this->container->get('templating')->exists('@YourBundle/..Path../twigName.html.twig')
if there is not$this->container
use$this->getContainer()->...
instead.