lib/HTML/Template/Menu.pm | |||
---|---|---|---|
Criterion | Covered | Total | % |
statement | 114 | 116 | 98.2 |
branch | 21 | 30 | 70.0 |
condition | 7 | 9 | 77.7 |
subroutine | 24 | 24 | 100.0 |
pod | 9 | 9 | 100.0 |
total | 175 | 188 | 93.0 |
line | stmt | bran | cond | sub | pod | time | code |
---|---|---|---|---|---|---|---|
1 | package HTML::Template::Menu; | ||||||
2 | 3 | 3 | 35531 | use strict; | |||
3 | 6 | ||||||
3 | 88 | ||||||
3 | 3 | 3 | 1421 | use LEOCHARRE::DEBUG; | |||
3 | 3898 | ||||||
3 | 17 | ||||||
4 | 3 | 3 | 325 | use warnings; | |||
3 | 4 | ||||||
3 | 83 | ||||||
5 | 3 | 3 | 15 | use Carp; | |||
3 | 7 | ||||||
3 | 4960 | ||||||
6 | |||||||
7 | $HTML::Template::Menu::DEFAULT_TMPL = q{ | ||||||
8 |
|
||||||
9 | |
||||||
10 | }; | ||||||
11 | |||||||
12 | |||||||
13 | sub new { | ||||||
14 | 4 | 4 | 1 | 740 | my $class = shift; | ||
15 | 4 | 10 | my $self = {}; | ||||
16 | 4 | 10 | bless $self,$class; | ||||
17 | 4 | 13 | return $self; | ||||
18 | } | ||||||
19 | |||||||
20 | sub name { | ||||||
21 | 2 | 2 | 1 | 258 | my $self = shift; | ||
22 | 2 | 50 | 8 | $self->{_name_} ||= 'main'; # redundant (?) | |||
23 | 2 | 11 | return $self->{_name_}; | ||||
24 | } | ||||||
25 | |||||||
26 | sub _name_set { | ||||||
27 | 4 | 4 | 8 | my($self,$val) = @_; | |||
28 | 4 | 50 | 13 | defined $val or confess; | |||
29 | 4 | 21 | return $self->{_name_} = $val; | ||||
30 | 0 | 0 | return 1; | ||||
31 | } | ||||||
32 | |||||||
33 | sub name_set { | ||||||
34 | 4 | 4 | 1 | 16 | my($self,$val) = @_; | ||
35 | 4 | 50 | 15 | defined $val or confess; | |||
36 | 4 | 15 | $self->_name_set($val); | ||||
37 | 4 | 9 | return 1; | ||||
38 | } | ||||||
39 | |||||||
40 | sub count { | ||||||
41 | 3 | 3 | 1 | 6 | my $self = shift; | ||
42 | 3 | 6 | my $a = $self->_get_menuitems_order; | ||||
43 | 3 | 13 | return scalar @$a; | ||||
44 | } | ||||||
45 | |||||||
46 | sub loop { | ||||||
47 | 4 | 4 | 1 | 797 | my $self = shift; | ||
48 | 4 | 18 | my $loop = $self->_get_main_menu_loop; | ||||
49 | 4 | 18 | return $loop; | ||||
50 | } | ||||||
51 | |||||||
52 | sub __to_icon_name { | ||||||
53 | 21 | 21 | 52 | my $r = lc( __prettify_string($_[0]) ); | |||
54 | 21 | 50 | $r=~s/ {1,}/_/g; | ||||
55 | 21 | 40 | $r; | ||||
56 | |||||||
57 | } | ||||||
58 | |||||||
59 | sub add { | ||||||
60 | 21 | 21 | 1 | 430 | my($self,$arg1,$label) = @_; | ||
61 | 21 | 50 | 52 | defined $arg1 or confess('missing argument'); | |||
62 | |||||||
63 | 21 | 19 | my $url; | ||||
64 | |||||||
65 | 21 | 100 | 76 | if (__is_runmode_name($arg1) ){ | |||
50 | |||||||
66 | |||||||
67 | 6 | 11 | $url = "?rm=$arg1"; # TODO, what is the runmode param string method in CGI::Application ? | ||||
68 | 6 | 50 | 22 | $label = __runmode_name_prettyfy($arg1) unless defined $label; | |||
69 | } | ||||||
70 | elsif (__is_url($arg1) ){ | ||||||
71 | 15 | 100 | 50 | $label = __url_prettyfy($arg1) unless defined $label; | |||
72 | 15 | 21 | $url = $arg1; | ||||
73 | } | ||||||
74 | else { | ||||||
75 | 0 | 0 | $url = $arg1; | ||||
76 | } | ||||||
77 | 21 | 50 | 43 | $label = $url unless defined $label; | |||
78 | |||||||
79 | 21 | 44 | my $icon=__to_icon_name($label); | ||||
80 | |||||||
81 | 21 | 102 | debug(" arg1 $arg1, url $url, label $label, icon $icon\n"); | ||||
82 | |||||||
83 | 21 | 100 | 152 | $self->_add_menu_item($arg1,$url,$label,$icon) or return 0; | |||
84 | 20 | 70 | return 1; | ||||
85 | } | ||||||
86 | |||||||
87 | sub _add_menu_item { | ||||||
88 | 21 | 21 | 39 | my ($self,$arg1,$url,$label,$icon) = @_; | |||
89 | |||||||
90 | 21 | 42 | my $hash = $self->_get_menuitems; | ||||
91 | 21 | 41 | my $array = $self->_get_menuitems_order; | ||||
92 | |||||||
93 | 21 | 100 | 49 | if (exists $hash->{$arg1}){ | |||
94 | 1 | 6 | debug("Menu item [$arg1] was already entered. Skipped.\n"); | ||||
95 | 1 | 11 | return 0; | ||||
96 | } | ||||||
97 | |||||||
98 | 20 | 31 | push @$array, $arg1; | ||||
99 | |||||||
100 | |||||||
101 | 20 | 128 | $hash->{$arg1} = { | ||||
102 | arg1 => $arg1, | ||||||
103 | url => $url, | ||||||
104 | label => $label, | ||||||
105 | icon => $icon, | ||||||
106 | }; | ||||||
107 | |||||||
108 | 20 | 61 | return 1; | ||||
109 | } | ||||||
110 | |||||||
111 | sub _get_main_menu_loop { | ||||||
112 | 4 | 4 | 9 | my $self = shift; | |||
113 | |||||||
114 | 4 | 14 | my $hash = $self->_get_menuitems; | ||||
115 | 4 | 11 | my $array = $self->_get_menuitems_order; | ||||
116 | |||||||
117 | 4 | 9 | my $loop=[]; | ||||
118 | 4 | 15 | for (@$array){ | ||||
119 | 25 | 35 | my $arg1 = $_; | ||||
120 | 25 | 134 | push @$loop, { url => $hash->{$arg1}->{url}, label => $hash->{$arg1}->{label}, icon => $hash->{$arg1}->{icon} }; | ||||
121 | } | ||||||
122 | 4 | 73 | return $loop; | ||||
123 | } | ||||||
124 | |||||||
125 | sub _get_menuitems { | ||||||
126 | 26 | 26 | 29 | my $self = shift; | |||
127 | 26 | 100 | 82 | $self->{__menuitems__} ||={}; | |||
128 | 26 | 80 | return $self->{__menuitems__}; | ||||
129 | } | ||||||
130 | |||||||
131 | sub _get_menuitems_order { | ||||||
132 | 28 | 28 | 33 | my $self = shift; | |||
133 | 28 | 100 | 961 | $self->{__menuitems__order__} ||=[]; | |||
134 | 28 | 54 | return $self->{__menuitems__order__}; | ||||
135 | } | ||||||
136 | |||||||
137 | sub __prettify_string { | ||||||
138 | 33 | 33 | 42 | my $val = shift; | |||
139 | 33 | 57 | my $label = lc $val; | ||||
140 | 33 | 79 | $label=~s/\W/ /g; | ||||
141 | 33 | 121 | $label=~s/^\s+|\s+$//g; | ||||
142 | |||||||
143 | 33 | 116 | $label=~s/\_+|\s{2,}/ /g; | ||||
144 | 33 | 100 | $label=~s/\b([a-z])/uc $1/eg; | ||||
49 | 152 | ||||||
145 | 33 | 83 | return $label; | ||||
146 | } | ||||||
147 | |||||||
148 | sub __runmode_name_prettyfy { | ||||||
149 | 6 | 6 | 7 | my $val = shift; | |||
150 | |||||||
151 | 6 | 17 | my $label = lc $val; | ||||
152 | 6 | 18 | $label=~s/\_/ /g; | ||||
153 | 6 | 26 | $label=~s/\b([a-z])/uc $1/eg; | ||||
12 | 42 | ||||||
154 | 6 | 18 | return $label; | ||||
155 | } | ||||||
156 | |||||||
157 | sub __is_runmode_name { | ||||||
158 | 36 | 36 | 42 | my $val = shift; | |||
159 | 36 | 100 | 209 | $val =~/^[a-z0-9_]+$/i or return 0; | |||
160 | 6 | 16 | return 1; | ||||
161 | } | ||||||
162 | |||||||
163 | sub __is_url { | ||||||
164 | 15 | 15 | 18 | my $val = shift; | |||
165 | 15 | 50 | 23 | return 0 if __is_runmode_name($val); | |||
166 | 15 | 33 | return 1; | ||||
167 | |||||||
168 | } | ||||||
169 | |||||||
170 | sub __url_prettyfy { | ||||||
171 | 14 | 14 | 19 | my $val = shift; | |||
172 | 14 | 100 | 46 | if ($val eq '/'){ return 'Home'; } | |||
2 | 5 | ||||||
173 | 12 | 33 | $val=~s/\/+$//; | ||||
174 | 12 | 33 | $val=~s/^.+\/+//; | ||||
175 | 12 | 31 | $val=~s/\.\w{1,5}$//; | ||||
176 | 12 | 21 | $val=~s/\.s*html*\?.+//i; | ||||
177 | 12 | 33 | $val=~s/\.\w{3}\?.+//i; | ||||
178 | |||||||
179 | 12 | 19 | my $label = __prettify_string($val); | ||||
180 | 12 | 23 | return $label; | ||||
181 | } | ||||||
182 | |||||||
183 | sub output { | ||||||
184 | 2 | 2 | 1 | 440 | my $self = shift; | ||
185 | 2 | 3741 | require HTML::Template; | ||||
186 | 2 | 50 | 32634 | my $tmpl = new HTML::Template( | |||
187 | die_on_bad_params => 0, | ||||||
188 | scalarref => \$HTML::Template::Menu::DEFAULT_TMPL, | ||||||
189 | ) | ||||||
190 | or die('cant instance HTML::Template object'); | ||||||
191 | |||||||
192 | 2 | 1510 | $tmpl->param( | ||||
193 | MAIN_MENU_LOOP => $self->loop, | ||||||
194 | MAIN_MENU_CLASS => $self->menu_class ); | ||||||
195 | 2 | 109 | return $tmpl->output; | ||||
196 | } | ||||||
197 | |||||||
198 | sub menu_class { | ||||||
199 | 2 | 2 | 1 | 5 | my $self = shift; | ||
200 | 2 | 66 | 14 | $self->{_menu_class_} ||= 'menu_class_'.$self->name; | |||
201 | 2 | 10 | return $self->{_menu_class_}; | ||||
202 | } | ||||||
203 | |||||||
204 | sub menu_class_set { | ||||||
205 | 2 | 2 | 1 | 4 | my($self,$val) =@_; | ||
206 | 2 | 50 | 9 | defined $val or confess('missing arg'); | |||
207 | 2 | 11 | $val=~s/\W//g; | ||||
208 | 2 | 6 | $self->{_menu_class_} = $val; | ||||
209 | 2 | 4 | return 1; | ||||
210 | } | ||||||
211 | |||||||
212 | |||||||
213 | |||||||
214 | 1; | ||||||
215 | |||||||
216 | =pod | ||||||
217 | |||||||
218 | =head1 NAME | ||||||
219 | |||||||
220 | HTML::Template::Menu - ease menu items for quick web user interface | ||||||
221 | |||||||
222 | =head1 SYNOPSIS | ||||||
223 | |||||||
224 | use HTML::Template::Menu; | ||||||
225 | |||||||
226 | my $m = new HTML::Template::Menu; | ||||||
227 | |||||||
228 | $m->add('/','home'); | ||||||
229 | $m->add('/contact.html'); | ||||||
230 | $m->add('http://google.com'); | ||||||
231 | $m->add('http://titantv.com', 'view tv listings'); | ||||||
232 | |||||||
233 | print $m->output; | ||||||
234 | |||||||
235 | =head1 METHODS | ||||||
236 | |||||||
237 | =head2 new() | ||||||
238 | |||||||
239 | =head2 name() | ||||||
240 | |||||||
241 | Returns name of the menu. | ||||||
242 | |||||||
243 | =head2 name_set() | ||||||
244 | |||||||
245 | Sets name of menu, argument is string. | ||||||
246 | |||||||
247 | my $m = new HTML::Template::Menu; | ||||||
248 | $m->name_set('login_menu'); | ||||||
249 | |||||||
250 | =head2 add() | ||||||
251 | |||||||
252 | Argument is url or CGI::Application runmode name. | ||||||
253 | Optional argument is a label, (the anchor text). | ||||||
254 | |||||||
255 | If the first argument has no funny chars, it is treated as a runmode, instead of a url. | ||||||
256 | |||||||
257 | The label is what will appear in the link text, | ||||||
258 | If not provided, one will be made. This is part of what this module does for you. | ||||||
259 | If you have a runmode called see_more, the link text is "See More". | ||||||
260 | |||||||
261 | The link will be | ||||||
262 | |||||||
263 | $ARG2 | ||||||
264 | |||||||
265 | So in this example: | ||||||
266 | |||||||
267 | $m->add('view_tasks'); | ||||||
268 | |||||||
269 | The result is: | ||||||
270 | |||||||
271 | View Tasks | ||||||
272 | |||||||
273 | =head2 loop() | ||||||
274 | |||||||
275 | get loop suitable for HTML::Template object | ||||||
276 | See SYNOPSIS. | ||||||
277 | |||||||
278 | =head2 count() | ||||||
279 | |||||||
280 | Takes no argument. | ||||||
281 | Returns count of items in this menu. (Each item is a menu link.) | ||||||
282 | |||||||
283 | =head2 menu_class() | ||||||
284 | |||||||
285 | What the TMPL_VAR MAIN_MENU_CLASS will hold, this is the css name. | ||||||
286 | |||||||
287 | =head2 menu_class_set() | ||||||
288 | |||||||
289 | Arg is string. | ||||||
290 | Sets the TMPL_VAR MAIN_MENU_CLASS css name. If not provided, one is generated for you. | ||||||
291 | |||||||
292 | =head2 output() | ||||||
293 | |||||||
294 | If you just want the output with the default hard coded template. | ||||||
295 | The default template code is stored in: | ||||||
296 | |||||||
297 | $CGI::Application::Plugin::MenuObject::DEFAULT_TMPL | ||||||
298 | |||||||
299 | |||||||
300 | =head1 ADDING MENU ITEMS | ||||||
301 | |||||||
302 | my $m = $self->menu_get('main menu'); | ||||||
303 | |||||||
304 | $m->add('home'); | ||||||
305 | $m->add('http://helpme.com','Need help?'); | ||||||
306 | $m->add('logout'); | ||||||
307 | |||||||
308 | Elements for the menu are shown in the order they are inserted. | ||||||
309 | |||||||
310 | =head1 DEFAULT TEMPLATE | ||||||
311 | |||||||
312 | This is the default template: | ||||||
313 | |||||||
314 |
|
||||||
315 | |
||||||
316 | |||||||
317 | |||||||
318 | |||||||
319 | You can feed your own template with: | ||||||
320 | |||||||
321 | my $m = HTML::Template::Menu->new; | ||||||
322 | $m->add('http://cpan.org'); | ||||||
323 | |||||||
324 | my $tmpl = HTML::Template->new( scalarref => \q{ | ||||||
325 |
|
||||||
326 | |
||||||
327 | |||||||
328 | }); | ||||||
329 | |||||||
330 | $tmpl->param( MENU_LOOP => $m->loop ); | ||||||
331 | |||||||
332 | |||||||
333 | One other way to change it: | ||||||
334 | |||||||
335 | $HTML::Template::Menu::DEFAULT_TMPL = q{ | ||||||
336 |
|
||||||
337 | |
||||||
338 | |||||||
339 | }; | ||||||
340 | |||||||
341 | |||||||
342 | =head1 ICONS | ||||||
343 | |||||||
344 | Each menu item has the TMPL_VAR s set: LABEL, URL, ICON. | ||||||
345 | ICON is a broken down simplification of whatever was in the URL. | ||||||
346 | You may choose to use this to include icons. | ||||||
347 | |||||||
348 | For example: | ||||||
349 | |||||||
350 | my $m = HTML::Template::Menu->new; | ||||||
351 | $m->add('http://cpan.org'); | ||||||
352 | |||||||
353 | my $tmpl = HTML::Template->new( scalarref => \q{ | ||||||
354 |
|
||||||
355 | |
||||||
356 | [ |
||||||
357 | |||||||
358 | }); | ||||||
359 | |||||||
360 | $tmpl->param( MENU_LOOP => $m->loop ); | ||||||
361 | |||||||
362 | This will create an entry such as: | ||||||
363 | |||||||
364 | |
||||||
365 | |||||||
366 | [Cpan] | ||||||
367 | |||||||
368 | |||||||
369 | |||||||
370 | =head1 SEE ALSO | ||||||
371 | |||||||
372 | L |
||||||
373 | L |
||||||
374 | |||||||
375 | |||||||
376 | =head1 AUTHOR | ||||||
377 | |||||||
378 | Leo Charre leocharre at cpan dot org | ||||||
379 | |||||||
380 | =head1 COPYRIGHT | ||||||
381 | |||||||
382 | Copyright (c) 2009 Leo Charre. All rights reserved. | ||||||
383 | |||||||
384 | =head1 LICENSE | ||||||
385 | |||||||
386 | This package is free software; you can redistribute it and/or modify it under the same terms as Perl itself, i.e., under the terms of the "Artistic License" or the "GNU General Public License". | ||||||
387 | |||||||
388 | =head1 DISCLAIMER | ||||||
389 | |||||||
390 | This package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||||||
391 | |||||||
392 | See the "GNU General Public License" for more details. | ||||||
393 | |||||||
394 | =cut | ||||||
395 |