Search code examples
phpvue.jssymfonytwig

Passing Twig variables to Vue.js in Symfony


I am running Symfony 4 app with Vue.js enabled. Is there any good practice to send my data from Twig templates to Vue.js components? Currently I have a number of data items for example on my header component, and HTML element data section looks like this:

<header-nav class="headnav headnav-fixed z-depth-1"
            logo="{{ asset('build/images/site_logo.png') }}"
            username="{{ app.user.name }}"
            logout-url="{{ path('logout') }}"
            logout-title="{% trans %} Logout {% endtrans %}"
            instruction-url="{{ path('system_instruction_download') }}"
            instruction-title="{% trans %} Download instruction {% endtrans %}"
            current-locale="{{ app.request.getLocale()|upper }}"
            v-bind:locales="{{ locales|json_encode }}"
>

Let's say I have a number of different URL's and other stuff. What is the best way to send the data? Should I first prepare an array of URL's on my controller? Which controller should it be if I want to prepare some global variables which will be used on my header, so they shouldn't be locked only on one controller.


Solution

  • Assuming that you render multiple "vue applications", you can define global variables with

    1) twig configuration

    Documentation says: "Twig allows to inject automatically one or more variables into all templates. These global variables are defined in the twig.globals option inside the main Twig configuration file"

    2) You could create abstract controller with function merging variables

    // MyAbstractController.php
    protected function getTwigVariables(array $vars) { 
        $globals = [];
        // ... fill $globals with your stuff
        return array_merge(['globalVar1' => ], $vars);
    }
    
    // TestController extends MyAbstractController
    public function indexAction() {
        //...
        return $this->render('viewPath.html.twig', $this->getTwigVariables([
            'specificVariable' => 'variableContent'
        ]));
    }
    

    You could also embed controllers inside your main twig. You can create headerAction, footerAction etc. and create subrequest for this actions.

    For storing variables you can also use script tags

    // twig
    <script id="serverJson" type="application/json">{{ jsonContent|json_encode()|raw }}</script>
    
    // serverJson.js
    const configElement = document.getElementById("serverJson");
    export default JSON.parse(configElement.innerHTML);
    
    // ViewTemplate.vue
    import serverJson from "path-to-serverJson.js"