I have a third party bundle OriginalBundle
and I want to customise some of the templates in it.
To achieve this, I have set up a Symfony bundle MyCustomBundle
using the override method shown in the Symfony docs.
<?php
namespace My\CustomBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class MyCustomBundle extends Bundle
{
public function getParent()
{
return 'OriginalBundle';
}
}
I am then using MyCustomBundle to create over-ride versions of some Twig templates from the OriginalBundle. However, I would like to be able to access the original template from my version (e.g. extend it) and just over-ride some of the blocks.
But, if I try to do something like this:
{# MyCustomBundle:Foo:bar.html.twig #}
{% extends 'OriginalBundle:Foo:bar.html.twig' %}
{% block xyz %}
{# ... code in here ... #}
{% endblock %}
Then I get a white screen of death. I'm guessing it causes a recursion of some kind since Symfony is routing the extends
call back to the customised file?
The original bundle's template looks like this:
{# OriginalBundle:Foo:bar.html.twig #}
{% block abc %}
{% block xyz %}
{# ... code in here ... #}
{% endblock %}
{% endblock %}
So the question...
is there any way to access the original template file when an over-ridden version of the same template exists?
I'm basically looking for the Twig/template equivalent of parent::doSomething()
.
Without this kind of access to the parent I find myself copying the entire original template file verbatim then updating a small part of it, which just feels wrong.
There is a solution. Symfony by default search for first matching resource and returns it. To change this behaviour you need to specify some additional syntax. I use "!" to reach second match.
{% extends '!OriginalBundle:Foo:bar.html.twig' %}
{% block xyz %}
{# ... code in here ... #}
{% endblock %}
Overriding file could be in app/Resources/OriginalBundle/views/Foo/bar.html.twig
To activate this system you need to override original Kernel to:
<?php
namespace Webility\Bundle\WebilityBundle\HttpKernel;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
abstract class Kernel extends BaseKernel
{
public function getBundle($name, $first = true)
{
$get_next = false;
if($name[0] == '!' && $first){
$name = substr($name, 1);
$first = false;
$get_next = true;
}
$bundles = parent::getBundle($name, $first);
if($get_next){
return isset($bundles[1]) ? $bundles[1] : $bundles[0];
} else {
return $bundles;
}
}
public function locateResource($name, $dir = null, $first = true)
{
$get_next = false;
if($name[0] == '@' && $name[1] == '!' && $first){
$name = '@'.substr($name, 2);
$first = false;
$get_next = true;
}
$files = parent::locateResource($name, $dir, $first);
if($get_next){
return isset($files[1]) ? $files[1] : $files[0];
} else {
return $files;
}
}
}
And use it in app/AppKernel.php
class AppKernel extends \Webility\Bundle\WebilityBundle\HttpKernel\Kernel
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With