0

I have this

base.html.twig

<html>
  {% block template_scope_vars %}
  {% endblock %}
  <head></head>
  <body>
    {% block content %}
    {% endblock %}
  </body>
</html>

user.html.twig

extends base...
{%block template_scope_vars %}
   {% set test= "bippo" %}
{%endblock%}

{%block content %}
   {{ test }}
{% endblock %}

Error

Variable "test" does not exist

Ok please please don't tell me that I don't have to use blocks for this, the use case is more difficult than this simple example obviously. The idea is that test gets available in the base.html.twig as well, as well as any sub-templates of it that I might be using in future

12
  • 1
    Not going to work the way you want it to. Blocks are pretty much independent. Commented May 21, 2014 at 0:11
  • @Cerad well that sucks big time. Is there something similar I could use? or some workaround? Commented May 21, 2014 at 0:21
  • Inject the variable as a twig global. Commented May 21, 2014 at 0:58
  • @Cerad that is like shooting a pigeon with a nuclear bomb. Besides, it doesn't solve basic use cases where you have to do just a tiny bit of logic. Hmm a real big shortcoming which makes this templating mechanism a lot weaker than say, JSF from java Commented May 21, 2014 at 1:12
  • @Cerad looking at this: twig.sensiolabs.org/doc/tags/include.html probably I can create a new twig, where I only write {% set test="foobar" %} {% include 'user.html.twig' %} reading the doc, this should work. But I have to create a new file, which is stupid Commented May 21, 2014 at 1:26

2 Answers 2

0

for the special use case I had I could use this. It is a shame though, there is no neater solution. All other solution I could come up with, would require to create a new file for each set of template scope variables. Which plain sucks

base.html.twig

<div id="menu"> //this is like a sidebar menu
                    <div class="menuitem  {% block foo %}{% endblock %}">
                    <a href="{{ path('MyBundle_my_routing_name_foo' }}">Foo</a>
                </div>
                    <div class="menuitem  {% block bar %}{% endblock %}">
                    <a href="{{ path('MyBundle_my_routing_name_bar' }}">Bar</a>
                </div>
<div>
{% block content %}
{% endblock %}

Then in

foo.html.twig

{% extends "MyBundle::base.html.twig" %}

{% block foo %}active{% endblock %}

{% block content %}
Some content specific for foo
{% endblock %}

bar.html.twig

{% extends "MyBundle::base.html.twig" %}

{% block bar%}active{% endblock %}

{% block content %}
Some content specific for bar
{% endblock %}

and then you set the css for the background of e.g.

CSS

menuitem.active {
background-color: red;
}
Sign up to request clarification or add additional context in comments.

Comments

0

base.html.twig

<div id="menu"> //this is like a sidebar menu
    <div class="menuitem{{ active == 'foo' ? ' active' : '' }}">
        <a href="{{ path('MyBundle_my_routing_name_foo') }}">Foo</a>
    </div>
    <div class="menuitem{{ active == 'bar' ? ' active' : '' }}">
        <a href="{{ path('MyBundle_my_routing_name_bar') }}">Bar</a>
    </div>
<div>
{% block content %}
{% endblock %}

foo.html.twig

{% extends "MyBundle:Whatever:base.html.twig" %}

{% block content %}
    {{ content }}
{% endblock %}

Controller

/**
 * @Route("/foo", defaults={"param" = null}, name="foo")
 * @Route("/foo/{param}", name="foo_with_param")
 * @Template()
 */
public function fooAction($param)
{
    // This would really be getting data from the Model
    if ($param == 'something') {
        $content = 'Some content';
        $active = 'foo';
    } else {
        $content = 'Different content';
        $active = 'bar';
    }

    return array(
        'content'=> $content,
        'active' => $active,
    );
}

When rendering foo.html.twig, base.html.twig will get the variable "active".

7 Comments

@Toskan Which part? The annotations? At any rate, it's all in the symfony docs. I won't insult your intelligence by posting a link to them. You should probably set active once at the top of base.html.twig (In case it's not passed) E.g.: {% set active = active|default(false) %}, then you can shorten the other code a bit. {{ active == 'foo' ? ' active' : '' }}
in case you get several return statements, e.g. redirects after persisting or after failed checks, you'll end up copy pasting this return array all over the place.
@Toskan I don't think you get it. You HAVE to send data to the template. That's the whole point of MVC.
feel free to explain why you have to send this data to the template. Does this ever change when the template does not change? Does it need to be controlled? No. This is template styling, nothing else. Template styling should not be part of the controller.
@Toskan You talk about DRY, and then you say you want to create new almost identical template file for every active menu item? That is completely insane. foo.html.twig, bar.html.twig, baz.html.twig, etc. You just need one twig template for the menu and even just one controller that tells the template which menu item to highlight (among all of the other data that will be passed to it anyway).
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.