13

What do I need to do to get twig to process a JavaScript file? I have an html.twig that uses a JavaScript twig. Something like this:

{% extends 'BaseBundle::layout.html.twig' %}

{% block javascripts %}
    {{ parent() }}
    {% javascripts
        '@BaseBundle/Resources/js/main.js.twig'
    %}
    {% endjavascripts %}
{% endblock %}

< more template omitted >

And parts of main.js.twig:

function testFunction()
{
    alert('{{VariableFromPHP}}');
}

And the controller:

/**
 * @Route("/",name="home")
 * @Template("MyBundle:Default:index.html.twig")
 */
public function indexAction()
{
   return array( 'VariableFromPHP' => 'Hello World');
}

I expected the JavaScript to look like this at run-time:

alert('Hello World');

But, the code is unchanged. Any ideas what I am doing wrong?

Thanks, Scott

3 Answers 3

18

My sugestion to use global variables:

{% javascripts '@AcmeBundle/Resources/public/js/*' output='js/compiled/main.js'%}
        <script>
            var TWIG = {};
            TWIG.variableOne   = "{{ path('rote_to_nowhere') }}";
            TWIG.variableTwo   = "{{ helloworldVar }}";
            TWIG.variableThree = "{{ "something"|trans }}";
        </script>
        <script type="text/javascript" src="{{ asset_url }}"></script>
{% endjavascripts %}

then you can use it in your js file:

alert(TWIG.variableTwo);
Sign up to request clarification or add additional context in comments.

3 Comments

This is perfect for what what I need, routes generated for use in ajax queries.
Possibly using var TWIG = TWIG || {};, especially when you are planning on using this twice.
@LaytonEverson The FosJsRoutingBundle can help you with that
12

Assetic does not include twig templates; you should create a separate controller for the javascript file. Although I would consider it bad practice performance-wise, because you will have to process two requests this way.

/**
 * @Route("/main.js")
 */
public function mainJsAction() {
    $params = array( 'test' => 'ok' );
    $rendered = $this->renderView( 'MyBundle:Default:main.js.twig', $params );
    $response = new \Symfony\Component\HttpFoundation\Response( $rendered );
    $response->headers->set( 'Content-Type', 'text/javascript' );
    return $response;
}
{% extends 'BaseBundle::layout.html.twig' %}

{% block javascripts %}
    {{ parent() }}
    <script type="text/javascript" src="{{ path('my_default_mainjs') }}"></script>
{% endblock %}

An alternative is to dump dynamic variables in the html, and only use static javascript files.

Comments

1

Instead, what I did is this in the main.js:

function doGetStringFromSubClass()
{
    if (typeof getStringFromSubClass == 'function')
    {
        return getStringFromSubClass();
    }
    else
    {
        alert('getStringFromSubClass() needs to be defined.')
    }
}

function testFunction()
{
    alert(doGetStringFromSubClass());
}

and, in the subclass twigs, we have this main.js:

function getStringFromSubClass(){
    return "baseClassString";
    }

And this twig:

{% extends 'BaseBundle:Default:index.html.twig' %}

{% block javascripts %}
    {{ parent() }}

    {% javascripts
        '@SomeSubclassBundle/Resources/js/main.js'
    %}

    <script type="text/javascript" src="{{ asset_url }}"></script>
    {% endjavascripts %}
{% endblock %}

Kinda goofy, but, it works.

Scott

Comments

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.