1NAME
2 File::Assets - Manage .css and .js assets for a web page or application
3
4VERSION
5 Version 0.064
6
7SYNOPSIS
8 use File::Assets
9
10 my $assets = File::Assets->new( base => [ $uri_root, $dir_root ] )
11
12 # Put minified files in $dir_root/built/... (the trailing slash is important)
13 $assets->set_output_path("built/")
14
15 # File::Assets will automatically detect the type based on the extension
16 $assets->include("/static/style.css")
17
18 # You can also include external assets:
19 $assets->include("http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js");
20
21 # This asset won't get included twice, as File::Assets will ignore repeats of a path
22 $assets->include("/static/style.css")
23
24 # And finally ...
25 $assets->export
26
27 # Or you can iterate (in order)
28 for my $asset ($assets->exports) {
29
30 print $asset->uri, "\n";
31
32 }
33
34 In your .tt (Template Toolkit) files:
35
36 [% WRAPPER page.tt %]
37
38 [% assets.include("/static/special-style.css", 100) %] # The "100" is the rank, which makes sure it is exported after other assets
39
40 [% asset = BLOCK %]
41 <style media="print">
42 body { font: serif; }
43 </style>
44 [% END %]
45 [% assets.include(asset) %] # This will include the css into an inline asset with the media type of "print"
46
47 # ... finally, in your "main" template:
48
49 [% CLEAR -%]
50 <html>
51
52 <head>
53 [% assets.export("css") %]
54 </head>
55
56 <body>
57
58 [% content %]
59
60 <!-- Generally, you want to include your JavaScript assets at the bottom of your html -->
61
62 [% assets.export("js") %]
63
64 </body>
65
66 </html>
67
68 Use the minify option to perform minification before export
69
70 my $assets = File::Assets->new( minify => 1, ... )
71
72DESCRIPTION
73 File::Assets is a tool for managing JavaScript and CSS assets in a (web)
74 application. It allows you to "publish" assests in one place after
75 having specified them in different parts of the application (e.g.
76 throughout request and template processing phases).
77
78 This package has the added bonus of assisting with minification and
79 filtering of assets. Support is built-in for YUI Compressor
80 (<http://developer.yahoo.com/yui/compressor/>), JavaScript::Minifier,
81 CSS::Minifier, JavaScript::Minifier::XS, and CSS::Minifier::XS.
82
83 File::Assets was built with Catalyst in mind, although this package is
84 framework agnostic. Look at Catalyst::Plugin::Assets for an easy way to
85 integrate File::Assets with Catalyst.
86
87USAGE
88 Cascading style sheets and their media types
89 A cascading style sheet can be one of many different media types. For
90 more information, look here: <http://www.w3.org/TR/REC-CSS2/media.html>
91
92 This can cause a problem when minifying, since, for example, you can't
93 bundle a media type of screen with a media type of print. File::Assets
94 handles this situation by treating .css files of different media types
95 separately.
96
97 To control the media type of a text/css asset, you can do the following:
98
99 $assets->include("/path/to/printstyle.css", ..., { media => "print" }); # The asset will be exported with the print-media indicator
100
101 $assets->include_content($content, "text/css", ..., { media => "screen" }); # Ditto, but for the screen type
102
103 Including assets in the middle of processing a Template Toolkit template
104 Sometimes, in the middle of a TT template, you want to include a new
105 asset. Usually you would do something like this:
106
107 [% assets.include("/include/style.css") %]
108
109 But then this will show up in your output, because ->include returns an
110 object:
111
112 File::Assets::Asset=HASH(0x99047e4)
113
114 The way around this is to use the TT "CALL" directive, as in the
115 following:
116
117 [% CALL assets.include("/include/style.css") %]
118
119 Avoid minifying assets on every request (if you minify)
120 By default, File::Assets will avoid re-minifying assets if nothing in
121 the files have changed. However, in a web application, this can be a
122 problem if you serve up two web pages that have different assets. That's
123 because File::Assets will detect different assets being served in page A
124 versus assets being served in page B (think AJAX interface vs. plain
125 HTML with some CSS). The way around this problem is to name your assets
126 object with a unique name per assets bundle. By default, the name is
127 "assets", but can be changed with $assets->name(<a new name>):
128
129 my $assets = File::Assets->new(...);
130 $assets->name("standard");
131
132 You can change the name of the assets at anytime before exporting.
133
134 YUI Compressor 2.2.5 is required
135 If you want to use the YUI Compressor, you should have version 2.2.5 or
136 above.
137
138 YUI Compressor 2.1.1 (and below) will *NOT WORK*
139
140 To use the compressor for minification specify the path to the .jar like
141 so:
142
143 my $assets = File::Assets->new( minify => "/path/to/yuicompressor.jar", ... )
144
145 Specifying an "output_path" pattern
146 When aggregating or minifying assets, you need to put the result in a
147 new file.
148
149 You can use the following directives when crafting a path/filename
150 pattern:
151
152 %n The name of the asset, "assets" by default
153 %e The extension of the asset (e.g. css, js)
154 %f The fingerprint of the asset collection (a hexadecimal digest of the concatenated digest of each asset in the collection)
155 %k The kind of the asset (e.g. css-screen, css, css-print, js)
156 %h The kind head-part of the asset (e.g. css, js)
157 %l The kind tail-part of the asset (e.g. screen, print) (essentially the media type of a .css asset)
158
159 In addition, in each of the above, a ".", "/" or "-" can be placed in
160 between the "%" and directive character. This will result in a ".", "/",
161 or "-" being prepended to the directive value.
162
163 The default pattern is:
164
165 %n%-l%-f.%e
166
167 A pattern of "%n%-l.%e" can result in the following:
168
169 assets.css # name of "assets", no media type, an asset type of CSS (.css)
170 assets-screen.css # name of "assets", media type of "screen", an asset type of CSS (.css)
171 assets.js # name of "assets", an asset type of JavaScript (.js)
172
173 If the pattern ends with a "/", then the default pattern will be
174 appended
175
176 xyzzy/ => xyzzy/%n%-l-%f.%e
177
178 If the pattern does not have an extension-like ending, then "%.e" will
179 be appended
180
181 xyzzy => xyzzy.%e
182
183 Strange output or "sticky" content
184 File::Assets uses built-in caching to share content across different
185 objects (via File::Assets::Cache). If you're having problems try
186 disabling the cache by passing "cache => 0" to File::Assets->new
187
188METHODS
189 File::Assets->new( base => <base>, output_path => <output_path>, minify => <minify> )
190 Create and return a new File::Assets object.
191
192 You can configure the object with the following:
193
194 base # A hash reference with a "uri" key/value and a "dir" key/value.
195 For example: { uri => http://example.com/assets, dir => /var/www/htdocs/assets }
196
197 # A URI::ToDisk object
198
199 # A Path::Resource object
200
201 minify # "1" or "best" - Will either use JavaScript::Minifier::XS> & CSS::Minifier::XS or
202 JavaScript::Minifier> & CSS::Minifier (depending on availability)
203 for minification
204
205 # "0" or "" or undef - Don't do any minfication (this is the default)
206
207 # "./path/to/yuicompressor.jar" - Will use YUI Compressor via the given .jar for minification
208
209 # "minifier" - Will use JavaScript::Minifier & CSS::Minifier for minification
210
211 # "xs" or "minifier-xs" - Will use JavaScript::Minifier::XS & CSS::Minifier::XS for minification
212
213 output_path # Designates the output path for minified .css and .js assets
214 The default output path pattern is "%n%-l%-d.%e" (rooted at the dir of <base>)
215 See above in "Specifying an output_path pattern" for details
216
217 $asset = $assets->include(<path>, [ <rank>, <type>, { ... } ])
218 $asset = $assets->include_path(<path>, [ <rank>, <type>, { ... } ])
219 First, if <path> is a scalar reference or "looks like" some HTML (starts
220 with a angle bracket, e.g.: <script></script>), then it will be treated
221 as inline content.
222
223 Otherwise, this will include an asset located at "<base.dir>/<path>" for
224 processing. The asset will be exported as "<base.uri>/<path>"
225
226 Optionally, you can specify a rank, where a lower number (i.e. -2, -100)
227 causes the asset to appear earlier in the exports list, and a higher
228 number (i.e. 6, 39) causes the asset to appear later in the exports
229 list. By default, all assets start out with a neutral rank of 0.
230
231 Also, optionally, you can specify a type override as the third argument.
232
233 By default, the newly created $asset is NOT inline.
234
235 Returns the newly created asset.
236
237 NOTE: See below for how the extra hash on the end is handled
238
239 $asset = $assets->include({ ... })
240 Another way to invoke include is by passing in a hash reference.
241
242 The hash reference should contain the follwing information:
243
244 path # The path to the asset file, relative to base
245 content # The content of the asset
246
247 type # Optional if a path is given, required for content
248 rank # Optional, 0 by default (Less than zero is earlier, greater than zero is later)
249 inline # Optional, by default true if content was given, false is a path was given
250 base # Optional, by default the base of $assets
251
252 You can also pass extra information through the hash. Any extra
253 information will be bundled in the ->attributes hash of $asset. For
254 example, you can control the media type of a text/css asset by doing
255 something like:
256
257 $assets->include("/path/to/printstyle.css", ..., { media => "print" }) # The asset will be exported with the print-media indicator
258
259 NOTE: The order of <rank> and <type> doesn't really matter, since we can
260 detect whether something looks like a rank (number) or not, and correct
261 for it (and it does).
262
263 $asset = $assets->include_content(<content>, [ <type>, <rank>, { ... } ])
264 Include an asset with some content and of the supplied type. The value
265 of <content> can be a "plain" string or a scalar reference.
266
267 You can include content that looks like HTML:
268
269 <style media="print">
270 body {
271 font: serif;
272 }
273 </style>
274
275 In the above case, <type> is optional, as File::Assets can detect from
276 the tag that you're supplying a style sheet. Furthermore, the method
277 will find all the attributes in the tag and put them into the asset. So
278 the resulting asset from including the above will have a type of
279 "text/css" and media of "print".
280
281 For now, only <style> and <script> will map to types (.css and .js,
282 respectively)
283
284 See ->include for more information on <rank>.
285
286 By default, the newly created $asset is inline.
287
288 Returns the newly created asset.
289
290 NOTE: The order of the <type> and <rank> arguments are reversed from
291 ->include and ->include_path Still, the order of <rank> and <type>
292 doesn't really matter, since we can detect whether something looks like
293 a rank (number) or not, and correct for it (and it does).
294
295 $name = $assets->name([ <name> ])
296 Retrieve and/or change the "name" of $assets; by default it is "assets"
297
298 This is useful for controlling the name of minified assets files.
299
300 Returns the name of $assets
301
302 $html = $assets->export([ <type> ])
303 Generate and return HTML for the assets of <type>. If no type is
304 specified, then assets of every type are exported.
305
306 $html will be something like this:
307
308 <link rel="stylesheet" type="text/css" href="http://example.com/assets.css">
309 <script src="http://example.com/assets.js" type="text/javascript"></script>
310
311 @assets = $assets->exports([ <type> ])
312 Returns a list of assets, in ranking order, that are exported. If no
313 type is specified, then assets of every type are exported.
314
315 You can use this method to generate your own HTML, if necessary.
316
317 $assets->empty
318 Returns 1 if no assets have been included yet, 0 otherwise.
319
320 $assets->exists( <path> )
321 Returns true if <path> has been included, 0 otherwise.
322
323 $assets->store( <asset> )
324 Store <asset> in $assets
325
326 $asset = $assets->fetch( <path> )
327 Fetch the asset located at <path>
328
329 Returns undef if nothing at <path> exists yet
330
331 $assets->set_name( <name> )
332 Set the name of $assets
333
334 This is exactly the same as
335
336 $assets->name( <name> )
337
338 $assets->set_base( <base> )
339 Set the base uri, dir, and path for assets
340
341 <base> can be a Path::Resource, URI::ToDisk, or a hash reference of the
342 form:
343
344 { uri => ..., dir => ..., path => ... }
345
346 Given a dir of "/var/www/htdocs", a uri of "http://example.com/static",
347 and a path of "assets" then:
348
349 $assets will look for files in "/var/www/htdocs/assets"
350
351 $assets will "serve" files with "http://example.com/static/assets"
352
353 $assets->set_base_uri( <uri> )
354 Set the base uri for assets
355
356 $assets->set_base_dir( <dir> )
357 Set the base dir for assets
358
359 $assets->set_base_path( <path> )
360 Set the base path for assets
361
362 Passing an undefined value for <path> will clear/get-rid-of the path
363
364 $assets->set_output_path( <path> )
365 Set the output path for assets generated by $assets
366
367 See "Specifying an "output_path" pattern" above
368
369 $assets->set_cache( <cache> )
370 Specify the cache object or cache name to use
371
372AUTHOR
373 Robert Krimen, "<rkrimen at cpan.org>"
374
375SEE ALSO
376 Catalyst::Plugin::Assets
377
378 Google::AJAX::Library
379
380 JS::YUI::Loader
381
382 JS::jQuery::Loader
383
384SOURCE
385 You can contribute or fork this project via GitHub:
386
387 <http://github.com/robertkrimen/file-assets/tree/master>
388
389 git clone git://github.com/robertkrimen/file-assets.git File-Assets
390
391BUGS
392 Please report any bugs or feature requests to "bug-file-assets at
393 rt.cpan.org", or through the web interface at
394 <http://rt.cpan.org/NoAuth/ReportBug.html?Queue=File-Assets>. I will be
395 notified, and then you'll automatically be notified of progress on your
396 bug as I make changes.
397
398SUPPORT
399 You can find documentation for this module with the perldoc command.
400
401 perldoc File::Assets
402
403 You can also look for information at:
404
405 * RT: CPAN's request tracker
406 <http://rt.cpan.org/NoAuth/Bugs.html?Dist=File-Assets>
407
408 * AnnoCPAN: Annotated CPAN documentation
409 <http://annocpan.org/dist/File-Assets>
410
411 * CPAN Ratings
412 <http://cpanratings.perl.org/d/File-Assets>
413
414 * Search CPAN
415 <http://search.cpan.org/dist/File-Assets>
416
417ACKNOWLEDGEMENTS
418COPYRIGHT & LICENSE
419 Copyright 2008 Robert Krimen
420
421 This program is free software; you can redistribute it and/or modify it
422 under the same terms as Perl itself.
423
424