File Coverage

blib/lib/MojoX/Renderer/IncludeLater.pm
Criterion Covered Total %
statement 3 19 15.7
branch 0 6 0.0
condition n/a
subroutine 1 4 25.0
pod 1 1 100.0
total 5 30 16.6


line stmt bran cond sub pod time code
1             package MojoX::Renderer::IncludeLater;
2              
3             our $VERSION = '0.02';
4              
5 1     1   1619 use Mojo::Base 'Mojolicious::Plugin';
  1         10232  
  1         9  
6              
7             our $counter = 0;
8              
9             sub register {
10 0     0 1   my ($self, $app) = @_;
11              
12             $app->helper(include_later => sub {
13 0     0     my ($self, $template) = (shift, shift);
14 0 0         my $args = scalar @_ % 2 == 0 ? { @_ } : shift;
15 0           my $key = "\0IL\0" . ++$counter . "\0";
16              
17 0           $self->stash->{'mojo.x.include_later'}->{$key} = [ $template, $args ];
18 0           return $key;
19 0           });
20              
21             $app->hook(after_render => sub {
22 0     0     my ($self, $output, $format) = @_;
23 0           while(my ($id) = $$output =~ /(\0IL\0\d+\0)/m) {
24 0           my ($template, $args) = @{$self->stash->{'mojo.x.include_later'}->{$id}};
  0            
25 0 0         my ($op, $format) = $app->renderer->render($self, { partial => 1, template => $template, $args ? %$args : () });
26 0 0         warn "Error rendering include_later" if !$op;
27 0           $id = quotemeta $id;
28 0           $$output =~ s/$id/$op/m;
29             }
30 0           });
31             }
32              
33             1;
34              
35             =encoding utf8
36              
37             =head1 NAME
38              
39             MojoX::Renderer::IncludeLater - A post processor to defer partial template rendering
40              
41             =head1 DESCRIPTION
42              
43             L is a L plugin which adds support for
44             deferring rendering of partial templates until the parent template rendering is complete.
45              
46             For example, this makes it possible to build up data during rendering (e.g. which
47             input fields are rendered) and then use that data to render an earlier part of a template.
48              
49             This should work with any L renderer, including L and
50             L.
51              
52             =head1 SYNOPSIS
53              
54             Example 'test' template:
55              
56             % stash('my_var') // 'my_var has not been set'
57              
58             Example page template:
59              
60            

Include later

61            

Include a template immediately

62             % include "test" # will render 'my_var has not been set'
63              
64            

Include a template later

65             % include_later "test" # will render 'foo'
66              
67            

Set a value the included template expects

68             % stash('test' => 'foo')
69              
70             Which will generate the following output:
71              
72            

Include later

73            

Include a template immediately

74             my_var has not been set
75              
76            

Include a template later

77             foo
78              
79            

Set a value the included template expects

80              
81             =head1 HELPERS
82              
83             This plugin creates the following L helpers:
84              
85             =head2 include_later
86              
87             Is identical to C but template inclusion happens after
88             the rest of the template has been rendered.
89              
90             =head1 HOOKS
91              
92             This plugin hooks into C to perform deferred template inclusion.
93              
94             =head1 SEE ALSO
95              
96             L
97              
98             =cut
99