I'm trying to intercept either the rendering function or the response to add a variable to it before loading the the view(twig).
I tried to override the default render method but it still gives me
Variable "myvar" does not exist in /path/to/baseAppLite.html.twig at line 10
What's wrong with my code and is there a better way ?
This is my override code in the baseController
public function render($view, array $parameters = array(), Response $response = null)
{
$parameters = array_merge(
$parameters,
array(
'myvar' => 'GlobalVar'
)
);
return parent::render($view, $parameters, $response);
}
Usage
{{ myvar }}
UPDATE: From what I can see is that the render function is not loading because i tried echoing "render bar foo" and nothing shows up
I don't think the render function needs to be overwritten at all to be honest. I can think of a couple of ways that you could get access to some kind of global variable depending on how the global variable is set (or calculated).
Twig Globals
If it is a hardcoded variable then you could add it into your config.yml as one of the twig globals, like so...
# app/config/config.yml
twig:
# ...
globals:
ga_tracking: UA-xxxxx-x
Which can then be used like...
<p>The google tracking code is: {{ ga_tracking }}</p>
As explained here - http://symfony.com/doc/current/cookbook/templating/global_variables.html
Twig Function
Alternatively if you variable is related in some way to an outside service you could use a custom twig function and call that in you template.
The twig extension (with function)..
class AcmeExtension extends \Twig_Extension
{
protected $container;
public function __construct(ContainerInterface $container = null)
{
$this->container = $container;
}
public function getFunctions()
{
return array(
new \Twig_SimpleFilter(
'get_parameter',
array($this, 'getParameter')
),
);
}
public function getParameter($parameter)
{
if (null === $this->container) {
return null;
}
return $this->container->getParameter($parameter);
// You could also do perform some kind of action
// rather than just return a value
}
public function getName()
{
return 'acme_extension';
}
}
Registered as a service..
services:
acme.twig.acme_extension:
class: Acme\DemoBundle\Twig\AcmeExtension
arguments:
- @service_container
tags:
- { name: twig.extension }
And then in your template you could use..
{{ get_parameter('myVar') }}
Or even..
{% set myVar = get_parameter('myVar') %}
To add to my comment I have created this answer (sorry for bad grammar / spelling).
If you want to pass a var in a template that needs to be always there, you can do the following (that's how I do this anyway).
Let's say we have a PageController with CRUD methods (update, delete, show etc etc). Instead of passing that var every time (or by modifying an already defined method), we could do the following: Let Twig 'fetch' the var by rendering a controller action. Twig will call the corresponding controller and will render that variable. Let's pretend that it's a sentence in a footer that needs to be rendered by variable on each page (to keep it simple).
We could write the following action in our PageController:
public function renderFooterAction() {
//Do your logic here, like retrieving the var from the database
//or something completely different.
//It could also be as easy as this:
$myVar = "This is a footer sentence";
//At the end we return a template
return $this->render('AcmeDemoBundle:Page:footer.html.twig', array(
'myVar' => $myVar,
));
}
The footer.html.twig page lives in YourBundle\Resources\views\Page\footer.html.twig. Depending on your needs it could be just like this (you can do everything in here like you can in a regular twig template, we're keeping it simple and only 'echoing' the variable):
{{ myVar }}
In your main template you can use the following piece of code: {{ render(controller('AcmeDemoBundle:Page:renderFooter')) }}
You can also pass parameters inside your template along if you need to when rendering a piece of it, like:
{{ render(controller('AcmeDemoBundle:Page:footer', { 'maxArticles': 5 })) }}
The above thing is assuming you want to do a for loop in the template the controller renders.
As you can see, rendering a controller in a template is almost like rendering a 'normal' view, instead of returning a whole template, you just create smaller files with only the controller responsible output.
Hope this explanation helped you a bit :) Of course, if you're still confused, just ask for more clarity.
edit: It should also be possible to directly return the variable (I think), but can't remember that so quickly. Will add that if I can find it :)
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