1
1
How to Use Assetic for Asset Management
2
2
=======================================
3
3
4
- Assetic is a powerful asset management library which is packaged with the
5
- Symfony2 Standard Edition and can be easily used in Symfony2 directly from
6
- Twig or PHP templates.
7
-
8
4
Assetic combines two major ideas: assets and filters. The assets are files
9
- such as CSS, JavaScript and images files. The filters are things that can
5
+ such as CSS, JavaScript and image files. The filters are things that can
10
6
be applied to these files before they are served to the browser. This allows
11
7
a separation between the asset files stored in the application and the files
12
8
actually presented to the user.
@@ -46,7 +42,8 @@ drawn from various sources such as from within a bundle:
46
42
47
43
.. code - block:: html+ jinja
48
44
49
- {% javascripts ' @AcmeFooBundle/Resources/public/js/*'
45
+ {% javascripts
46
+ ' @AcmeFooBundle/Resources/public/js/*'
50
47
% }
51
48
< script type= " text/javascript" src= " {{ asset_url }}" > </script >
52
49
{% endjavascripts %}
@@ -58,27 +55,62 @@ drawn from various sources such as from within a bundle:
58
55
<script type="text/javascript" src="<?php echo $view->escape($url) ?>"></script>
59
56
<?php endforeach; ?>
60
57
58
+ .. tip ::
59
+
60
+ To bring in CSS stylesheets, you can use the same methodologies seen
61
+ in this entry, except with the `stylesheets ` tag:
62
+
63
+ .. configuration-block ::
64
+
65
+ .. code-block :: html+jinja
66
+
67
+ {% stylesheets
68
+ '@AcmeFooBundle/Resources/public/css/*'
69
+ %}
70
+ <link rel="stylesheet" href="{{ asset_url }}" />
71
+ {% endstylesheets %}
72
+
73
+ .. code-block :: html+php
74
+
75
+ <?php foreach ($view['assetic']->stylesheets(
76
+ array('@AcmeFooBundle/Resources/public/css/*')) as $url): ?>
77
+ <link rel="stylesheet" href="<?php echo $view->escape($url) ?>" />
78
+ <?php endforeach; ?>
79
+
61
80
In this example, all of the files in the ``Resources/public/js/ `` directory
62
81
of the ``AcmeFooBundle `` will be loaded and served from a different location.
63
82
The actual rendered tag might simply look like:
64
83
65
- <script src="/js/abcd123.js"></script>
84
+ .. code-block :: html
85
+
86
+ <script src =" /app_dev.php/js/abcd123.js" ></script >
87
+
88
+ .. note ::
89
+
90
+ This is a key point: once you let Assetic handle your assets, the files are
91
+ served from a different location. This *can * cause problems with CSS files
92
+ that reference images by their relative path. However, this can be fixed
93
+ by using the ``cssrewrite `` filter, which updates paths in CSS files
94
+ to reflect their new location.
95
+
96
+ Combining Assets
97
+ ~~~~~~~~~~~~~~~~
66
98
67
99
You can also combine several files into one. This helps to reduce the number
68
- of HTTP requests which is good for front end performance, as most browsers
69
- will only process a limited number at a time slowing down page load times.
70
- It also allows you to maintain the files more easily by splitting them into
71
- manageable parts. This can also help with re-usability as you can easily
72
- split project specific files from those which can be used in other applications
73
- but still serve them as a single file:
100
+ of HTTP requests, which is great for front end performance. It also allows
101
+ you to maintain the files more easily by splitting them into manageable parts.
102
+ This can help with re-usability as you can easily split project-specific
103
+ files from those which can be used in other applications, but still serve
104
+ them as a single file:
74
105
75
106
.. configuration-block ::
76
107
77
108
.. code-block :: html+jinja
78
109
79
- {% javascripts '@AcmeFooBundle/Resources/public/js/*'
80
- '@AcmeBarBundle/Resources/public/js/form.js'
81
- '@AcmeBarBundle/Resources/public/js/calendar.js'
110
+ {% javascripts
111
+ '@AcmeFooBundle/Resources/public/js/*'
112
+ '@AcmeBarBundle/Resources/public/js/form.js'
113
+ '@AcmeBarBundle/Resources/public/js/calendar.js'
82
114
%}
83
115
<script src="{{ asset_url }}"></script>
84
116
{% endjavascripts %}
@@ -92,15 +124,27 @@ but still serve them as a single file:
92
124
<script src="<?php echo $view->escape($url) ?>"></script>
93
125
<?php endforeach; ?>
94
126
95
- This does not only apply to your own files you can also use Assetic to
96
- combine third party assets, such as jQuery with your own into a single file:
127
+ In the `dev ` environment, each file is still served individually, so that
128
+ you can debug problems more easily. However, in the `prod ` environment, this
129
+ will be rendered as a single `script ` tag.
130
+
131
+ .. tip ::
132
+
133
+ If you're new to Assetic and try to use your application in the ``prod ``
134
+ environment (by using the ``app.php `` controller), you'll likely see
135
+ that all of your CSS and JS breaks. Don't worry! This is on purpose.
136
+ For details on using Assetic in the `prod ` environment, see :ref: `cookbook-assetic-dumping `.
137
+
138
+ And combining files doesn't only apply to *your * files. You can also use Assetic to
139
+ combine third party assets, such as jQuery, with your own into a single file:
97
140
98
141
.. configuration-block ::
99
142
100
143
.. code-block :: html+jinja
101
144
102
- {% javascripts '@AcmeFooBundle/Resources/public/js/thirdparty/jquery.js'
103
- '@AcmeFooBundle/Resources/public/js/*'
145
+ {% javascripts
146
+ '@AcmeFooBundle/Resources/public/js/thirdparty/jquery.js'
147
+ '@AcmeFooBundle/Resources/public/js/*'
104
148
%}
105
149
<script src="{{ asset_url }}"></script>
106
150
{% endjavascripts %}
@@ -116,21 +160,26 @@ combine third party assets, such as jQuery with your own into a single file:
116
160
Filters
117
161
-------
118
162
119
- Additionally to this Assetic can apply filters to the assets before they
120
- are served. This includes tasks such as compressing the output for smaller
121
- file sizes which is another valuable front end optimisation. Other filters
122
- include compiling JavaScript file from CoffeeScript files and SASS to CSS.
163
+ Once they're managed by Assetic, you can apply filters to your assets before
164
+ they are served. This includes filters that compress the output of your assets
165
+ for smaller file sizes (and better front-end optimization). Other filters
166
+ can compile JavaScript file from CoffeeScript files and process SASS into CSS.
167
+ In fact, Assetic has a long list of available filters.
168
+
169
+ Many of the filters do not do the work directly, but use existing third-party
170
+ libraries to do the heavy-lifting. This means that you'll often need to install
171
+ a third-party library to use a filter. The great advantage of using Assetic
172
+ to invoke these libraries (as opposed to using them directly) is that instead
173
+ of having to run them manually after you work on the files, Assetic will
174
+ take care of this for you and remove this step altogether from your development
175
+ and deployment processes.
123
176
124
- Many of the filters do not do the work directly but use other libraries
125
- to do it, this so you will often have to install that software as well.
126
- The great advantage of using Assetic to invoke these libraries is that
127
- instead of having to run them manually when you have worked on the files,
128
- Assetic will take care of this for you and remove this step altogether
129
- from your development and deployment processes.
177
+ To use a filter, you first need to specify it in the Assetic configuration.
178
+ Adding a filter here doesn't mean it's being used - it just means that it's
179
+ available to use (we'll use the filter below).
130
180
131
- To use a filter you must specify it in the Assetic configuration
132
- as they are not enabled by default. For example to use the JavaScript YUI
133
- Compressor the following config needs to be added:
181
+ For example to use the JavaScript YUI Compressor the following config should
182
+ be added:
134
183
135
184
.. configuration-block ::
136
185
@@ -162,14 +211,17 @@ Compressor the following config needs to be added:
162
211
),
163
212
));
164
213
165
-
166
- You can then specify using the filter in the template:
214
+ Now, to actually * use * the filter on a group of JavaScript files, add it
215
+ into your template:
167
216
168
217
.. configuration-block ::
169
218
170
219
.. code-block :: html+jinja
171
220
172
- {% javascripts '@AcmeFooBundle/Resources/public/js/*' filter='yui_js' %}
221
+ {% javascripts
222
+ '@AcmeFooBundle/Resources/public/js/*'
223
+ filter='yui_js'
224
+ %}
173
225
<script src="{{ asset_url }}"></script>
174
226
{% endjavascripts %}
175
227
@@ -181,22 +233,22 @@ You can then specify using the filter in the template:
181
233
<script src="<?php echo $view->escape($url) ?>"></script>
182
234
<?php endforeach; ?>
183
235
184
-
185
- A more detail guide to configuring and using Assetic filters as well as
236
+ A more detailed guide abour configuring and using Assetic filters as well as
186
237
details of Assetic's debug mode can be found in :doc: `/cookbook/assetic/yuicompressor `.
187
238
188
239
Controlling the URL used
189
240
------------------------
190
241
191
- If you wish to you can control the URLs which Assetic produces. This is
242
+ If you wish to you can control the URLs that Assetic produces. This is
192
243
done from the template and is relative to the public document root:
193
244
194
245
.. configuration-block ::
195
246
196
247
.. code-block :: html+jinja
197
248
198
- {% javascripts '@AcmeFooBundle/Resources/public/js/*'
199
- output='js/combined.js'
249
+ {% javascripts
250
+ '@AcmeFooBundle/Resources/public/js/*'
251
+ output='js/compiled/main.js'
200
252
%}
201
253
<script src="{{ asset_url }}"></script>
202
254
{% endjavascripts %}
@@ -206,48 +258,131 @@ done from the template and is relative to the public document root:
206
258
<?php foreach ($view['assetic']->javascripts(
207
259
array('@AcmeFooBundle/Resources/public/js/*'),
208
260
array(),
209
- array('output' => 'js/combined .js')
261
+ array('output' => 'js/compiled/main .js')
210
262
) as $url): ?>
211
263
<script src="<?php echo $view->escape($url) ?>"></script>
212
264
<?php endforeach; ?>
213
265
214
266
.. note ::
215
267
216
268
Symfony also contains a method for cache *busting *, where the final URL
217
- generated by Assetic in the ``prod `` environment contains a query parameter
218
- that can be incremented via configuration on each deployment. For more
219
- information, see the :ref: `ref-framework-assets-version ` configuration
220
- option.
221
-
222
- Caching the output
223
- ------------------
224
-
225
- The process of creating the files served up can be quite slow especially
226
- when using some of the filters which invoke third party software to the
227
- actual work. Even when working in the development environment the slow
228
- down in the page loads if this was to be done each time would quickly get
229
- frustrating. Fortunately in the dev environment Assetic caches the output
230
- so this will not happen, rather than having to clear the cache manually
231
- though, it monitors for changes to the assets and regenerates the files
232
- as needed. This means you can work on the asset files and see the results
233
- on page load but without having to suffer continual slow page loads.
234
-
235
- For production, where you will not be making changes to the asset files,
236
- performance can be increased by avoiding the step of checking for changes.
237
- Assetic allows you to go further than this and avoid touching Symfony2
238
- and even PHP at all when serving the files. This is done by dumping all
239
- of the output files using a console command. These can then be served directly
240
- by the web server as static files, increasing performance and allowing the
241
- web server to deal with caching headers. The console command to dump the files
242
- is:
269
+ generated by Assetic contains a query parameter that can be incremented
270
+ via configuration on each deployment. For more information, see the
271
+ :ref: `ref-framework-assets-version ` configuration option.
272
+
273
+ .. _cookbook-assetic-dumping :
274
+
275
+ Dumping Asset Files
276
+ -------------------
277
+
278
+ In the ``dev `` environment, Assetic generates paths to CSS and JavaScript
279
+ files that don't physically exist on your computer. But they render nonetheless
280
+ because an internal Symfony controller opens the files and serves back the
281
+ content (after running any filters).
282
+
283
+ This kind of dynamic serving of processed assets is great because it means
284
+ that you can immediately see the new state of any asset files you change.
285
+ It's also bad, because it can be quite slow. If you're using a lot of filters,
286
+ it might be downright frustrating.
287
+
288
+ Fortunately, Assetic provides a way to dump your assets to real files, instead
289
+ of being generated dynamically.
290
+
291
+ Dumping Asset Files in the ``prod `` environment
292
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
293
+
294
+ In the ``prod `` environment, your JS and CSS files are represented by a single
295
+ tag each. In other words, instead of seeing each JavaScript file you're including
296
+ in your source, you'll likely just see something like this:
297
+
298
+ .. code-block :: html
299
+
300
+ <script src =" /app_dev.php/js/abcd123.js" ></script >
301
+
302
+ Moreover, that file does **not ** actually exist, nor is it dynamically rendered
303
+ by Symfony (as the asset files are in the ``dev `` environment). This is on
304
+ purpose - letting Symfony generate these files dynamically in a production
305
+ environment is just too slow.
306
+
307
+ Instead, each time you use your app in the ``prod `` environment (and therefore,
308
+ each time you deploy), you should run the following task:
309
+
310
+ .. code-block :: bash
311
+
312
+ php app/console assetic:dump --env=prod --no-debug
313
+
314
+ This will physically generate and write each file that you need (e.g. ``/js/abcd123.js ``).
315
+ If you update any of your assets, you'll need to run this again to regenerate
316
+ the file.
317
+
318
+ Dumping Asset Files in the ``dev `` environment
319
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
320
+
321
+ By default, each asset path generated in the ``dev `` environment is handled
322
+ dynamically by Symfony. This has no disadvantage (you can see your changes
323
+ immediately), except that assets can load noticeably slow. If you feel like
324
+ your assets are loading too slowly, follow this guide.
325
+
326
+ First, tell Symfony to stop trying to process these files dynamically. Make
327
+ the following change in your ``config_dev.yml `` file:
328
+
329
+ .. configuration-block ::
330
+
331
+ .. code-block :: yaml
332
+
333
+ # app/config/config_dev.yml
334
+ assetic :
335
+ use_controler : false
336
+
337
+ .. code-block :: xml
338
+
339
+ <!-- app/config/config_dev.xml -->
340
+ <assetic : config use-controller =" false" />
341
+
342
+ .. code-block :: php
343
+
344
+ // app/config/config_dev.php
345
+ $container->loadFromExtension('assetic', array(
346
+ 'use_controller' => false,
347
+ ));
348
+
349
+ Next, since Symfony is no longer generating these assets for you, you'll
350
+ need to dump them manually. To do so, run the following:
243
351
244
352
.. code-block :: bash
245
353
246
354
php app/console assetic:dump
247
355
248
- .. note ::
356
+ This physically writes all of the asset files you need for your ``dev ``
357
+ environment. The big disadvantage is that you need to run this each time
358
+ you update an asset. Fortunately, by passing the ``--watch `` option, the
359
+ command will automatically regenerate assets *as they change *:
360
+
361
+ .. code-block :: bash
362
+
363
+ php app/console assetic:dump --watch
364
+
365
+ Since running this command in the ``dev `` environment may generate a bunch
366
+ of files, it's usually a good idea to point your generated assets files to
367
+ some isolated directory (e.g. ``/js/compiled ``), to keep things organized:
368
+
369
+ .. configuration-block ::
370
+
371
+ .. code-block :: html+jinja
372
+
373
+ {% javascripts
374
+ '@AcmeFooBundle/Resources/public/js/*'
375
+ output='js/compiled/main.js'
376
+ %}
377
+ <script src="{{ asset_url }}"></script>
378
+ {% endjavascripts %}
249
379
250
- Once you have dumped the output you will need to run the console
251
- command again to see any new changes. If you run it on your development
252
- server you will need to remove the files in order to start letting Assetic
253
- process the assets on the fly again.
380
+ .. code-block :: html+php
381
+
382
+ <?php foreach ($view['assetic']->javascripts(
383
+ array('@AcmeFooBundle/Resources/public/js/*'),
384
+ array(),
385
+ array('output' => 'js/compiled/main.js')
386
+ ) as $url): ?>
387
+ <script src="<?php echo $view->escape($url) ?>"></script>
388
+ <?php endforeach; ?>
0 commit comments