File Coverage

blib/lib/Mojolicious/Plugin/RenderCGI.pm
Criterion Covered Total %
statement 52 55 94.5
branch 23 28 82.1
condition 11 22 50.0
subroutine 7 7 100.0
pod 1 3 33.3
total 94 115 81.7


line stmt bran cond sub pod time code
1             package Mojolicious::Plugin::RenderCGI;
2              
3 1     1   897 use Mojo::Base 'Mojolicious::Plugin';
  1         3  
  1         10  
4 1     1   815 use Mojolicious::Plugin::RenderCGI::Template;
  1         4  
  1         14  
5 1     1   46 use Mojo::Util qw(encode md5_sum);
  1         2  
  1         1180  
6              
7             our $VERSION = '0.102';
8             my $pkg = __PACKAGE__;
9              
10             has qw(app);
11             has handler_name => 'cgi.pl';
12             has default => 0;
13             has cgi_import => sub { [qw(:html :form)] };
14             has exception => sub { {'handler'=>'ep', 'layout' => undef,} };
15             has cache => sub { {} };
16              
17             sub register {
18 2     2 1 5392 my ($plugin, $app, $conf) = @_;
19            
20 2         10 $plugin->app($app);
21            
22 2         31 map $plugin->$_($conf->{$_}), grep defined($conf->{$_}), qw(name default import exception);
23             #~ $app->renderer->default_handler($plugin->handler_name) не работает
24 2 50 50     45 $app->log->debug("Set default render handler ".$plugin->handler_name)
25             and $app->defaults('handler'=>$plugin->handler_name)
26             if $plugin->default;
27            
28             $app->renderer->add_handler(
29 14     14   132810 $plugin->handler_name => sub {$plugin->handler(@_)}
30 2         855 );
31             }
32              
33             sub handler {
34 14     14 0 49 my ($plugin, $renderer, $c, $output, $options) = @_;
35 14         40 my $app = $c->app;
36             #~ $app->log->debug($app->dumper($options));
37            
38             # относительный путь шаблона
39 14         68 my $content = $options->{inline};# встроенный шаблон
40 14 100       92 my $name = defined $content ? md5_sum encode('UTF-8', $content) : undef;
41 14 50 33     88 return unless defined($name //= $renderer->template_path($options) || $renderer->template_name($options));
      66        
42            
43             #~ my $url = Mojo::URL->new($name);
44             #~ ($name, my $param) = (url_unescape($url->path), $url->query->to_hash);
45             #~ utf8::decode($name);
46            
47 14         1866 my ($template, $from) = ($plugin->cache->{$name}, 'cache');# подходящий шаблон из кэша
48            
49 14         115 my $stash = $c->stash($pkg);
50 14 100       202 $c->stash($pkg => {stack => []})
51             unless $stash;
52 14   66     202 $stash ||= $c->stash($pkg);
53 14         103 my $last_template = $stash->{stack}[-1];
54             #~ if ($last_template && $last_template eq $name) {
55             #~ $$output = $plugin->error("Stop looping template [$name]!", $c);
56             #~ return;
57             #~ }
58 14         26 push @{$stash->{stack}}, $name;
  14         43  
59            
60 14         30 $$output = '';
61            
62 14 100       39 unless ($template) {#не кэш
63 13 100       29 if (defined $content) {# инлайн
64 1         2 $from = 'inline';
65             } else {
66             # подходящий шаблон в секции DATA
67 12         77 ($content, $from) = ($renderer->get_data_template($options), 'DATA section');#,, $name
68            
69 12 100       364 unless (defined $content) {# file
70             # абсолютный путь шаблона
71 3 50       9 if (my $path = $renderer->template_path($options)) {
72 0         0 my $file = Mojo::Asset::File->new(path => $path);
73 0         0 ($content, $from) = ($file->slurp, 'file');
74            
75             } else {
76 3         306 $$output = $plugin->error(sprintf(qq{Template "%s" does not found}, $name), $c);
77 3         37 return;
78             }
79             }
80             }
81            
82 10 100 50     56 $app->log->debug(sprintf(qq{Empty or nothing template "%s"}, $name))
83             and return
84             unless $content =~ /\w/;
85            
86 7         34 utf8::decode($content);
87            
88 7         26 $template = Mojolicious::Plugin::RenderCGI::Template->new(_import=>$plugin->cgi_import, _plugin=>$plugin, );
89              
90 7         33 my $err = $template->_compile($content);
91            
92 7 100 50     35 $$output = $plugin->error(sprintf(qq{Compile time error for template "%s" from the %s: %s}, $name, $from, $err), $c)
93             and return
94             unless ref $err; # ref success
95            
96             }
97            
98 7         26 $app->log->debug(sprintf(qq{Rendering template "%s" from the %s}, $name, $from,));
99 7   66     1437 $plugin->cache->{$name} ||= $template;
100            
101 7         79 my @out = eval { $template->_run($c)};
  7         30  
102 7 100 50     2499 $$output = $plugin->error(sprintf(qq{Runtime error for template "%s" from the %s:\n%s}, $name, $from, $@), $c)
103             and return
104             if $@;
105            
106 6         69 $$output = join "\n", grep defined, @out;
107            
108             }
109              
110             sub error {# харе
111 5     5 0 73 my ($plugin, $error, $c) = @_;
112 5 50 0     20 $c->stash(%{$plugin->exception})
  0         0  
113             and die $error
114             if ref($plugin->exception) eq 'HASH';
115            
116 5         49 $c->app->log->error($error);# лог после die!
117 5 100       956 return $error
118             if $plugin->exception eq 'template';
119            
120 1 50       10 return ""
121             if $plugin->exception =~ m'comment';
122             };
123              
124             1;
125              
126              
127             =pod
128              
129             =encoding utf8
130              
131             Доброго всем
132              
133             =head1 Mojolicious::Plugin::RenderCGI
134              
135             ¡ ¡ ¡ ALL GLORY TO GLORIA ! ! !
136              
137             =head1 NAME
138              
139             Mojolicious::Plugin::RenderCGI - Rendering Mojoliciuos template by CGI.pm subs as tags.
140              
141             =head1 SYNOPSIS
142              
143             $app->plugin('RenderCGI');
144              
145             =head1 Template
146              
147             Template is a Perl code that generate content as list of statements. Similar to C. Template file name like "templates/foo/bar.html.cgi.pl"
148              
149             # There are predefined variables:
150             # $self is a Mojolicious::Plugin::RenderCGI::Template object
151             # $c is a current controller object
152             # $cgi is a CGI object
153            
154             $c->layout('default', handler=>'ep',);# set handler 'ep' for all templates/includes !!! even default handler cgi
155             my $foo = $c->stash('foo')
156             or die "Where is your FOO?";
157            
158             #=======================================
159             #======= content comma list! ===========
160             #=======================================
161            
162             h1({}, "Welcome"),# but this template handlered CGI
163             div({-class=>"container"},
164             span('Okay here'),
165             p(['blah', 'blaz']),
166             ),
167            
168             $c->include('foo', handler=>'cgi.pl'),# change handler against layout
169             $c->include('bar'); # handler still "ep" unless template "foo" (and its includes) didn`t changes it by $c->stash('handler'=>...)
170            
171             <
172            
173             END_HTML
174            
175             $self->app->log->info("Template has done")
176             && undef,
177              
178             There are NO Mojolicious helpers without OO-style prefixes: C<< $c-> >>.
179              
180             B Escapes untrusted data. No auto escapes!
181              
182             div({}, esc(...UNTRUSTED DATA...)),
183              
184             C is a shortcut for &CGI::escapeHTML.
185              
186             =head1 NOTE about autoloading subs and methods
187              
188             In template you can generate any tag:
189              
190             # ...
191             foo_tag({-class=>"class1",}, '...'),
192             # same
193             $self->foo_tag({-class=>"class1",}, '...'),
194              
195             =head1 OPTIONS
196              
197             =head2 handler_name ( string )
198              
199             # Mojolicious::Lite
200             plugin RenderCGI => {handler_name => 'pl'};
201              
202             Handler name, defaults to B.
203              
204             =head2 default (bool)
205              
206             When C then default handler. Defaults - 0 (no this default handler for app).
207              
208             default => 1,
209              
210             Is similar to C<< $app->defaults(handler=> ); >>
211              
212             =head2 cgi_import ( string (space delims) | arrayref )
213              
214             What subs do you want from CGI.pm import
215              
216             $app->plugin('RenderCGI', cgi_import=>':html ...');
217             # or
218             $app->plugin('RenderCGI', cgi_import=>[qw(:html ...)]);
219              
220             See at perldoc CGI.pm section "USING THE FUNCTION-ORIENTED INTERFACE".
221             Default is ':html :form' (string) same as [qw(:html :form)] (arrayref).
222              
223             cgi_import=>[], # none import subs CGI
224              
225             =head2 exception ( string | hashref )
226              
227             To show fatal errors (not found, compile and runtime errors) as content of there template you must set string B