CSS::Squish(3pm)
π NAME π
CSS::Squish β it smooshes a whole pile of CSS files into one big file π
okay so real talk, this is the CSS::Squish(3pm) page from the User Contributed Perl Documentation, and it is genuinely one of the most useful little modules you'll ever meet. Sit down, bestie, we're gonna go through it together π«Ά
β¨ SYNOPSIS β¨
use CSS::Squish;
my $concatenated = CSS::Squish->concatenate(@files);
my $squisher = CSS::Squish->new( roots => ['/root1', '/root2'] );
my $concatenated = $squisher->concatenate(@files);
two ways to do the thing. class-method girlie or object girlie. both valid π
πΈ DESCRIPTION πΈ
So what does this module actually do? You hand it a list of CSS files and it concatenates them β like, glues them all together β and it makes sure to honor any valid @import statements that show up inside those files. No cap.
The whole point, the benefit, is that you get to keep your CSS as individual files (organised, cute, β¨aestheticβ¨) but still serve it to users as one big file. Which saves you the overhead of possibly dozens of HTTP requests. Dozens!! Your users' browsers will thank you, their little loading spinners will rest ππ
Following the CSS 2.1 spec, @import statements must be the first rules in a CSS file. That's not a suggestion, that's the law. Media-specific @import statements get honored by enclosing the included file in an @media rule. And here's the fun part β this has the side effect of actually improving compatibility in Internet Explorer, which ignores media-specific @import rules but understands @media rules. iconic behaviour honestly, we love an accidental glow-up π
Also, heads up: it is possible that future versions will include methods to compact whitespace and other parts of the CSS itself, but this functionality is not supported at the current time. so don't come for me about whitespace, it's not on the menu yet π
π COMMON METHODS π
new( [roots=>[...]] ) π±
A constructor. And for backward compatibility with versions prior to 0.06 you can still call everything as a class method β but bestie, remember that in that case roots are shared between all callers. Shared!! All of them!! π³
if you're using persistent environment (like mod_perl) then it's very recomended to use objects. like, please. use objects. for your own sake π
concatenate( @files ) π§
Takes a list of files to concatenate and returns the results as one big scalar. One big glowy blob of CSS. slay.
concatenate_to( $dest, @files ) π
Takes a filehandle to print to and a list of files to concatenate. And plot twist β concatenate uses this method with an opened scalar. it's methods all the way down π¦
π RESOLVING METHODS π
The following methods help map URIs to files and find them on the disk. very detective, very main character π
In common situation you control CSS and can adopt it to use imports with relative URIs, and most probably only have to set root(s). easy peasy.
However β and this is the fun part β you can subclass these methods to parse css files before submitting, implement advanced mapping of URIs to file system and other things. go off, customise your heart out π
Mapping works in the following way. When you call concatenate method we get content of file using file_handle method which as well lookup files in roots. If roots are not defined then files are treated as absolute paths or relative to the current directory. Using of absolute paths is not recommended as unhide server dirrectory layout to clients in css comments and as well don't allow to handle @import commands with absolute URIs. (read that again, it's giving security vibes, not cute vibes π¨) When files is found we parse its content for @import commands. On each URI we call resolve_uri method that convert absolute and relative URIs into file paths.
Here is example of processing:
roots: /www/overlay/, /www/shared/
$squisher->concatenate('/css/main.css');
->file_handle('/css/main.css');
->resolve_file('/css/main.css');
<- '/www/shared/css/main.css';
<- handle;
content parsing
find '@import url(nav.css)'
-> resolve_uri('nav.css', '/css/main.css');
<- '/css/nav.css';
... recursivly process file
find '@import url(/css/another.css)'
-> resolve_uri('/css/another.css', '/css/main.css');
<- '/css/another.css'
...
so pretty. a little recursive tree of CSS. we love to see it π³β¨
roots( @dirs ) πΈ
A getter/setter for paths to search when looking for files.
The paths specified here are searched for files. This is useful if your server has multiple document roots or document root doesn't match the current dir. messy server? this fixes that π
See also 'resolve_file' below.
file_handle( $file ) π
Takes a path to a file, resolves (see resolve_file) it and returns a handle.
Returns undef if file couldn't be resolved or it's impossible to open file.
You can subclass it to filter content, process it with templating system or generate it on the fly. like, generate CSS out of thin air, the audacity, the talent π₯:
package My::CSS::Squish;
use base qw(CSS::Squish);
sub file_handle {
my $self = shift;
my $file = shift;
my $content = $self->my_prepare_content($file);
return undef unless defined $content;
open my $fh, "<", \$content or warn "Couldn't open handle: $!";
return $fh;
}
Note that the file is not resolved yet and is relative to the root(s), so you have to resolve it yourself or call resolve_file method. don't forget, bestie, I'm not gonna do it for you π
resolve_file( $file ) π¦
Lookup file in the root(s) and returns first path it found or undef.
When roots are not set just checks if file exists. simple. clean. no drama.
_resolve_file( $file, @roots ) π
DEPRECATED. This private method is deprecated and do nothing useful except maintaining backwards compatibility. If you were using it then most probably to find files in roots before submitting them into concatenate method. Now, it's not required and this method returns back file path without changes.
okay so it literally does nothing now, it's just there being nostalgic in the corner. respect the elder π«‘ but also don't call it.
resolve_uri( $uri_string, $base_file ) π§
Takes an URI and base file path and transforms it into new file path. that's it, that's the whole job, and it does it beautifully β¨
π BUGS AND SHORTCOMINGS π
At the current time, comments are not skipped. This means comments happening before @import statements at the top of a file will cause the @import rules to not be parsed. Make sure the @import rules are the very first thing in the file (and only one per line). Processing of @import rules stops as soon as the first line that doesn't match an @import rule is encountered.
so if you've got a cute little /* hi bestie */ comment at the top of your file? yeah, that's gonna break the whole import parsing. no comments before imports. none. zero. put them after. I'm serious π€
All other bugs should be reported via <http://rt.cpan.org/Public/Dist/Display.html?Name=CSS-Squish> or bug-CSS-Squish@rt.cpan.org.
π AUTHOR π
Thomas Sibley <trs@bestpractical.com>, Ruslan Zakirov <ruz@bestpractical.com>
legends. both of them. thank you for your service π«Ά
π COPYRIGHT AND LICENSE π
Copyright (c) 2006.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.3 or, at your option, any later version of Perl 5 you may have available.
and that's the whole page, bestie!! π this was perl v5.26.1, dated 2018-03-31, and you just read the one and only CSS::Squish(3pm) β go forth and concatenate responsibly, mwah π
πβ¨
π¦ where this page comes from
- debian bookworm: libcss-squish-perl 0.10-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- debian trixie: libcss-squish-perl 0.10-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu jammy: libcss-squish-perl 0.10-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu noble: libcss-squish-perl 0.10-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms