Skip to content

[TwigBundle] Improve the overriding of bundle templates #24264

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 29, 2017

Conversation

yceruto
Copy link
Member

@yceruto yceruto commented Sep 19, 2017

Q A
Branch? 3.4
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets #17557
License MIT
Doc PR -

Overriding a Template that also extends itself

Now that bundles inheritance is deprecated and removed (#24160, #24161), I'm wondering if we can solve this old issue defining an exclusive namespace only for root bundles in 3.4 just bundles in 4.0:

twig:
    paths:
        # adding paths behind the scene into TwigExtension
        app/Resources/FooBundle/views: Foo
        vendor/acme/foo-bundle/Resources/views: Foo
        vendor/acme/foo-bundle/Resources/views: !Foo # exclusive

Thus, one can decide when use the exclusive namespace to avoid the issue and then we could say also:

To override the bundle template partially (which contains block) creates a new index.html.twig template in app/Resources/AcmeBlogBundle/views/Blog/index.html.twig and extends from @!AcmeBlogBundle/Blog/index.html.twig to customize the bundle template:

{# app/Resources/FooBundle/views/layout.html.twig #}

{# this does not work: circular reference to itself #}
{% extends '@Foo/layout.html.twig' %}

{# this will work: load bundle layout template #}
{% extends '@!Foo/layout.html.twig' %}

{% block title 'New title' %}

I hear other suggestions about the excluse namespace.

We will need to update http://symfony.com/doc/current/templating.html#referencing-templates-in-a-bundle too to add this convention.

WDYT?

@yceruto
Copy link
Member Author

yceruto commented Sep 25, 2017

I just updated the description to clarify the proposal, it's not about Bundle suffix but bundle class name instead. So, you have a bundle named AcmeBlogBundle? you will have two namespaces for their templates: @AcmeBlog and @AcmeBlogBundle. The last one is specially useful when you're overriding a template that also extends itself, without configure twig.paths manually.

At the same time, you can from a controller or anywhere to load directly the template of the bundle or the overridden one in your app, without create extra templates or extra configuration to achieve it.

@yceruto
Copy link
Member Author

yceruto commented Sep 27, 2017

Feat. freeze is coming :) also we can use some preffix or suffix to achieve it, WDYT?

ping @fabpot, @javiereguiluz

@javiereguiluz
Copy link
Member

I don't dislike the idea ... but I'm not sold on it either. My concern is that you'll have two almost identical namespaces that are completely different: @FOSUser, @FOSUserBundle ... which one should I use? I already have a lot of problems remembering if the namespace contains the Bundle suffix or not. If I see @TwigBundle/... in a template, I don't think I'll remember that it refers to the original template path of the parent bundle.

@yceruto
Copy link
Member Author

yceruto commented Sep 27, 2017

Other proposal that is easy to remember?

  • !FOSUser
  • FOSUser!
  • FOSUserSource
  • FOSUserOriginal
  • FOSUserParent
  • FOSUserBundle

This namespace should be used only to avoid the circular reference.

@xabbuh
Copy link
Member

xabbuh commented Sep 27, 2017

I share @javiereguiluz' concerns though I also do not have a better proposal.

@javiereguiluz
Copy link
Member

Some random proposals:

{% extends 'parent@Foo/layout.html.twig' %}

{% extends '@@Foo/layout.html.twig' %}

{% extends '@Foo/layout.html.twig', { parent: true } %}

@yceruto
Copy link
Member Author

yceruto commented Sep 27, 2017

@javiereguiluz only the second one @@Foo can be possible right now as valid Twig namespace, I'll take your proposal, thanks.

@yceruto
Copy link
Member Author

yceruto commented Sep 27, 2017

It's not intuitive anyway, so we need document it.

Copy link
Contributor

@ogizanagi ogizanagi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but my own preference would actually be

{% extends '@!Foo/layout.html.twig' %}

@xabbuh
Copy link
Member

xabbuh commented Sep 28, 2017

@ogizanagi's suggestion sounds good to me too.

@yceruto
Copy link
Member Author

yceruto commented Sep 28, 2017

Perfect! I like this too, changed to ! preffix :)

@yceruto yceruto force-pushed the template_inheritance branch from 52ddda0 to 0a658c6 Compare September 28, 2017 18:35
@fabpot
Copy link
Member

fabpot commented Sep 29, 2017

Thank you @yceruto.

@fabpot fabpot merged commit 0a658c6 into symfony:3.4 Sep 29, 2017
fabpot added a commit that referenced this pull request Sep 29, 2017
…s (yceruto)

This PR was merged into the 3.4 branch.

Discussion
----------

[TwigBundle] Improve the overriding of bundle templates

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #17557
| License       | MIT
| Doc PR        | -

### [Overriding a Template that also extends itself](https://twig.symfony.com/doc/2.x/recipes.html#overriding-a-template-that-also-extends-itself)

Now that bundles inheritance is deprecated and removed (#24160, #24161), I'm wondering if we can solve this old issue defining an exclusive namespace only for root bundles in `3.4` just bundles in `4.0`:
```yaml
twig:
    paths:
        # adding paths behind the scene into TwigExtension
        app/Resources/FooBundle/views: Foo
        vendor/acme/foo-bundle/Resources/views: Foo
        vendor/acme/foo-bundle/Resources/views: !Foo # exclusive
```
Thus, one can decide when use the exclusive namespace to avoid the issue and then [we could to say also](http://symfony.com/doc/current/templating/overriding.html):

> To override the bundle template partially (which contains `block`) creates a new `index.html.twig` template in `app/Resources/AcmeBlogBundle/views/Blog/index.html.twig` and extends from `@!AcmeBlogBundle/Blog/index.html.twig` to customize the bundle template:

```twig
{# app/Resources/FooBundle/views/layout.html.twig #}

{# this does not work: circular reference to itself #}
{% extends '@Foo/layout.html.twig' %}

{# this will work: load bundle layout template #}
{% extends '@!Foo/layout.html.twig' %}

{% block title 'New title' %}
```
I hear other suggestions about the excluse namespace.

We will need to update http://symfony.com/doc/current/templating.html#referencing-templates-in-a-bundle too to add this convention.

WDYT?

Commits
-------

0a658c6 Add exclusive Twig namespace for bundles path
@yceruto yceruto deleted the template_inheritance branch September 29, 2017 01:34
@nicolas-grekas
Copy link
Member

nicolas-grekas commented Sep 29, 2017

@yceruto or anyone else with some free time: I broke tests when merging this into master, could you have a look please?

@yceruto
Copy link
Member Author

yceruto commented Sep 29, 2017

@nicolas-grekas Still broken?

@nicolas-grekas
Copy link
Member

yes

@yceruto
Copy link
Member Author

yceruto commented Sep 29, 2017

The code in master look good to me:

if ($paths) {
// the last path must be the bundle views directory
$twigFilesystemLoaderDefinition->addMethodCall('addPath', array($path, '!'.$namespace));
}

and Travis pass (at least for TwigBundle):

taken from https://travis-ci.org/symfony/symfony/builds/281245817

@nicolas-grekas
Copy link
Member

Oh nice sorry, I didn't break it because if this PR, but another one, NVM :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants