Twig Variable in External Js File

Twig variable in external JS file

There a two approaches when you need to pass a twig variable to an external javascript file

  1. Define the variables inside a script block in the twig template
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<script>
var my_twig_var = {% if twig_var is defined %}'{{ twig_var }}'{% else %}null{% endif %}
</script>
<script src="scripts/functions.js"></script>
</body>
</html>

For this approach I usally add a block called "javascript" block in my main/base template

base.twig.html

<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
{% block body %}
{% endblock %}
{% block javascript %}
{% endblock %}
</body>
</html>

page.html.twig

{% extends base.twig.html %}
{% block body%}
<h1>Hello World</h1>
{% endblock %}
{% block javascript %}
<script>
alert('{{ twig_var|default('Hello World') }}');
</script>
{% endblock %}



  1. Pass the variables to javascript with the aid of data-* attributes
<div data-foo="{{ foo }}">...</div>
$(function() {
$(document).on('click', '.button', function(e) {
console.log($('div[data-foo]').data('foo'));
});
});

Sidenote: if you want to pass an object or an array to twig you can always use the json_encode filter, which will convert the variable to a valid javascript object

If you want to have control over which object properties are exposed by the json_encode filter you can always implement the interface Serializable

Use Twig variables in external js file

You can use two tricks for this.

a. Use classes or specific attributes in your form elements, and access to them with global selectors.

<?php

namespace App\Form;

class MyForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add("descriptionText", null, [
"attr" => [ "class" => ["trumbowygable"]],
...
]) ;

... or ...

$builder->add("otherField", null, [
"attr" => [ "data-other-thing" => 1]],
...
])

}
}

And JS looks like ...

$('input.trumbowygable').trumbowyg(trumbowyg_config);
// or
$('input[data-other-thing]').on("someEvent", bla bla bla);

b. Create a global javascript function that receive id elements by parameters.

function buildTrumbowyg(id_one, id_two) {
$('#' + id_one).blaBlaBla( ... )
}

How can I use javascript code in an external file with twig elements?

First of all (as the comments already said) it is not a good idea to mix JavaScript with Twig.

  • Makes your code hard to maintain, hard to read and hard to understand
  • Syntax errors and JavaScript errors might happen quite easily
  • Probably messes up syntax highlighting in IDEs
  • etc.

How to improve this situation? Obviously you have the variable output. You might do the following in your main file:

var output = {{ output|json_encode() }};

Within script.js you might do something like:

$(document).ready(function () {

let options = { "repsonsive": true };

if(output.json === true) {
options.serverSide = true;
options.ajax = { ... }
} else {
options.data = output.data
}
var table = $('.datatable').DataTable(options);
});

Use this process of refactoring also to clean and restructure your code and especially keep JavaScript and CSS seperated from the Twig files as good as possible.

Pass variable from twig to js

Assign the variable in the template and pick it up with javascript...

<script>
var foo = '{{ foo }}';
alert(foo);
</script>

Call js function from external file Symfony Twig

I hope everyone is doing great during this troubles times ! France started containment last week so I had plenty of time finding the solution.

Dumbest thing ever but I didn't know that..

In your js external files, you have to declare your functions like this :

window.myfunction = function myfonction(){}

That's all..

Could that potentialy cause security issues ? I don't know so I'm asking xD

How to make twig globals accessible in javascript library

I used a bad example above. I was using in my html something more like

<div id="twig-vars" data-newRoute="{{ URL_Symfony_dev }}"></div>

And so the js was :

var test= $('#twig-vars').data('newRoute');
alert(test);

Which didn't work. But the problem (camel case in names) couldn't be detected with the example i gave. My apologies
I noticed it after some rewording with data-test worked so i ended up with this in the html.

<div id="twig-vars" data-newroute="{{ URL_Symfony_dev }}"></div>

And in my JS:

var test= $('#twig-vars').data('newroute');
alert(test);

And THAT WORKS.
I am new to this place and i dont know if i should edit the original question. Any help for it also appreciated.

EDIT: Using class(.) instead of id(#) will only capture the first html even if the attribute name is different. This means:

<div **class**="twig-vars" data-**test1**="{{ URL_Symfony_dev }}"></div>
<div **class**="twig-vars" data-**test2**="{{ URL_Symfony_dev }}"></div>
<div **class**="twig-vars" data-**test3**="{{ URL_Symfony_dev }}"></div>

var test1= $('.twig-vars').data('test1');
var test2= $('.twig-vars').data('test2');
var test3= $('.twig-vars').data('test3');
alert(test1);//output-> correct result
alert(test2);//output-> undefined
alert(test3);//output-> undefined


Related Topics



Leave a reply



Submit