NAME
File::Assets - Manage .css and .js assets in a web application
VERSION
Version 0.050
SYNOPSIS
use File::Assets
my $assets = File::Assets->new( base => [ $uri_root, $htdocs_root ] );
$assets->include("/static/style.css"); # File::Assets will automatically detect the type based on the extension
# Then, later ...
$assets->include("/static/main.js");
$assets->include("/static/style.css"); # This asset won't get included twice, as File::Assets will ignore repeats of a path
# And then, in your .tt (Template Toolkit) files:
[% WRAPPER page.tt %]
[% assets.include("/static/special-style.css", 100) %] # The "100" is the rank, which makes sure it is exported after other assets
# ... finally, in your "main" template:
[% CLEAR -%]
<html>
<head>
[% assets.export("css") %]
</head>
<body>
[% content %]
<!-- Generally, you want to include your JavaScript assets at the bottom of your html -->
[% assets.export("js") %]
</body>
</html>
# If you want to process each asset individually, you can use exports:
for my $asset ($assets->exports) {
print $asset->uri, "\n";
}
DESCRIPTION
File::Assets is a tool for managing JavaScript and CSS assets in a (web) application. It allows you to "publish" assests in one place after having specified them in different parts of the application (e.g. throughout request and template processing phases).
This package has the added bonus of assisting with minification and filtering of assets. Support is built-in for YUI Compressor (http://developer.yahoo.com/yui/compressor/), JavaScript::Minifier, and CSS::Minifier. Filtering is fairly straightforward to implement, so it's a good place to start if need a JavaScript or CSS preprocessor (e.g. something like HAML http://haml.hamptoncatlin.com/)
File::Assets was built with Catalyst in mind, although this package is framework agnostic. Look at Catalyst::Plugin::Assets for an easy way to integrate File::Assets with Catalyst.
USAGE
Cascading style sheets and their media types
A cascading style sheet can be one of many different media types. For more information, look here: http://www.w3.org/TR/REC-CSS2/media.html
This can cause a problem when minifying, since, for example, you can't bundle a media type of screen with a media type of print. File::Assets handles this situation by treating .css files of different media types separately.
To control the media type of a text/css asset, you can do the following:
$assets->include("/path/to/printstyle.css", ..., { media => "print" }); # The asset will be exported with the print-media indicator
$assets->include_content($content, "text/css", ..., { media => "screen" }); # Ditto, but for the screen type
Including assets in the middle of processing a Template Toolkit template
Sometimes, in the middle of a TT template, you want to include a new asset. Usually you would do something like this:
[% assets.include("/include/style.css") %]
But then this will show up in your output, because ->include returns an object:
File::Assets::Asset=HASH(0x99047e4)
The way around this is to use the TT "CALL" directive, as in the following:
[% CALL assets.include("/include/style.css") %]
Avoid minifying assets on every request (if you minify)
By default, File::Assets will avoid re-minifying assets if nothing in the files have changed. However, in a web application, this can be a problem if you serve up two web pages that have different assets. That's because File::Assets will detect different assets being served in page A versus assets being served in page B (think AJAX interface vs. plain HTML with some CSS). The way around this problem is to name your assets object with a unique name per assets bundle. By default, the name is "assets", but can be changed with $assets->name(<a new name>):
my $assets = File::Assets->new(...);
$assets->name("standard");
You can change the name of the assets at anytime before exporting.
METHODS
File::Assets->new( base => <base> )
Create and return a new File::Assets object. <base> can be:
* An array (list reference) where <base>[0] is a URI object or uri-like string (e.g. "http://www.example.com") and <base>[1] is a Path::Class::Dir object or a dir-like string (e.g. "/var/htdocs")
* A URI::ToDisk object
* A Path::Resource object
$asset = $assets->include(<path>, [ <rank>, <type>, { ... } ])
$asset = $assets->include_path(<path>, [ <rank>, <type>, { ... } ])
Include an asset located at "<base.dir>/<path>" for processing. The asset will be exported as "<base.uri>/<path>".
Optionally, you can specify a rank, where a lower number (i.e. -2, -100) causes the asset to appear earlier in the exports list, and a higher number (i.e. 6, 39) causes the asset to appear later in the exports list. By default, all assets start out with a neutral rank of 0.
Also, optionally, you can specify a type override as the third argument.
By default, the newly created $asset is NOT inline.
Returns the newly created asset.
NOTE: See below for how the extra hash on the end is handled
$asset = $assets->include({ ... })
Another way to invoke include is by passing in a hash reference.
The hash reference should contain the follwing information:
path # The path to the asset file, relative to base
content # The content of the asset
type # Optional if a path is given, required for content
rank # Optional, 0 by default (Less than zero is earlier, greater than zero is later)
base # Optional, by default the base of $assets
inline # Optional, by default true if content was given, false is a path was given
You can also pass extra information through the hash. Any extra information will be bundled in the ->attributes hash of $asset. For example, you can control the media type of a text/css asset by doing something like:
$assets->include("/path/to/printstyle.css", ..., { media => "print" }) # The asset will be exported with the print-media indicator
$asset = $assets->include_content(<content>, [ <type>, <rank>, { ... } ])
Include an asset with some content and of the supplied type. The value of <content> can be a "plain" string or a scalar reference.
See ->include for more information on <rank>.
By default, the newly created $asset is inline.
Returns the newly created asset.
NOTE: The order of the <type> and <rank> arguments are reversed from ->include and ->include_path
$name = $assets->name([ <name> ])
Retrieve and/or change the "name" of $assets; by default it is "assets"
This is useful for controlling the name of minified assets files.
Returns the name of $assets
$html = $assets->export([ <type> ])
Generate and return HTML for the assets of <type>. If no type is specified, then assets of every type are exported.
$html will be something like this:
<link rel="stylesheet" type="text/css" href="http://example.com/assets.css">
<script src="http://example.com/assets.js" type="text/javascript"></script>
@assets = $assets->exports([ <type> ])
Returns a list of assets, in ranking order, that are exported. If no type is specified, then assets of every type are exported.
You can use this method to generate your own HTML, if necessary.
$assets->empty
Returns 1 if no assets have been included yet, 0 otherwise.
$assets->exists( <path> )
Returns true if <path> has been included, 0 otherwise.
$assets->store( <asset> )
Store <asset> in $assets
$asset = $assets->fetch( <path> )
Fetch the asset located at <path>
Returns undef if nothing at <path> exists yet
AUTHOR
Robert Krimen, <rkrimen at cpan.org>
BUGS
Please report any bugs or feature requests to bug-file-assets at rt.cpan.org
, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=File-Assets. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
SUPPORT
You can find documentation for this module with the perldoc command.
perldoc File::Assets
You can also look for information at:
RT: CPAN's request tracker
AnnoCPAN: Annotated CPAN documentation
CPAN Ratings
Search CPAN
ACKNOWLEDGEMENTS
COPYRIGHT & LICENSE
Copyright 2008 Robert Krimen
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.