/[Frey]/trunk/lib/Frey/Action.pm
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /trunk/lib/Frey/Action.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 768 - (show annotations)
Tue Dec 9 20:31:30 2008 UTC (15 years, 4 months ago) by dpavlin
File size: 6135 byte(s)
 r3627@llin (orig r746):  dpavlin | 2008-12-07 02:33:37 +0100
 Blame Newspeak for this: removed all action stuff because we don't really need it.
 
 Since we do double round trips with whole state to browser and back, it's enough just to separate second step into own package and put that into form action :-)
 

1 package Frey::Action;
2 use Moose;
3 extends 'Frey::PPI';
4 with 'Frey::Web';
5 with 'Frey::Config';
6
7 use Clone qw/clone/;
8 use Data::Dump qw/dump/;
9
10 =head1 DESCRIPTION
11
12 Invoke any L<Frey> object creating html for with various default parameters
13 if not supplied at invocation.
14
15 =cut
16
17 has 'class' => (
18 is => 'rw',
19 isa => 'Str',
20 required => 1,
21 );
22
23 has 'params' => (
24 is => 'rw',
25 isa => 'HashRef',
26 default => sub { {} },
27 );
28
29 =head2 required
30
31 my @required_attributes = $self->required;
32 my $required_attributes = $self->required;
33
34 =cut
35
36 sub required {
37 my ( $self ) = @_;
38 $self->load_class( $self->class );
39
40 my @required =
41 grep {
42 defined $_ && $_->can('name') &&
43 ! defined( $self->params->{ $_->name } ) &&
44 ! $_->is_lazy
45 }
46 map {
47 my $attr = $self->class->meta->get_attribute($_);
48 blessed $attr && $attr->is_required && $attr;
49 } $self->class->meta->get_attribute_list;
50
51 warn "## required = ",dump( map { $_->name } @required ), " for ", $self->class if @required && $self->debug;
52 return @required if wantarray;
53 return \@required;
54 }
55
56 =head2 attributes
57
58 Generated from attributes specified in code (extracted using L<Frey::PPI>)
59 and required atributes
60
61 my @class_attributes = $self->attributes;
62 my @class_attributes = $self->attributes;
63
64 =cut
65
66 sub attributes {
67 my ( $self ) = @_;
68 my $a;
69 my @attrs = @{ $self->attribute_order };
70 @attrs = map { $a->{$_}++; $_ } @attrs;
71 push @attrs, $_ foreach grep { ! $a->{$_} } map { $_->name } @{ $self->required };
72 warn "# attributes = ",dump( @attrs ) if $self->debug;
73 return @attrs if wantarray;
74 return \@attrs;
75 }
76
77 =head2 params_form
78
79 my $html = $self->params_form;
80 my ($html,$default_params) = $self->params_form;
81
82 =cut
83
84 sub params_form {
85 my ( $self ) = @_;
86 my @required = $self->required;
87 if ( ! @required ) {
88 warn "all params available ", dump( $self->params ), " not creating form" if $self->debug;
89 return (undef,$self->params) if wantarray;
90 return;
91 } else {
92 warn $self->class, " required params ", map { $_->dump(2) } @required if $self->debug;
93 }
94
95 my $class = $self->class;
96
97 $self->load_class( $class );
98
99 my $default = clone $self->params; # XXX we really don't want to modify params!
100
101 my $params_config = {};
102 $params_config = $self->config($class);
103 warn "# $class config = ",dump( $params_config ) if $self->debug;
104
105 my $form;
106
107 sub select_values {
108 my ( $name, $attr_type, $values ) = @_;
109
110 if ( $#$values > 3 ) {
111 my $options = join("\n",
112 map {
113 my $v = ref($_) eq 'HASH' ? $_->{$name} : $_;
114 qq|<option value="$v">$v</option>| if $v;
115 } @$values
116 );
117 qq|<select title="$attr_type" name="$name">$options</select>| if $options;
118 } else {
119 my $radio = join("\n",
120 map {
121 my $v = ref($_) eq 'HASH' ? $_->{$name} : $_;
122 qq|<input type="radio" name="$name" value="$v" title="$attr_type"><span style="float: left; padding-right: 2em;">$v</span>|;
123 } @$values
124 );
125 qq|<div>$radio</div>|;
126 }
127 }
128
129 foreach my $checkbox ( split(/\s+/, $default->{'frey-checkboxes'} ) ) {
130 next if defined $default->{ $checkbox };
131
132 $default->{ $checkbox } = 0;
133 $self->params->{ $checkbox } = 0;
134 warn "# checkbox $checkbox not ticked";
135 }
136
137 my @checkboxes;
138
139 my $label_width = 1; # minimum
140
141 foreach my $name (
142 grep {
143 ! $class->meta->get_attribute($_)->is_lazy
144 && ! defined $default->{$_}
145 && ! m{^_} # skip _private
146 } $self->attributes
147 ) {
148 my $attr_type = '';
149 my $type = $name =~ m/^pass/ ? 'password' : 'text';
150 my $label = $name;
151 my $label_title = '';
152 my $value_html = '';
153
154 my $attr = $class->meta->get_attribute( $name );
155 $attr_type = $attr->type_constraint->name if $attr->has_type_constraint;
156
157 my $value =
158 defined $default->{$name} ? $default->{$name} :
159 $attr->has_default ? $attr->default( $name ) :
160 '';
161
162 if ( ref($params_config) eq 'HASH' ) {
163 $value = $params_config->{$name};
164 } elsif ( ref($params_config) eq 'ARRAY' ) {
165 $value_html = select_values( $name, $attr_type, $params_config );
166 $default->{$name} = $params_config->[0]->{$name};
167 } elsif ( $attr->has_type_constraint && $attr->type_constraint->can('values') ) {
168 $value_html = select_values( $name, $attr_type, $attr->type_constraint->values );
169 } elsif ( $attr_type =~ m{^Bool} ) {
170 my $suffix = '';
171 $suffix = ' checked' if $value;
172 $value_html = qq|<input type="checkbox" name="$name" title="$attr_type" value="$value"$suffix>|;
173 push @checkboxes, $name;
174 } elsif ( ! defined $value ) {
175 $value_html = qq|<tt id="$name">undef</tt><!-- $name = undef -->|; # FIXME if $self->debug
176 } elsif ( $attr_type !~ m{^(Str|Int)$} || $value =~ $Frey::Web::re_html ) {
177 $value_html = qq|<textarea name="$name" title="$attr_type">$value</textarea>|;
178 }
179
180 $label_title = qq| title="| . $attr->documentation . qq|"| if $attr->has_documentation;
181
182 $default->{$name} = $value unless defined $default->{$name};
183
184 $value_html = qq|<input type="$type" name="$name" title="$attr_type" value="$value">| unless $value_html;
185
186 # warn "# required $name ", $class->meta->get_attribute( $name )->dump( 2 );
187 $form .= qq|<label for="$name"$label_title>$label</label>$value_html<br>|;
188 my $ll = length($label);
189 $label_width = $ll if $ll > $label_width;
190 }
191 $form .= qq|<input type="hidden" name="frey-checkboxes" value="| . join(' ', @checkboxes) . qq|">| if @checkboxes;
192
193 $self->add_css(qq|
194 label,input {
195 display: block;
196 float: left;
197 margin-bottom: 10px;
198 }
199
200 label {
201 text-align: right;
202 width: ${label_width}ex;
203 padding-right: 20px;
204 }
205
206 br {
207 clear: left;
208 }
209 |);
210
211 my $html;
212
213 # http://www.quirksmode.org/oddsandends/forms.html
214 # $form =~ s{<([^>]+)(name=")([^"]+)(")([^>]*)>}{<$1$2$3$4 id="$3" $5}gs;
215
216 $html = qq|
217 <h1>$class params</h1>
218 <form method="post">
219 $form
220 <input type="submit" value="Run $class">
221 </form>
222 | if $form;
223
224 $self->add_status({
225 $self->class => {
226 params => $self->params,
227 params_config => $params_config,
228 default => $default,
229 },
230 });
231
232 return ($html,$default) if wantarray;
233 return $html;
234 }
235
236 =head1 SEE ALSO
237
238 L<http://www.quirksmode.org/css/forms.html> for info on CSS2 forms
239
240 =cut
241
242 1;

  ViewVC Help
Powered by ViewVC 1.1.26