File Coverage

blib/lib/Labyrinth/Writer.pm
Criterion Covered Total %
statement 19 21 90.4
branch n/a
condition n/a
subroutine 7 7 100.0
pod n/a
total 26 28 92.8


line stmt bran cond sub pod time code
1             package Labyrinth::Writer;
2              
3 6     6   27 use warnings;
  6         7  
  6         185  
4 6     6   23 use strict;
  6         9  
  6         158  
5              
6 6     6   20 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
  6         4  
  6         502  
7             $VERSION = '5.30';
8              
9             =head1 NAME
10              
11             Labyrinth::Writer - Output Management for Labyrinth
12              
13             =head1 SYNOPSIS
14              
15             use Labyrinth::Writer;
16             Publish('mytemplate.html');
17             PublishCode('MESSAGE');
18              
19             =head1 DESCRIPTION
20              
21             The Publish package contains one function, Publish(), which handles
22             the parsing of a given template with global variables and prints the result.
23              
24             =head1 EXPORT
25              
26             Publish
27             PublishCode
28             UnPublish
29             Transform
30             Croak
31              
32             =cut
33              
34             # -------------------------------------
35             # Export Details
36              
37             require Exporter;
38             @ISA = qw( Exporter );
39             @EXPORT_OK = qw( Publish PublishCode UnPublish Transform Croak );
40             @EXPORT = qw( Publish PublishCode UnPublish Transform Croak );
41              
42             # -------------------------------------
43             # Library Modules
44              
45 6     6   24 use File::Basename;
  6         15  
  6         378  
46 6     6   2673 use MIME::Types;
  6         26479  
  6         290  
47              
48 6     6   49 use Labyrinth::Audit;
  6         9  
  6         883  
49 6     6   2718 use Labyrinth::Globals;
  0            
  0            
