File Coverage

blib/lib/Template/Lace/Factory.pm
Criterion Covered Total %
statement 48 52 92.3
branch 4 6 66.6
condition 1 3 33.3
subroutine 16 17 94.1
pod 0 9 0.0
total 69 87 79.3


line stmt bran cond sub pod time code
1             package Template::Lace::Factory;
2              
3 1     1   1014 use Moo;
  1         3  
  1         12  
4 1     1   560 use Module::Runtime 'use_module';
  1         4  
  1         10  
5              
6 7     7 0 30 sub DOM_CLASS { use_module 'Template::Lace::DOM' }
7 7     7 0 34 sub RENDERER_CLASS { use_module 'Template::Lace::Renderer' }
8 7     7 0 26 sub COMPONENTS_CLASS { use_module 'Template::Lace::Components' }
9              
10             has 'model_class' => (
11             is=>'ro',
12             required=>1);
13              
14             has 'model_constructor' => (
15             is=>'ro',
16             required=>0,
17             predicate=>'has_model_constructor');
18              
19             has 'renderer_class' => (
20             is=>'ro',
21             required=>1,
22             default=>sub { RENDERER_CLASS } );
23              
24             has 'dom' => (
25             is=>'ro',
26             required=>1);
27              
28             has 'init_args' => (
29             is=>'ro',
30             required=>1,
31             default=>sub { +{} });
32              
33             has 'components' => (
34             is=>'ro',
35             required=>1);
36              
37             around BUILDARGS => sub {
38             my ($orig, $class, @args) = @_;
39             my $args = $class->$orig(@args);
40             my $model_class = $class->_get_model_class($args);
41             my $dom_class = $class->_get_dom_class($args);
42             my $components_class = $class->_get_components_class($args);
43             my $dom = $args->{dom} = $class->_build_dom($dom_class, $model_class);
44             my $component_handlers = $args->{component_handlers};
45             $args->{components} = $class->_build_components(
46             $components_class,
47             $model_class,
48             $dom,
49             $component_handlers);
50             return $args;
51             };
52              
53             sub _get_model_class {
54 7     7   28 my ($class, $args) = @_;
55 7         49 my $model_class = use_module($args->{model_class});
56 7         375 return $model_class;
57             }
58              
59             sub _get_dom_class {
60 7     7   27 my ($class, $args) = @_;
61             my $dom_class = exists $args->{dom_class} ?
62 7 50       42 use_module($args->{dom_class}) :
63             DOM_CLASS;
64 7         308 return $dom_class;
65             }
66              
67             sub _get_components_class {
68 7     7   24 my ($class, $args) = @_;
69             my $components_class = exists $args->{components_class} ?
70 7 50       42 use_module($args->{components_class}) :
71             COMPONENTS_CLASS;
72 7         234 return $components_class;
73             }
74              
75             sub _build_dom {
76 7     7   27 my ($class, $dom_class, $model_class) = @_;
77 7         90 my $template = $model_class->template;
78 7         81 my $dom = $dom_class->new($template);
79 7 100       7263 $model_class->prepare_dom($dom) if $model_class->can('prepare_dom');
80 7         40 return $dom;
81             }
82              
83             sub _build_components {
84 7     7   31 my ($class, $components_class, $model_class, $dom, $component_handlers) = @_;
85 7         203 my $components = $components_class->new(
86             dom => $dom,
87             model_class => $model_class,
88             component_handlers => $component_handlers);
89 7         275 return $components;
90             }
91              
92             sub create {
93 8     8 0 776 my ($self, @args) = @_;
94 8         72 my %args = $self->prepare_args(@args);
95 8         51 my $dom = $self->create_dom(%args);
96 8         51 my $model = $self->create_model(%args);
97 8         56 my $renderer = $self->create_renderer(
98             $model,
99             $dom,
100             $self->components);
101 8         57 return $renderer;
102             }
103              
104             sub render {
105 0     0 0 0 my ($self, @args) = @_;
106 0         0 my $renderer = $self->create(@args);
107 0         0 my $response = $renderer->render;
108 0         0 return $response;
109             }
110              
111             sub prepare_args {
112 8     8 0 41 my ($self, @args) = @_;
113 8         20 my %args = (%{$self->init_args}, @args);
  8         78  
114 8         66 return %args;
115             }
116              
117             sub create_dom {
118 8     8 0 47 my ($self, %args) = @_;
119 8         66 my $dom = $self->dom->clone;
120 8         46 return $dom;
121             }
122              
123             sub create_model {
124 8     8 0 49 my ($self, %args) = @_;
125             my $model = eval {
126             $self->has_model_constructor ?
127             $self->model_constructor->($self->model_class, %args) :
128             $self->model_class->new(%args);
129 8   33     24 } || do {
130 1     1   1638 use Data::Dumper;
  1         3  
  1         256  
131             my $args = Dumper(\%args);
132             die "Cannot construct instance for ${\$self->model_class} with args $args: $@";
133             };
134 8         11190 return $model;
135             }
136              
137              
138             sub create_renderer {
139 8     8 0 33 my ($self, $model, $dom, $components) = @_;
140 8         240 my $renderer = $self->renderer_class->new(
141             model=>$model,
142             components=>$components,
143             dom=>$dom);
144 8         2230 return $renderer;
145             }
146              
147             1;
148              
149             =head1 NAME
150              
151             Template::Lace::Factory - Create templates
152              
153             =head1 SYNOPSIS
154              
155             TBD
156              
157             =head1 DESCRIPTION
158              
159             Produces Templates from a model.
160              
161             =head1 INITIALIZATION ARGUMENTS
162              
163             This class defines the following initialization arguments
164              
165             =head2 model_class
166              
167             The class that is providing the view model and does the interface
168             defined by L<Template::Lace::ModelRole>
169              
170             =head2 model_constructor
171              
172             An optional codereference that allows you to specify how the C<model_class>
173             it turned into an instance. By default we call a method called C<new>
174             on the C<model_class>. If you have special needs in creating the model
175             you can define this coderef which gets the C<model_class> and initialization
176             arguments and should return an instance. For example:
177              
178             model_constructor => sub {
179             my ($model_class, %args) = @_:
180             return $model_class->new( version=>1, %args);
181             },
182              
183             =head2 renderer_class
184              
185             The name of the Render class. useful if you need to subclass to provide
186             special feeatures.
187              
188             =head2 init_args
189              
190             A hashref of arguments that are fixed and are always passed to the model
191             constructor at create time. Useful if your model class has some attributes
192             which only need to be defined once.
193              
194             =head2 component_mappings
195              
196             A Hashref of component information. For now see the core documentation at
197             L<Template::Lace> for details about components.
198              
199             =head1 SEE ALSO
200            
201             L<Template::Lace>.
202              
203             =head1 AUTHOR
204              
205             Please See L<Template::Lace> for authorship and contributor information.
206            
207             =head1 COPYRIGHT & LICENSE
208            
209             Please see L<Template::Lace> for copyright and license information.
210              
211             =cut