Load order in Symfony2 assetic for JS files
Asked Answered
C

3

10

I am currently using a bootstrap template that uses a few JS files. To get them to load I placed all the required JS files in the app/Resources/views/base.html.twig file. Here is a snippet of the code:

{% block body %}{% endblock %}
{% block javascripts %}
    {% javascripts '@ABBundle/Resources/public/js/*' %}
    <script type="text/javascript" src="{{ asset_url }}"></script>
    {% endjavascripts %}
{% endblock %}

My code in the child twig file located in AB/ABBundle/Resources/views/Home/show.html.twig has the following code:

{% extends '::base.html.twig' %}
{% block body %}
    blah blah blah normal html code blah blah blah
{% endblock %}

The problem is that when I view this page I get several errors such as "ReferenceError: jQuery is not defined" and "ReferenceError: $ is not defined". This is even though the JS files are included (the names of the JS file are changed as expected).

I found out that the error can be fixed with a rather nasty hack by instead of loading all js files with a single line of code {% javascripts '@ABBundle/Resources/public/js/*' %} I know need to include the js files like this:

{% block javascripts %}
    {% javascripts '@ABBundle/Resources/public/js/jquery.js' %}
    <script src="{{ asset_url }}"></script>
    {% endjavascripts %}

    {% javascripts '@ABBundle/Resources/public/js/jquery.prettyPhoto.js' %}
    <script src="{{ asset_url }}"></script>
    {% endjavascripts %}
{% endblock %}

Is there a way I can force Assetic to load certain JS files first while still using the much shorter: {% javascripts '@ABBundle/Resources/public/js/*' %} option?

Cyanocobalamin answered 21/1, 2014 at 10:57 Comment(2)
No, but you could extend Assetic to to support this, the framework is somewhat lacking a dependency management system for assets.Honeymoon
github.com/RobLoach/component-installer, This should help however.Honeymoon
B
17

You can specify order which files are loaded using different folder structure like this:

{% javascripts '@AcmeFooBundle/Resources/public/js/file1.js' 
               '@AcmeFooBundle/Resources/public/js/file2.js'
               '@AcmeFooBundle/Resources/public/js/folder/*'
%}
    <script type="text/javascript" src="{{ asset_url }}"></script>
{% endjavascripts %}
Bouchier answered 21/1, 2014 at 11:11 Comment(0)
A
4

I do it by naming my .js files in the order I want. Like this:

10_foo.js
20_bar.js
30_baz.js

then I don't need to specify them one by one, I just do as normal:

{% javascripts '@MyBundle/Resources/public/js/*' %}
    <script type="text/javascript" src="{{ asset_url }}"></script>
{% endjavascripts %}

and they are loaded in order.

Now for the main libraries that should be available in every page, I use a base.html.twig template in the app/Resources/view that gets extended in every page with this code in it:

before <body> tag:

{% stylesheets '@MyMainBundle/Resources/public/css/*' %}
    <link rel="stylesheet" href="{{ asset_url }}" />
{% endstylesheets %}
{% block stylesheets %}{% endblock %}

and near the end of <body> tag:

{% javascripts  '@MyMainBundle/Resources/public/js/*' %}
    <script type="text/javascript" src="{{ asset_url }}"></script>
{% endjavascripts %}
{% block javascripts %}{% endblock %}

so I leave the main js libraries (with the naming convention I mentioned above) in the "MainBundle" and also configured in the base template. This way they are loaded in every page and I have the possibility of extending CSS and javascript files with some files specific to that page like this:

{% extends '::base.html.twig' %}
{% block stylesheets %}
    {% stylesheets '@MySpecificBundle/Resources/public/css/*'  %}
        <link rel="stylesheet" href="{{ asset_url }}" />
    {% endstylesheets %}
{% endblock %}
{% block body %}
     ... < whatever > ...
{% endblock %}
{% block javascripts %}
    {{ parent() }}
    {% javascripts  '@MySpecificBundle/Resources/public/js/*' %}
        <script type="text/javascript" src="{{ asset_url }}"></script>
    {% endjavascripts %}
{% endblock %}
Arthropod answered 28/1, 2015 at 12:36 Comment(0)
E
1

It is an old question, but i was wondering too how to achieve that, and based on @TroodoN-Mike solution I realized that this will do the trick :

{% javascripts '@AcmeFooBundle/Resources/public/js/file1.js' '@AcmeFooBundle/Resources/public/js/*' %} <script type="text/javascript" src="{{ asset_url }}"></script> {% endjavascripts %}

Eliott answered 31/3, 2015 at 7:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.