summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Plack/Middleware/File/Less.pm76
-rw-r--r--t/bar.css4
-rw-r--r--t/foo.less9
-rw-r--r--t/less.t28
4 files changed, 117 insertions, 0 deletions
diff --git a/lib/Plack/Middleware/File/Less.pm b/lib/Plack/Middleware/File/Less.pm
new file mode 100644
index 0000000..8ae22b5
--- /dev/null
+++ b/lib/Plack/Middleware/File/Less.pm
@@ -0,0 +1,76 @@
+package Plack::Middleware::File::Less;
+
+# ABSTRACT: LESS CSS support
+
+use strict;
+use warnings;
+
+use parent qw(Plack::Middleware);
+use Plack::Util;
+use CSS::LESSp;
+
+sub call {
+ my ($self, $env) = @_;
+
+ my $orig_path_info = $env->{PATH_INFO};
+ if ($env->{PATH_INFO} =~ s/\.css$/.less/i) {
+ my $res = $self->app->($env);
+
+ return $res unless ref $res eq 'ARRAY';
+
+ if ($res->[0] == 200) {
+ my $less;
+ Plack::Util::foreach($res->[2], sub { $less .= $_[0] });
+ my @css = CSS::LESSp->parse($less);
+ my $css = join("", @css);
+
+ my $h = Plack::Util::headers($res->[1]);
+ $h->set('Content-Type' => 'text/css');
+ $h->set('Content-Length' => length $css);
+
+ $res->[2] = [$css];
+ }
+ elsif ($res->[0] == 404) {
+ $env->{PATH_INFO} = $orig_path_info;
+ $res = $self->app->($env);
+ }
+
+ return $res;
+ }
+ return $self->app->($env);
+}
+
+1;
+
+=head1 SYNOPSIS
+
+ use Plack::App::File;
+ use Plack::Builder;
+
+ builder {
+ mount "/stylesheets" => builder {
+ enable "File::Less";
+ Plack::App::File->new(root => "./stylesheets");
+ };
+ };
+
+ # Or with Middleware::Static
+ enable "File::Less";
+ enable "Static", path => qr/\.css$/, root => "./static";
+
+=head1 DESCRIPTION
+
+Plack::Middleware::File::Less is middleware that compiles
+L<Less|http://lesscss.org> templates into CSS stylesheet..
+
+When a request comes in for I<.css> file, this middleware changes the
+internal path to I<.less> in the same directory. If the LESS template
+is found, a new CSS stylesheet is built on memory and served to the
+browsers. Otherwise, it falls back to the original I<.css> file in
+the directory.
+
+=head1 SEE ALSO
+
+L<Plack::App::File> L<CSS::LESSp> L<http://lesscss.org/>
+
+=cut
diff --git a/t/bar.css b/t/bar.css
new file mode 100644
index 0000000..b8c021f
--- /dev/null
+++ b/t/bar.css
@@ -0,0 +1,4 @@
+#data {
+ float: left;
+ margin-left: 10px;
+}
diff --git a/t/foo.less b/t/foo.less
new file mode 100644
index 0000000..deb790c
--- /dev/null
+++ b/t/foo.less
@@ -0,0 +1,9 @@
+@brand_color: #4D926F;
+
+#header {
+ color: @brand_color;
+}
+
+h2 {
+ color: @brand_color;
+}
diff --git a/t/less.t b/t/less.t
new file mode 100644
index 0000000..9be599f
--- /dev/null
+++ b/t/less.t
@@ -0,0 +1,28 @@
+use strict;
+use Plack::App::File;
+use Plack::Middleware::File::Less;
+use Test::More;
+use Plack::Test;
+use HTTP::Request::Common;
+
+my $app = Plack::App::File->new(root => "t");
+$app = Plack::Middleware::File::Less->wrap($app);
+
+test_psgi $app, sub {
+ my $cb = shift;
+
+ my $res = $cb->(GET "/");
+ is $res->code, 404;
+
+ $res = $cb->(GET "/foo.css");
+ is $res->code, 200;
+ is $res->content_type, 'text/css';
+ like $res->content, qr/color: #4D926F;/;
+
+ $res = $cb->(GET "/bar.css");
+ is $res->code, 200;
+ is $res->content_type, 'text/css';
+ like $res->content, qr/float: left/;
+};
+
+done_testing;