Access parent template from overridden version in symfony / twig

I have a third-party package OriginalBundleand I want to customize some of its templates.

To do this, I installed the Symfony package MyCustomBundleusing 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';
    }
}

Then I use MyCustomBundle to create versions of some Twig templates from the original package. However, I would like to be able to access the original template from my version (for example, extend it) and just overload 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 assume this causes some recursion as Symfony routes the call extendsback to the configured file?

:

{# OriginalBundle:Foo:bar.html.twig #}

{% block abc %}
    {% block xyz %}
        {# ... code in here ... #}
    {% endblock %}
{% endblock %}

, ...

- , ?

Twig/template parent::doSomething().

, , .

+4
7

. Symfony . , . "!" .

{% extends '!OriginalBundle:Foo:bar.html.twig' %}

{% block xyz %}
    {# ... code in here ... #}
{% endblock %}

app/Resources/OriginalBundle/views/Foo/bar.html.twig

, :

<?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;
        }
    }
}

app/AppKernel.php

class AppKernel extends \Webility\Bundle\WebilityBundle\HttpKernel\Kernel
+6

xyz , FooController,

{{ parent() }}

, , - , .

+3

:

{# MyCustomBundle:Foo:bar.html.twig #}

{% block xyz %}
    {# ... code in here ... #}
{% endblock %}

?

+3

, "extends" , a), /Resources/original -bundle/views/layout.html.twig / /Resources/original -bundle/views/Foo/bar.html.twig, , ( ), ''

, b): , ( "" )

, b

+2

, ... a) b,

+1

. :

- . . , . , .

, .

: , . - - , - ...

+1

, Symfony OriginalBundle ChildBundle , .

, :

{% extends "@Original/Foo/bar.html.twig" %}

:

{% extends "OriginalBundle:Foo:bar.html.twig" %}

Twig FilesystemLoadersplits the reference string into the namespace (original) and the path (Foo / bar.html.twig). A namespace is the name of your package without the Bundle suffix. The full path for each namespace is resolved by combining by default <bundle_path>/Resources/views/with the provided outline .

+1
source

All Articles