50             use Labyrinth::Variables;
51             use Labyrinth::MLUtils;
52              
53             # -------------------------------------
54             # Variables
55              
56             my ($PARSER,$RENDER);
57              
58             my $published;
59              
60             my %codes = (
61             BADLAYOUT => 'public/badlayout.html',
62             BADPAGE => 'public/badpage.html',
63             BADCMD => 'public/badcommand.html',
64             MESSAGE => 'public/error_message.html',
65             );
66              
67             my %binary = (
68             pdf => 'application/pdf'
69             );
70              
71             my %knowntypes = (
72             html => 'text/html',
73             ics => 'text/calendar',
74             #js => 'application/javascript',
75             js => 'text/html',
76             json => 'application/json',
77             rss => 'application/xml',
78             txt => 'text/plain',
79             xml => 'application/xml',
80             yml => 'text/yaml',
81             yaml => 'text/yaml'
82             );
83              
84             # -------------------------------------
85             # The Subs
86              
87             =head1 FUNCTIONS
88              
89             =over 4
90              
91             =item Config()
92              
93             Configure template parser and output method.
94              
95             =cut
96              
97             sub Config {
98             $settings{'writer-parser'} ||= 'TT';
99             $settings{'writer-render'} ||= 'CGI';
100              
101             my $parser = 'Labyrinth::Writer::Parser::' . $settings{'writer-parser'};
102             my $render = 'Labyrinth::Writer::Render::' . $settings{'writer-render'};
103              
104             eval {
105             eval "CORE::require $parser";
106             $PARSER = $parser->new();
107             };
108             die "Cannot load Writer::Parser package for '$settings{'writer-parser'}': $@" if($@);
109              
110             eval {
111             eval "CORE::require $render";
112             $RENDER = $render->new();
113             };
114             die "Cannot load Writer::Render package for '$settings{'writer-render'}': $@" if($@);
115              
116             }
117              
118             =item Publish()
119              
120             Publish() parses a given template, via Template Toolkit, and prints the
121             result.
122              
123             =item PublishCode
124              
125             Publishes a template based on an internal code. Current codes and associated
126             templates are:
127              
128             BADLAYOUT => 'public/badlayout.html',
129             BADPAGE => 'public/badpage.html',
130             BADCMD => 'public/badcommand.html',
131             MESSAGE => 'public/error_message.html',
132              
133             TODO: Provide these and more as configurable codes.
134              
135             =item UnPublish
136              
137             Used to reset publishing status. Usually only applicable in mod_perl
138             environments.
139              
140             =item Transform
141              
142             Given a template and a set of variables, parse without publishing the content.
143              
144             =cut
145              
146             sub Publish {
147             return if($published);
148              
149             Config() unless($PARSER && $RENDER);
150              
151             # redirects require minimal processing
152             if($tvars{redirect} && $tvars{redirect} ne $tvars{request}) {
153             $RENDER->redirect($tvars{redirect});
154             $published = 1;
155             return;
156             }
157              
158             # binary files handled directly
159             if($tvars{contenttype} && $binary{$tvars{contenttype}}) {
160             $tvars{'writer'} = { 'ctype' => $binary{$tvars{'contenttype'}}, 'file' => $tvars{'file'} };
161             $RENDER->binary($tvars{'writer'});
162             $published = 1;
163             return;
164             }
165              
166             my $path = $settings{'templates'} || '';
167             my $vars = \%tvars;
168              
169             unless($vars->{'layout'} && -r "$path/$vars->{'layout'}") {
170             $vars->{'badlayout'} = $vars->{'layout'};
171             $vars->{'layout'} = $codes{BADLAYOUT};
172             }
173             unless($vars->{'content'} && -r "$path/$vars->{'content'}") {
174             $vars->{'badcontent'} = $vars->{'content'};
175             $vars->{'content'} = $codes{BADPAGE};
176             }
177             my $layout = $vars->{'layout'};
178             my $content = $vars->{'content'};
179              
180             # LogDebug( "layout=[$layout]" );
181             # LogDebug( "content=[$content]" );
182             # LogDebug( "cookie=[$vars->{cookie}]" ) if($vars->{cookie});
183             # use Data::Dumper;
184             # LogDebug( "vars=".Dumper($vars) );
185              
186              
187             $vars->{evalperl} = ($content eq $codes{BADPAGE} ? 1 : 0);
188              
189             #LogDebug("");
190              
191             my $output;
192             eval { $output = $PARSER->parser($layout,$vars) };
193             if($@ || !$output) {
194             LogDebug( "template error=$@" );
195             $$output = $@;
196             }
197              
198             my ($ext) = $layout =~ m/\.(\w+)$/;
199             $ext ||= 'html';
200              
201             # split HTML and process etc
202             if($ext =~ /htm/) {
203             if(defined $settings{parsehtml} && $settings{parsehtml}) {
204             my ($top,$body,$tail) = ($$output =~ m!^(.*?]*>)(.*?)(.*)$!si);
205             # LogDebug( "parsehtml=[$settings{parsehtml}]" );
206             # LogDebug( "html=[$html]" );
207             # LogDebug( "top=[$top]" );
208             # LogDebug( "tail=[$tail]" );
209             # LogDebug( "body=[$body]" );
210             my $html = $top . process_html($body,0,1) . $tail;
211              
212             if($settings{parsetest}) {
213             DumpToFile($settings{parsetest},"=== ORIGINAL ===",$$output,"=== PROCESSED ===",$html,"=== END ===");
214             }
215             $output = \$html;
216             }
217             }
218              
219             $tvars{headers}{type} = $knowntypes{$ext} || do {
220             my $types = MIME::Types->new;
221             my $mime = $types->mimeTypeOf($ext);
222             $mime->type || 'text/html';
223             };
224              
225             $tvars{headers}{'charset'} = 'utf-8';
226             $tvars{headers}{'status'} = '404 Page Not Found' if($content eq $codes{BADPAGE} || $content eq $codes{BADCMD});
227             $tvars{headers}{'cookie'} = $tvars{cookie} if($tvars{cookie});
228             $tvars{headers}{'attachment'} = basename($content) if($layout =~ /\.ics$/);
229              
230             $published = 1;
231              
232             return $RENDER->publish($tvars{headers}, $output);
233             }
234              
235             sub PublishCode {
236             $tvars{'content'} = $codes{$_[0]};
237             return Publish();
238             }
239              
240             sub UnPublish {
241             $published = 0;
242             }
243              
244             sub Transform {
245             my ($template,$vars,$file,$binary) = @_;
246              
247             my $path = $settings{'templates'};
248             my $layout = "$path/$template";
249              
250             die "Missing template [$layout]\n" unless(-e $layout);
251              
252             Config() unless($PARSER && $RENDER);
253              
254             if($file) {
255             $PARSER->parse_to_file($layout,$vars,$file,$binary);
256             return;
257             }
258              
259             my $output = $PARSER->parser($layout,$vars);
260             return $$output;
261             }
262              
263             =item Croak
264              
265             A shorthand call to publish and record errors.
266              
267             =cut
268              
269             sub Croak {
270             my $errmess = join(" ",@_);
271             LogError($errmess);
272             print STDERR "$errmess\n";
273             PublishCode('MESSAGE');
274             exit;
275             }
276              
277             1;
278              
279             __END__