File Coverage

blib/lib/Plack/Middleware/File/Less.pm
Criterion Covered Total %
statement 48 57 84.2
branch 8 12 66.6
condition n/a
subroutine 12 13 92.3
pod 2 4 50.0
total 70 86 81.4


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