Revision d093f01c
Von Moritz Bunkus vor mehr als 11 Jahren hinzugefügt
SL/Template/Plugin/L.pm | ||
---|---|---|
19 | 19 |
} |
20 | 20 |
} |
21 | 21 |
|
22 |
my %_valueless_attributes = map { $_ => 1 } qw( |
|
23 |
checked compact declare defer disabled ismap multiple noresize noshade nowrap |
|
24 |
readonly selected |
|
25 |
); |
|
26 |
|
|
27 | 22 |
sub _H { |
28 | 23 |
my $string = shift; |
29 | 24 |
return $::locale->quote_special_chars('HTML', $string); |
... | ... | |
53 | 48 |
} |
54 | 49 |
|
55 | 50 |
sub _call_presenter { |
56 |
my ($method, @args) = @_; |
|
51 |
my ($method, $self, @args) = @_;
|
|
57 | 52 |
|
58 |
my $presenter = $::request->presenter; |
|
53 |
my $presenter = $::request->presenter;
|
|
59 | 54 |
|
60 |
return '' unless $presenter->can($method); |
|
55 |
if (!$presenter->can($method)) { |
|
56 |
$::lxdebug->message(LXDebug::WARN(), "SL::Presenter has no method named '$method'!"); |
|
57 |
return ''; |
|
58 |
} |
|
61 | 59 |
|
62 | 60 |
splice @args, -1, 1, %{ $args[-1] } if @args && (ref($args[-1]) eq 'HASH'); |
63 | 61 |
|
64 | 62 |
$presenter->$method(@args); |
65 | 63 |
} |
66 | 64 |
|
67 |
sub name_to_id { |
|
68 |
my $self = shift; |
|
69 |
my $name = shift; |
|
70 |
|
|
71 |
$name =~ s/[^\w_]/_/g; |
|
72 |
$name =~ s/_+/_/g; |
|
73 |
|
|
74 |
return $name; |
|
75 |
} |
|
76 |
|
|
77 |
sub attributes { |
|
78 |
my ($self, @slurp) = @_; |
|
79 |
my %options = _hashify(@slurp); |
|
80 |
|
|
81 |
my @result = (); |
|
82 |
while (my ($name, $value) = each %options) { |
|
83 |
next unless $name; |
|
84 |
next if $_valueless_attributes{$name} && !$value; |
|
85 |
$value = '' if !defined($value); |
|
86 |
push @result, $_valueless_attributes{$name} ? _H($name) : _H($name) . '="' . _H($value) . '"'; |
|
87 |
} |
|
88 |
|
|
89 |
return @result ? ' ' . join(' ', @result) : ''; |
|
90 |
} |
|
91 |
|
|
92 |
sub html_tag { |
|
93 |
my ($self, $tag, $content, @slurp) = @_; |
|
94 |
my $attributes = $self->attributes(@slurp); |
|
95 |
|
|
96 |
return "<${tag}${attributes}>" unless defined($content); |
|
97 |
return "<${tag}${attributes}>${content}</${tag}>"; |
|
98 |
} |
|
65 |
sub name_to_id { return _call_presenter('name_to_id', @_); } |
|
66 |
sub html_tag { return _call_presenter('html_tag', @_); } |
|
67 |
sub select_tag { return _call_presenter('select_tag', @_); } |
|
68 |
sub input_tag { return _call_presenter('input_tag', @_); } |
|
69 |
sub truncate { return _call_presenter('truncate', @_); } |
|
70 |
sub simple_format { return _call_presenter('simple_format', @_); } |
|
99 | 71 |
|
100 | 72 |
sub img_tag { |
101 | 73 |
my ($self, @slurp) = @_; |
... | ... | |
106 | 78 |
return $self->html_tag('img', undef, %options); |
107 | 79 |
} |
108 | 80 |
|
109 |
sub select_tag { |
|
110 |
my $self = shift; |
|
111 |
my $name = shift; |
|
112 |
my $collection = shift; |
|
113 |
my %attributes = _hashify(@_); |
|
114 |
|
|
115 |
$attributes{id} ||= $self->name_to_id($name); |
|
116 |
|
|
117 |
my $value_key = delete($attributes{value_key}) || 'id'; |
|
118 |
my $title_key = delete($attributes{title_key}) || $value_key; |
|
119 |
my $default_key = delete($attributes{default_key}) || 'selected'; |
|
120 |
|
|
121 |
|
|
122 |
my $value_title_sub = delete($attributes{value_title_sub}); |
|
123 |
|
|
124 |
my $value_sub = delete($attributes{value_sub}); |
|
125 |
my $title_sub = delete($attributes{title_sub}); |
|
126 |
my $default_sub = delete($attributes{default_sub}); |
|
127 |
|
|
128 |
my $with_empty = delete($attributes{with_empty}); |
|
129 |
my $empty_title = delete($attributes{empty_title}); |
|
130 |
|
|
131 |
my $with_optgroups = delete($attributes{with_optgroups}); |
|
132 |
|
|
133 |
my %selected; |
|
134 |
|
|
135 |
if ( ref($attributes{default}) eq 'ARRAY' ) { |
|
136 |
|
|
137 |
foreach my $entry (@{$attributes{default}}) { |
|
138 |
$selected{$entry} = 1; |
|
139 |
} |
|
140 |
} elsif ( defined($attributes{default}) ) { |
|
141 |
$selected{$attributes{default}} = 1; |
|
142 |
} |
|
143 |
|
|
144 |
delete($attributes{default}); |
|
145 |
|
|
146 |
|
|
147 |
my @all_options; |
|
148 |
push @all_options, [undef, $empty_title || ''] if $with_empty; |
|
149 |
|
|
150 |
my $normalize_entry = sub { |
|
151 |
my ($type, $entry, $sub, $key) = @_; |
|
152 |
|
|
153 |
return $sub->($entry) if $sub; |
|
154 |
|
|
155 |
my $ref = ref($entry); |
|
156 |
|
|
157 |
if ( !$ref ) { |
|
158 |
return $entry if $type eq 'value' || $type eq 'title'; |
|
159 |
return 0; |
|
160 |
} |
|
161 |
|
|
162 |
if ( $ref eq 'ARRAY' ) { |
|
163 |
return $entry->[ $type eq 'value' ? 0 : $type eq 'title' ? 1 : 2 ]; |
|
164 |
} |
|
165 |
|
|
166 |
return $entry->{$key} if $ref eq 'HASH'; |
|
167 |
return $entry->$key if $type ne 'default' || $entry->can($key); |
|
168 |
return undef; |
|
169 |
}; |
|
170 |
|
|
171 |
my $list_to_code = sub { |
|
172 |
my ($sub_collection) = @_; |
|
173 |
|
|
174 |
my @options; |
|
175 |
foreach my $entry ( @{ $sub_collection } ) { |
|
176 |
my $value; |
|
177 |
my $title; |
|
178 |
|
|
179 |
if ( $value_title_sub ) { |
|
180 |
($value, $title) = @{ $value_title_sub->($entry) }; |
|
181 |
} else { |
|
182 |
|
|
183 |
$value = $normalize_entry->('value', $entry, $value_sub, $value_key); |
|
184 |
$title = $normalize_entry->('title', $entry, $title_sub, $title_key); |
|
185 |
} |
|
186 |
|
|
187 |
my $default = $normalize_entry->('default', $entry, $default_sub, $default_key); |
|
188 |
|
|
189 |
push(@options, [$value, $title, $default]); |
|
190 |
} |
|
191 |
|
|
192 |
foreach my $entry (@options) { |
|
193 |
$entry->[2] = 1 if $selected{$entry->[0]}; |
|
194 |
} |
|
195 |
|
|
196 |
return join '', map { $self->html_tag('option', _H($_->[1]), value => $_->[0], selected => $_->[2]) } @options; |
|
197 |
}; |
|
198 |
|
|
199 |
my $code; |
|
200 |
|
|
201 |
if (!$with_optgroups) { |
|
202 |
$code = $list_to_code->($collection); |
|
203 |
|
|
204 |
} else { |
|
205 |
$code = join '', map { |
|
206 |
my ($optgroup_title, $sub_collection) = @{ $_ }; |
|
207 |
$self->html_tag('optgroup', $list_to_code->($sub_collection), label => $optgroup_title) |
|
208 |
} @{ $collection }; |
|
209 |
} |
|
210 |
|
|
211 |
return $self->html_tag('select', $code, %attributes, name => $name); |
|
212 |
} |
|
213 |
|
|
214 | 81 |
sub textarea_tag { |
215 | 82 |
my ($self, $name, $content, @slurp) = @_; |
216 | 83 |
my %attributes = _hashify(@slurp); |
... | ... | |
266 | 133 |
return $code; |
267 | 134 |
} |
268 | 135 |
|
269 |
sub input_tag { |
|
270 |
my ($self, $name, $value, @slurp) = @_; |
|
271 |
my %attributes = _hashify(@slurp); |
|
272 |
|
|
273 |
$attributes{id} ||= $self->name_to_id($name); |
|
274 |
$attributes{type} ||= 'text'; |
|
275 |
|
|
276 |
return $self->html_tag('input', undef, %attributes, name => $name, value => $value); |
|
277 |
} |
|
278 |
|
|
279 | 136 |
sub hidden_tag { |
280 | 137 |
my ($self, $name, $value, @slurp) = @_; |
281 | 138 |
return $self->input_tag($name, $value, _hashify(@slurp), type => 'hidden'); |
... | ... | |
589 | 446 |
return '<pre>' . Data::Dumper::Dumper(@_) . '</pre>'; |
590 | 447 |
} |
591 | 448 |
|
592 |
sub truncate { |
|
593 |
my $self = shift; |
|
594 |
return _call_presenter('truncate', @_); |
|
595 |
} |
|
596 |
|
|
597 | 449 |
sub sortable_table_header { |
598 | 450 |
my ($self, $by, @slurp) = @_; |
599 | 451 |
my %params = _hashify(@slurp); |
... | ... | |
638 | 490 |
return SL::Presenter->get->render('common/paginate', %template_params); |
639 | 491 |
} |
640 | 492 |
|
641 |
sub simple_format { |
|
642 |
my $self = shift; |
|
643 |
return _call_presenter('simple_format', @_); |
|
644 |
} |
|
645 |
|
|
646 | 493 |
1; |
647 | 494 |
|
648 | 495 |
__END__ |
... | ... | |
676 | 523 |
|
677 | 524 |
=head2 LOW-LEVEL FUNCTIONS |
678 | 525 |
|
679 |
=over 4 |
|
680 |
|
|
681 |
=item C<name_to_id $name> |
|
682 |
|
|
683 |
Converts a name to a HTML id by replacing various characters. |
|
684 |
|
|
685 |
=item C<attributes %items> |
|
526 |
The following items are just forwarded to L<SL::Presenter::Tag>: |
|
686 | 527 |
|
687 |
Creates a string from all elements in C<%items> suitable for usage as |
|
688 |
HTML tag attributes. Keys and values are HTML escaped even though keys |
|
689 |
must not contain non-ASCII characters for browsers to accept them. |
|
528 |
=over 2 |
|
690 | 529 |
|
691 |
=item C<html_tag $tag_name, $content_string, %attributes>
|
|
530 |
=item * C<name_to_id $name>
|
|
692 | 531 |
|
693 |
Creates an opening and closing HTML tag for C<$tag_name> and puts |
|
694 |
C<$content_string> between the two. If C<$content_string> is undefined |
|
695 |
or empty then only a E<lt>tag/E<gt> tag will be created. Attributes |
|
696 |
are key/value pairs added to the opening tag. |
|
532 |
=item * C<stringify_attributes %items> |
|
697 | 533 |
|
698 |
C<$content_string> is not HTML escaped.
|
|
534 |
=item * C<html_tag $tag_name, $content_string, %attributes>
|
|
699 | 535 |
|
700 | 536 |
=back |
701 | 537 |
|
702 | 538 |
=head2 HIGH-LEVEL FUNCTIONS |
703 | 539 |
|
704 |
=over 4 |
|
705 |
|
|
706 |
=item C<select_tag $name, \@collection, %attributes> |
|
707 |
|
|
708 |
Creates a HTML 'select' tag named C<$name> with the contents of one |
|
709 |
'E<lt>optionE<gt>' tag for each element in C<\@collection> and with arbitrary |
|
710 |
HTML attributes from C<%attributes>. The value |
|
711 |
to use and the title to display are extracted from the elements in |
|
712 |
C<\@collection>. Each element can be one of four things: |
|
713 |
|
|
714 |
=over 12 |
|
715 |
|
|
716 |
=item 1. An array reference with at least two elements. The first element is |
|
717 |
the value, the second element is its title. The third element is optional and and should contain a boolean. |
|
718 |
If it is true, than the element will be used as default. |
|
540 |
The following functions are just forwarded to L<SL::Presenter::Tag>: |
|
719 | 541 |
|
720 |
=item 2. A scalar. The scalar is both the value and the title.
|
|
542 |
=over 2
|
|
721 | 543 |
|
722 |
=item 3. A hash reference. In this case C<%attributes> must contain |
|
723 |
I<value_key>, I<title_key> and may contain I<default_key> keys that name the keys in the element to use |
|
724 |
for the value, title and default respectively. |
|
544 |
=item * C<input_tag $name, $value, %attributes> |
|
725 | 545 |
|
726 |
=item 4. A blessed reference. In this case C<%attributes> must contain |
|
727 |
I<value_key>, I<title_key> and may contain I<default_key> keys that name functions called on the blessed |
|
728 |
reference whose return values are used as the value, title and default |
|
729 |
respectively. |
|
546 |
=item * C<select_tag $name, \@collection, %attributes> |
|
730 | 547 |
|
731 | 548 |
=back |
732 | 549 |
|
733 |
For cases 3 and 4 C<$attributes{value_key}> defaults to C<id>, |
|
734 |
C<$attributes{title_key}> defaults to C<$attributes{value_key}> |
|
735 |
and C<$attributes{default_key}> defaults to C<selected>. |
|
736 |
|
|
737 |
In addition to pure keys/method you can also provide coderefs as I<value_sub> |
|
738 |
and/or I<title_sub> and/or I<default_sub>. If present, these take precedence over keys or methods, |
|
739 |
and are called with the element as first argument. It must return the value, title or default. |
|
740 |
|
|
741 |
Lastly a joint coderef I<value_title_sub> may be provided, which in turn takes |
|
742 |
precedence over the C<value_sub> and C<title_sub> subs. It will only be called once for each |
|
743 |
element and must return a list of value and title. |
|
744 |
|
|
745 |
If the option C<with_empty> is set then an empty element (value |
|
746 |
C<undef>) will be used as the first element. The title to display for |
|
747 |
this element can be set with the option C<empty_title> and defaults to |
|
748 |
an empty string. |
|
749 |
|
|
750 |
The option C<default> can be either a scalar or an array reference |
|
751 |
containing the values of the options which should be set to be |
|
752 |
selected. |
|
753 |
|
|
754 |
The tag's C<id> defaults to C<name_to_id($name)>. |
|
755 |
|
|
756 |
If the option C<with_optgroups> is set then this function expects |
|
757 |
C<\@collection> to be one level deeper. The upper-most level is |
|
758 |
translated into a HTML C<optgroup> tag. So the structure becomes: |
|
550 |
Available high-level functions implemented in this module: |
|
759 | 551 |
|
760 | 552 |
=over 4 |
761 | 553 |
|
762 |
=item 1. Array of array references. Each element in the |
|
763 |
C<\@collection> is converted into an optgroup. |
|
764 |
|
|
765 |
=item 2. The optgroup's C<label> attribute will be set to the the |
|
766 |
first element in the array element. The second array element is then |
|
767 |
converted to a list of C<option> tags like it is described above. |
|
768 |
|
|
769 |
=back |
|
770 |
|
|
771 |
Example for use of optgroups: |
|
772 |
|
|
773 |
# First in a controller: |
|
774 |
my @collection = ( |
|
775 |
[ t8("First optgroup with two items"), |
|
776 |
[ { id => 42, name => "item one" }, |
|
777 |
{ id => 54, name => "second item" }, |
|
778 |
{ id => 23, name => "and the third one" }, |
|
779 |
] ], |
|
780 |
[ t8("Another optgroup, with a lot of items from Rose"), |
|
781 |
SL::DB::Manager::Customer->get_all_sorted ], |
|
782 |
); |
|
783 |
|
|
784 |
# Later in the template: |
|
785 |
[% L.select_tag('the_selection', COLLECTION, with_optgroups=1, title_key='name') %] |
|
786 |
|
|
787 | 554 |
=item C<yes_no_tag $name, $value, %attributes> |
788 | 555 |
|
789 | 556 |
Creates a HTML 'select' tag with the two entries C<yes> and C<no> by |
... | ... | |
791 | 558 |
which entry is selected. The C<%attributes> are passed through to |
792 | 559 |
L<select_tag>. |
793 | 560 |
|
794 |
=item C<input_tag $name, $value, %attributes> |
|
795 |
|
|
796 |
Creates a HTML 'input type=text' tag named C<$name> with the value |
|
797 |
C<$value> and with arbitrary HTML attributes from C<%attributes>. The |
|
798 |
tag's C<id> defaults to C<name_to_id($name)>. |
|
799 |
|
|
800 | 561 |
=item C<hidden_tag $name, $value, %attributes> |
801 | 562 |
|
802 | 563 |
Creates a HTML 'input type=hidden' tag named C<$name> with the value |
Auch abrufbar als: Unified diff
L/Presenter: mehrere Funktionen aus L in Presenter verschoben