diff options
-rw-r--r-- | lib/Plack/Middleware/File/Less.pm | 76 | ||||
-rw-r--r-- | t/bar.css | 4 | ||||
-rw-r--r-- | t/foo.less | 9 | ||||
-rw-r--r-- | t/less.t | 28 |
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; |