File Coverage

blib/lib/Plack/Middleware/File/Less.pm
Criterion Covered Total %
statement 24 58 41.3
branch 0 12 0.0
condition n/a
subroutine 8 13 61.5
pod 2 4 50.0
total 34 87 39.0


line stmt bran cond sub pod time code
1             package Plack::Middleware::File::Less;
2              
3             # ABSTRACT: LESS CSS support
4              
5 1     1   31395 use strict;
  1         2  
  1         26  
6 1     1   4 use warnings;
  1         1  
  1         20  
7 1     1   28 use 5.008_001;
  1         5  
  1         60  
8             our $VERSION = '0.02';
9              
10 1     1   4 use parent qw(Plack::Middleware);
  1         1  
  1         6  
11 1     1   1142 use Plack::Util;
  1         2  
  1         18  
12 1     1   5 use Plack::Util::Accessor qw(less);
  1         2  
  1         4  
13 1     1   1013 use IPC::Open3 qw(open3);
  1         2733  
  1         51  
14 1     1   6 use Carp;
  1         1  
  1         405  
15              
16             sub prepare_app {
17 0     0 1   my $self = shift;
18 0           $self->less(\&less_command);
19 0           my $less = `lessc -v`;
20 0 0         if ($less) {
    0          
21 0           $self->less(\&less_command);
22 0           } elsif (eval { require CSS::LESSp }) {
23 0           $self->less(\&less_perl);
24             } else {
25 0           Carp::croak("Can't find lessc command nor CSS::LESSp module");
26             }
27             }
28              
29             sub less_command {
30 0     0 0   my $less = shift;
31 0           my $pid = open3(my $in, my $out, my $err, "lessc", "-");
32 0           print $in $less;
33 0           close $in;
34              
35 0           my $buf = join '', <$out>;
36 0           waitpid $pid, 0;
37              
38 0           return $buf;
39             }
40              
41             sub less_perl {
42 0     0 0   return join "", CSS::LESSp->parse(shift);
43             }
44              
45             sub call {
46 0     0 1   my ($self, $env) = @_;
47              
48 0           my $orig_path_info = $env->{PATH_INFO};
49 0 0         if ($env->{PATH_INFO} =~ s/\.css$/.less/i) {
50 0           my $res = $self->app->($env);
51              
52 0 0         return $res unless ref $res eq 'ARRAY';
53              
54 0 0         if ($res->[0] == 200) {
    0          
55 0           my $less;
56 0     0     Plack::Util::foreach($res->[2], sub { $less .= $_[0] });
  0            
57              
58 0           my $css = $self->less->($less);
59              
60 0           my $h = Plack::Util::headers($res->[1]);
61 0           $h->set('Content-Type' => 'text/css');
62 0           $h->set('Content-Length' => length $css);
63              
64 0           $res->[2] = [$css];
65             }
66             elsif ($res->[0] == 404) {
67 0           $env->{PATH_INFO} = $orig_path_info;
68 0           $res = $self->app->($env);
69             }
70              
71 0           return $res;
72             }
73 0           return $self->app->($env);
74             }
75              
76             1;
77              
78             =head1 SYNOPSIS
79              
80             use Plack::App::File;
81             use Plack::Builder;
82              
83             builder {
84             mount "/stylesheets" => builder {
85             enable "File::Less";
86             Plack::App::File->new(root => "./stylesheets");
87             };
88             };
89              
90             # Or with Middleware::Static
91             enable "File::Less";
92             enable "Static", path => qr/\.css$/, root => "./static";
93              
94             =head1 DESCRIPTION
95              
96             Plack::Middleware::File::Less is middleware that compiles
97             L templates into CSS stylesheet..
98              
99             When a request comes in for I<.css> file, this middleware changes the
100             internal path to I<.less> in the same directory. If the LESS template
101             is found, a new CSS stylesheet is built on memory and served to the
102             browsers. Otherwise, it falls back to the original I<.css> file in
103             the directory.
104              
105             =head1 LESS BACKENDS
106              
107             If you have the C executable available in your PATH, this
108             module automatically uses the command to convert LESS into CSS. If the
109             command is not available and you have L perl module
110             available, it will be used. Otherwise you'll get an exception during
111             the initialization of this middleware component.
112              
113             =head1 SEE ALSO
114              
115             L L L
116              
117             =head1 AUTHORS
118              
119             =over 4
120              
121             =item *
122              
123             Naoya Ito i.naoya@gmail.com
124              
125             =item *
126              
127             Franck Cuny https://github.com/franckcuny
128              
129             =item *
130              
131             Tatsuhiko Miyagawa miyagawa@bulknews.net
132              
133             =back
134              
135             =head1 LICENSE
136              
137             This library is free software; you can redistribute it and/or modify it
138             under the same terms as Perl itself.
139              
140             =cut