Oldek
Oldek

Reputation: 2779

Symfony2 set default view variables

I want to set some variables for all views, is this possible?

I guess I need to do some kind of bootstrap method.

But what I want to achieve is, when I return an array from a function, so that it loads the template. Using a default set up of Symfony2.

Then I would like to append some variables that I will access by Javascript.

For example I always want there to be a user object, so I want it to appear in the layout like

var user = {{user | json_encode()}}

And this would then be accessible in javascript. However I do not want to set this variable in each controller I create, I want to add that to all controllers. I would appreciate some help here. I have found the bundle php file, but I don't know if that one will help me.

Upvotes: 2

Views: 1982

Answers (3)

Paul Andrieux
Paul Andrieux

Reputation: 1847

I think you could use Twig Globals to get this feature. Try to add this in your Namespace\DefaultBundle\NamespaceDefaultBundle.php:

class MyBundle extends Bundle
{
    public function boot()
    {
        $fooBar = 'foobar';
        $this->container->get('twig')->addGlobal('foo_bar', $fooBar);
    }
}

This way the var {{ foo_bar }} will be available in all your twig templates.

Upvotes: 2

Oldek
Oldek

Reputation: 2779

I did get somewhere,

I managed to set up this abstract controller, I placed it in my default controller folder

<?php
namespace Namespace\DefaultBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\StreamedResponse;

class AbstractController extends Controller
{
    /**
     * Returns a rendered view.
     *
     * @param string $view       The view name
     * @param array  $parameters An array of parameters to pass to the view
     *
     * @return string The rendered view
     */
    public function renderView($view, array $parameters = array())
    {
        $parameters = array_merge_recursive($parameters, $this->getDefaultSettings());

        return parent::renderView($view, $parameters);
    }

    /**
     * Renders a view.
     *
     * @param string   $view       The view name
     * @param array    $parameters An array of parameters to pass to the view
     * @param Response $response   A response instance
     *
     * @return Response A Response instance
     */
    public function render($view, array $parameters = array(), Response $response = null)
    {
        $parameters = array_merge_recursive($parameters, $this->getDefaultSettings());

        return parent::render($view, $parameters, $response);
    }


    /**
     * Streams a view.
     *
     * @param string           $view       The view name
     * @param array            $parameters An array of parameters to pass to the view
     * @param StreamedResponse $response   A response instance
     *
     * @return StreamedResponse A StreamedResponse instance
     */
    public function stream($view, array $parameters = array(), StreamedResponse $response = null)
    {
        $parameters = array_merge_recursive($parameters, $this->getDefaultSettings());

        return parent::stream($view, $parameters, $response);
    }

    public function getDefaultSettings()
    {
        $settings = array();

        if ($this->getUser()) {
            # Just exports to an array
            $settings['user'] = $this->getUser()->export();
        }

        $settings['locales'] = array(
            array(
                'label' => 'English',
                'code' => 'en-us'
            ),
            array(
                'label' => 'Swedish',
                'code' => 'sv-se'
            )
        );

        return array(
            "settings" => $settings
        );
    }
}

Then I added this AbstractController to my actual controller:

<?php

namespace Namespace\DefaultBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Response;
class DefaultController extends AbstractController
{
    /**
     * @Route("/", name="home")
     */
    public function indexAction()
    {

        return new Response($this->renderView("NamespaceDefaultBundle:Default:index.html.twig"));
    }
}

However this does not work when I do @Template() in my docblock. As it is not using the parent class. So it needs some more work, but it does what I wanted.

Then in the layout.html.twig I got the following:

<script type="text/javascript">
    var settings = {{ settings | json_encode() | raw }};
</script>

Upvotes: 0

BENARD Patrick
BENARD Patrick

Reputation: 30975

If you don't want to init in the controller, you can create a twig function who return it.

This way is call "extending Twig" : http://twig.sensiolabs.org/doc/advanced.html

Special Symfony2 : http://symfony.com/doc/current/cookbook/templating/twig_extension.html

It will do something like

var myJsvar = "{{ myfunction() }}";

Upvotes: 1

Related Questions