File Coverage

blib/lib/HTML/FormHandler/Blocks.pm
Criterion Covered Total %
statement 50 63 79.3
branch 11 24 45.8
condition 9 11 81.8
subroutine 10 11 90.9
pod 0 4 0.0
total 80 113 70.8


line stmt bran cond sub pod time code
1             package HTML::FormHandler::Blocks;
2             # ABSTRACT: arrange form layout using blocks
3             $HTML::FormHandler::Blocks::VERSION = '0.40068';
4              
5 143     143   118497 use Moose::Role;
  143         418  
  143         1367  
6 143     143   787906 use Try::Tiny;
  143         403  
  143         10152  
7 143     143   923 use Class::Load qw/ load_optional_class /;
  143         379  
  143         6095  
8 143     143   899 use namespace::autoclean;
  143         366  
  143         1522  
9 143     143   11872 use Data::Clone;
  143         1473  
  143         6527  
10 143     143   74374 use HTML::FormHandler::Widget::Block;
  143         537  
  143         104000  
11              
12             has 'blocks' => (
13             isa => 'HashRef[Object]',
14             is => 'ro',
15             lazy => 1,
16             traits => ['Hash'],
17             builder => 'build_blocks',
18             handles => {
19             has_blocks => 'count',
20             add_block => 'set',
21             block => 'get',
22             block_exists => 'exists',
23             },
24             );
25 10     10 0 305 sub build_blocks { {} }
26              
27             has 'block_list' => ( is => 'rw', isa => 'ArrayRef', lazy => 1, builder => 'build_block_list' );
28 243     243 0 6632 sub build_block_list {[]}
29              
30             has 'render_list' => (
31             is => 'rw',
32             isa => 'ArrayRef[Str]',
33             traits => ['Array'],
34             lazy => 1,
35             builder => 'build_render_list',
36             handles => {
37             has_render_list => 'count',
38             add_to_render_list => 'push',
39             all_render_list => 'elements',
40             get_render_list => 'get',
41             }
42             );
43              
44             sub get_renderer {
45 0     0 0 0 my ( $self, $name ) = @_;
46 0 0       0 die "must provide a name to get_renderer" unless $name;
47 0         0 my $obj = $self->block($name);
48 0 0       0 return $obj if ref $obj;
49 0         0 $obj = $self->field_from_index($name);
50 0 0       0 return $obj if ref $obj;
51 0         0 die "did not find a field or block with name $name\n";
52             }
53              
54             after '_build_fields' => sub {
55             my $self = shift;
56              
57             my $meta_blist = $self->_build_meta_block_list;
58             if( @$meta_blist ) {
59             foreach my $block_attr (@$meta_blist) {
60             $self->make_block($block_attr);
61             }
62             }
63             my $blist = $self->block_list;
64             if( @$blist ) {
65             foreach my $block_attr (@$blist) {
66             $self->make_block($block_attr);
67             }
68             }
69             };
70              
71             sub make_block {
72 22     22 0 70 my ( $self, $block_attr ) = @_;
73              
74 22   100     135 my $type = $block_attr->{type} ||= '';
75 22         56 my $name = $block_attr->{name};
76 22 50       66 die "You must supply a name for a block" unless $name;
77              
78 22         49 my $do_update;
79 22 50       80 if ( $name =~ /^\+(.*)/ ) {
80 0         0 $block_attr->{name} = $name = $1;
81 0         0 $do_update = 1;
82             }
83              
84 22         41 my $class;
85 22 100       68 if( $type ) {
86 5         29 $class = $self->get_widget_role($type, 'Block');
87             }
88             else {
89 17         39 $class = 'HTML::FormHandler::Widget::Block';
90             }
91              
92 22 50       17223 $block_attr->{form} = $self->form if $self->form;
93              
94 22         78 my $block = $self->form->block( $block_attr->{name} );
95 22 50 33     97 if ( defined $block && $do_update ) {
96 0         0 delete $block_attr->{name};
97 0         0 foreach my $key ( keys %{$block_attr} ) {
  0         0  
98 0 0       0 $block->$key( $block_attr->{$key} )
99             if $block->can($key);
100             }
101             }
102             else # new block
103             {
104 22         239 $block = $class->new(%$block_attr);
105 22         27302 $self->add_block( $name, $block );
106             }
107             }
108              
109             # loops through all inherited classes and composed roles
110             # to find blocks specified with 'has_block'
111             sub _build_meta_block_list {
112 245     245   678 my $self = shift;
113 245         618 my @block_list;
114              
115 245         2027 foreach my $sc ( reverse $self->meta->linearized_isa ) {
116 988         13039 my $meta = $sc->meta;
117 988 50       19816 if ( $meta->can('calculate_all_roles') ) {
118 988         3267 foreach my $role ( reverse $meta->calculate_all_roles ) {
119 2767 100 100     27035 if ( $role->can('block_list') && $role->has_block_list ) {
120 1         2 foreach my $block_def ( @{ $role->block_list } ) {
  1         29  
121 3         7 push @block_list, $block_def;
122             }
123             }
124             }
125             }
126 988 100 100     33667 if ( $meta->can('block_list') && $meta->has_block_list ) {
127 7         17 foreach my $block_def ( @{ $meta->block_list } ) {
  7         206  
128 13         42 push @block_list, $block_def;
129             }
130             }
131             }
132 245         2811 return clone( \@block_list );
133             }
134              
135              
136             1;
137              
138             __END__
139              
140             =pod
141              
142             =encoding UTF-8
143              
144             =head1 NAME
145              
146             HTML::FormHandler::Blocks - arrange form layout using blocks
147              
148             =head1 VERSION
149              
150             version 0.40068
151              
152             =head1 SYNOPSIS
153              
154             This is a role which provides the ability to render your form in
155             arbitrary 'blocks', instead of by fields. This role is included
156             by default in HTML::FormHandler.
157              
158             package MyApp::Form;
159             use HTML::FormHandler::Moose;
160             extends 'HTML::FormHandler';
161              
162             sub build_render_list {[ 'foo', 'fset' ]}
163             has_field 'foo';
164             has_field 'bar';
165             has_field 'nox';
166             has_block 'fset' => ( tag => 'fieldset', render_list => ['bar', 'nox'] );;
167             ....
168             $form->render;
169              
170             Blocks live in the HTML::FormHandler::Widget::Block:: namespace. The default,
171             non-typed block is L<HTML::FormHandler::Widget::Block>. Provide a type for
172             custom blocks:
173              
174             has_block 'my_block' => ( type => 'CustomBlock', render_list => [...] );
175              
176             You can also build blocks with a 'block_list' attribute, or the builder for it,
177             'build_block_list'.
178              
179             Rendering with blocks is supported by the rendering widgets. Render::Simple doesn't
180             do it, though it would be possible to make your own custom renderer.
181              
182             =head1 AUTHOR
183              
184             FormHandler Contributors - see HTML::FormHandler
185              
186             =head1 COPYRIGHT AND LICENSE
187              
188             This software is copyright (c) 2017 by Gerda Shank.
189              
190             This is free software; you can redistribute it and/or modify it under
191             the same terms as the Perl 5 programming language system itself.
192              
193             =cut