NB: i´m using Twig in a non-Symfony context.
I want to register a master layout that all templates should inherit, so that i don´t have to forget to preface them with:
{% extends 'layout.html.twig' %}
I know i have seen this somewhere, and Symfony makes use of it.
It is possible!
After some experimenting i came up with this solution:
{# index.html.twig #}
{% block title %}Hello world{% endblock%}
Wrap global layout in a block:
{# layout.html.twig #}
{% block layout %}
<html>
<head>
<title>{% block title %}{% endblock%}</title>
</head>
<html>
{% endblock %}
Pass child template to twig:
// index.php
...
$twig->display(array('template'=>'index.html.twig'));
...
Inject child template via a proxy template:
{# proxy.twig #}
{% extends 'layout.html.twig' %}
{% block layout %}
{# Get extended block #}
{{ parent() }}
{# inject template into master layout #}
{% include template %}
{% endblock %}
Related
I am writing PHPUnit test and I am trying to test if my twig view is rendered correctly.
$expected='<html>
<p>The status of user!</p>;
</html>'
self::bootKernel();
$twig = self::$kernel->getContainer()->get('twig');
$actual = $twig->render('user-test.html.twig');
$this->assertEquals($expected, $actual);
But user-test.html.twig by default extends 'base.html.twig which is not needed in this test case.
Like:
{% extends 'base.html.twig' %}
<html>
<p>The status of user!</p>;
</html>
Is there a way I could mock base.html.twig template and test just user-test.html.twig without it throwing an error?
I think you have an error in your template because if you are extending another template all your HTML code needs to be in {% block blockname %}...{% endblock %} tags with blockname block defined in base.html.twig.
{# user-test.html.twig #}
{% extends 'base.html.twig' %}
{% block main %}
<html>
<p>The status of user!</p>;
</html>
{% endblock %}
Maybe what you can do is you can make another template with that part you need to check and include it.
{# user-test.html.twig #}
{% extends 'base.html.twig' %}
{% block main %}
{% include '_user-test.html.twig' %}
{% endblock %}
{# _user-test.html.twig #}
<html>
<p>The status of user!</p>;
</html>
And then test _user-test.html.twig that renders only what you want.
I'm working with Symfony and Twig and I can't find solution for the next problem:
in my parent template (index.html.twig) I have such code:
<noscript>
{% block noscript %}
<div class="alert alert-warning">
<strong>{% block notice %}{{ notice_js_disabled }}{% endblock %} </strong>
{% block message %}{{ js_disabled }}{% endblock %}
</div>
{% endblock %}
</noscript>
I have child template (category.html.twig) which extends index.html.twig template.
Can I pass value of {{ notice_js_disabled }} var from index template to category template?
notice_js_disabled is returned from my Symfony indexAction controller.
UPD:
The solution for my problem I founded, next:
I have made base templae, called main.html.twig, where I'm rendering element from the controller:
{% block header %}
{{ render(controller('StoreBundle:Header:index')) }}
{% endblock %}
Then, on my index.html.twig file, I made next things:
{% extends 'Store/tpl/main.html.twig' %}
{% block title %}{{ title }}{% endblock %}
{% block content %}
<p class="currentPage" hidden>home</p>
{{ parent() }}
{% endblock %}
I'm not sure is it correct solution, but it's work:)
The only way in Twig you can pass some variable to a child template is by the include tag.
{# template.html will have access to the variables from the current context and the additional ones provided #}
{% include 'template.html' with {'foo': 'bar'} %}
{% set vars = {'foo': 'bar'} %}
{% include 'template.html' with vars %}
However in this way you are not extending some parent template from the child, but you are doing the other way around: you are placing a submodule into the current template.
There are only a couple of variables which are global in symfony
You can set some custom global variables in configuration like described here
Otherwise you can use some predefined global variables, the app variable. (check it out here)
My personal advice is that you should review your application template logic.
Hope it helps!
What you have to do is the following:
-Create A variable in the parent template
{% set notice_js_disabled = value_received_from_indexAction %}
After the template that you need that value
{{ notice_js_disabled }}
I hope it helps you
I have some twigs that are embedded in base twig. Embedded twigs contain blocks that I'd like to override in other twigs, which extend base. This changes are not showing. I saw similar questions, but couldn't deduce the answer from that.
For example in base twig:
<body>
<div id="wrapper">
{% embed 'Bundle::sidebar.html.twig' %}{% endembed %}
</div>
</body>
Sidebar twig contains the block that should be overridden:
<div>Some content here</div>
{% block example_block %}
Content of a block
{% endblock %}
Twig that extends the base:
{% extends 'Bundle::base.html.twig' %}
{% block example_block %}
I want different content here
{% endblock %}
Based on the Docs on embed http://twig.sensiolabs.org/doc/tags/embed.html I think this should work…
Base Twig Template:
<body>
<div id="wrapper">
{% block sidebar %}
{% embed 'Bundle::sidebar.html.twig' %}{% endembed %}
{% endblock %}
</div>
</body>
Twig that extends base:
{% extends 'Bundle::base.html.twig' %}
{% block sidebar %}
{% embed "Bundle::sidebar.html.twig" %}
{# This block is defined in "sidebar.html.twig" #}
{# and we override it right here: #}
{% block example_block %}
I want different content here
{% endblock %}
{% endembed %}
{% endblock %}
If you declare a sidebar block in the base template, then override it in the extended file, declaring the embed again and the blocks you want to override.
I have splitted my layout and templates to few partials, mostly because of old Symfony1 habits.
file layout.html.twig:
...
<body>
{{ include("ABCBundle:Partials:breadcrumbs.html.twig") }}
{% block body %}{% endblock %}
</body>
...
file breadcrumbs.html.twig
<div class="abc">
{% block breadcrumbs %}
Home
{% endblock %}
</div>
file show.html.twig
{% extends "ABCBundle::layout.html.twig" %}
{% block breadcrumbs %}
{{ parent() }}
abc
{% endblock %}
{% block body %}
(something something)
{% endblock %}
Funny thing is, when I render show.html.twig, I can put data into body block, and everything works fine, but I can't do anything with breadcrumbs block. Whatever I do - write something inside that block or call parent(), nothing happens, only content from breadcrumbs.html.twig is being rendered. There's also no error about calling parent() and any other error related to extending block.
I think you should use {% include "..." %} rather than {{ include("...") }}
According to the twig documentation, the {% include %} tag "includes a template and returns the rendered content of that file into the current namespace" where as the include function "returns the rendered content of a template"
(Meaning the include function just returns the rendered content, where the tag adds the content to the current namespace which would include the blocks you defined)
Found the solution.
It looks like you can't extend block included in layout's include, from template extending this layout:
[partial.html.twig] --- [ layout.html.twig ] --- [ template.html.twig ]
{% block abc %} {% include 'partial.html.twig' %} {% extends layout.html.twig %}
{% block abc%} aaa {%endblock %}
You have to perform a little hack, including adding extra content to layout and replacing original block from partial.html.twig with conditional. More here: Overriding blocks within included Twig templates
How can I override a block inside an included template file?
example:
{# layout.html #}
{% include "menu.html" %}
{# menu.html #}
{% block overrideme %}{% endblock %}
{# index.html #}
{% extends "layout.html" %}
{% block overrideme %}Overriden{% endblock %}
I read somewhere that a trait function was implemented? I can't find any documentation about it though, does anyone know how I could make this work?
If you want to override blocks inside a file that you are including then you should 'embed' it rather than 'include' it.
{% embed "menu.html" %}
{% block overrideme %}
Overriden
{% endblock %}
{% endembed %}
See the docs for more details: http://twig.sensiolabs.org/doc/tags/embed.html