File Coverage

blib/lib/Tags/HTML/Messages.pm
Criterion Covered Total %
statement 76 76 100.0
branch 18 18 100.0
condition 6 6 100.0
subroutine 12 12 100.0
pod 1 1 100.0
total 113 113 100.0


line stmt bran cond sub pod time code
1             package Tags::HTML::Messages;
2              
3 5     5   571265 use base qw(Tags::HTML);
  5         13  
  5         2676  
4 5     5   33715 use strict;
  5         11  
  5         109  
5 5     5   22 use warnings;
  5         11  
  5         2436  
6              
7 5     5   31 use Class::Utils qw(set_params split_params);
  5         15  
  5         305  
8 5     5   31 use Error::Pure qw(err);
  5         9  
  5         312  
9 5     5   2584 use Mo::utils::Hash 0.02 qw(check_hash check_hash_keys);
  5         3540  
  5         107  
10 5     5   2264 use Mo::utils::Language 0.05 qw(check_language_639_2);
  5         1023942  
  5         159  
11 5     5   345 use Scalar::Util qw(blessed);
  5         20  
  5         3538  
12              
13             our $VERSION = 0.10;
14              
15             # Constructor.
16             sub new {
17 28     28 1 1009649 my ($class, @params) = @_;
18              
19             # Create object.
20 28         220 my ($object_params_ar, $other_params_ar) = split_params(
21             ['css_messages', 'flag_no_messages', 'lang', 'text'], @params);
22 28         1114 my $self = $class->SUPER::new(@{$other_params_ar});
  28         205  
23              
24             # CSS class.
25 26         1229 $self->{'css_messages'} = 'messages';
26              
27             # Flag for no messages.
28 26         102 $self->{'flag_no_messages'} = 1;
29              
30             # Language.
31 26         92 $self->{'lang'} = 'eng';
32              
33             # Texts.
34 26         148 $self->{'text'} = {
35             'eng' => {
36             'no_messages' => 'No messages',
37             },
38             };
39              
40             # Process params.
41 26         56 set_params($self, @{$object_params_ar});
  26         94  
42              
43             # Check language.
44 26         318 check_language_639_2($self, 'lang');
45              
46             # Check texts.
47 25         274617 check_hash($self, 'text');
48 24         419 check_hash_keys($self, 'text', $self->{'lang'});
49 23         681 check_hash_keys($self, 'text', $self->{'lang'}, 'no_messages');
50              
51             # Object.
52 22         1028 return $self;
53             }
54              
55             sub _check_messages {
56 11     11   27 my ($self, $message_ar) = @_;
57              
58 11 100       41 if (ref $message_ar ne 'ARRAY') {
59 1         6 err "Bad list of messages.";
60             }
61 10         21 foreach my $message (@{$message_ar}) {
  10         35  
62 8 100 100     69 if (! blessed($message) || ! $message->isa('Data::Message::Simple')) {
63              
64 2         94 err 'Bad message data object.';
65             }
66             }
67              
68 8         19 return;
69             }
70              
71             # Process 'Tags'.
72             sub _process {
73 12     12   1647 my ($self, $message_ar) = @_;
74              
75 12 100       59 if (! defined $message_ar) {
76 1         3 return;
77             }
78              
79 11         43 $self->_check_messages($message_ar);
80              
81             # No messages.
82 8 100 100     32 if (! $self->{'flag_no_messages'} && ! @{$message_ar}) {
  2         11  
83 1         4 return;
84             }
85              
86 7         16 my $num = 0;
87             $self->{'tags'}->put(
88             ['b', 'div'],
89 7         74 ['a', 'class', $self->{'css_messages'}],
90             );
91 7 100       674 if (@{$message_ar}) {
  7         25  
92 5         10 foreach my $message (@{$message_ar}) {
  5         12  
93 6 100       19 if ($num) {
94 1         7 $self->{'tags'}->put(
95             ['b', 'br'],
96             ['e', 'br'],
97             );
98             }
99 6 100       136 $self->{'tags'}->put(
100             ['b', 'span'],
101             ['a', 'class', $message->type],
102             defined $message->lang
103             ? (['a', 'lang', $message->lang])
104             : (),
105             ['d', $message->text],
106             ['e', 'span'],
107             );
108 6         1025 $num++;
109             }
110             } else {
111             $self->{'tags'}->put(
112 2         13 ['d', $self->{'text'}->{$self->{'lang'}}->{'no_messages'}],
113             );
114             }
115 7         97 $self->{'tags'}->put(
116             ['e', 'div'],
117             );
118              
119 7         358 return;
120             }
121              
122             # Process 'CSS::Struct'.
123             sub _process_css {
124 4     4   82 my ($self, $message_types_hr) = @_;
125              
126 4 100       24 if (! defined $message_types_hr) {
127 1         4 return;
128             }
129 3 100       15 if (ref $message_types_hr ne 'HASH') {
130 1         20 err 'Message types must be a hash reference.';
131             }
132              
133 2         12 foreach my $message_type (sort keys %{$message_types_hr}) {
  2         8  
134             $self->{'css'}->put(
135             ['s', '.'.$message_type],
136 1         20 ['d', 'color', $message_types_hr->{$message_type}],
137             ['e'],
138             );
139             }
140              
141 2         102 return;
142             }
143              
144             1;
145              
146             __END__
147              
148             =pod
149              
150             =encoding utf8
151              
152             =head1 NAME
153              
154             Tags::HTML::Messages - Tags helper for HTML messages.
155              
156             =head1 SYNOPSIS
157              
158             use Tags::HTML::Messages;
159              
160             my $obj = Tags::HTML::Messages->new(%params);
161             $obj->process($message_ar);
162             $obj->process_css($type, $color);
163              
164             =head1 METHODS
165              
166             =head2 C<new>
167              
168             my $obj = Tags::HTML::Messages->new(%params);
169              
170             Constructor.
171              
172             =over 8
173              
174             =item * C<css>
175              
176             'CSS::Struct::Output' object for L<process_css> processing.
177              
178             Default value is undef.
179              
180             =item * C<css_messages>
181              
182             CSS class for main messages div block.
183              
184             Default value is 'messages'.
185              
186             =item * C<flag_no_messages>
187              
188             Flag for no messages printing.
189              
190             Possible values:
191              
192             0 - Print nothing
193             1 - Print message box with 'No messages.' text.
194              
195             Default value is 1.
196              
197             =item * C<tags>
198              
199             'Tags::Output' object.
200              
201             Default value is undef.
202              
203             =back
204              
205             =head2 C<process>
206              
207             $obj->process($message_ar);
208              
209             Process Tags structure for output.
210              
211             Reference to array with message objects C<$message_ar> must be a instance of
212             L<Data::Message::Simple> object.
213              
214             Returns undef.
215              
216             =head2 C<process_css>
217              
218             $obj->process_css($message_types_hr);
219              
220             Process CSS::Struct structure for output.
221              
222             Variable C<$message_type_hr> is reference to hash with keys for message type and value for color in CSS style.
223             Possible message types are info and error now. Types are defined in L<Data::Message::Simple>.
224              
225             Returns undef.
226              
227             =head1 ERRORS
228              
229             new():
230             From Class::Utils::set_params():
231             Unknown parameter '%s'.
232             Parameter 'css' must be a 'CSS::Struct::Output::*' class.
233             Parameter 'tags' must be a 'Tags::Output::*' class.
234              
235             process():
236             Bad list of messages.
237             Bad message data object.
238              
239             process_css():
240             Message types must be a hash reference.
241              
242             =head1 EXAMPLE1
243              
244             =for comment filename=html_page_with_messages.pl
245              
246             use strict;
247             use warnings;
248              
249             use CSS::Struct::Output::Indent;
250             use Data::Message::Simple;
251             use Tags::HTML::Page::Begin;
252             use Tags::HTML::Page::End;
253             use Tags::HTML::Messages;
254             use Tags::Output::Indent;
255              
256             # Object.
257             my $tags = Tags::Output::Indent->new(
258             'preserved' => ['style'],
259             'xml' => 1,
260             );
261             my $css = CSS::Struct::Output::Indent->new;
262             my $begin = Tags::HTML::Page::Begin->new(
263             'css' => $css,
264             'lang' => {
265             'title' => 'Tags::HTML::Messages example',
266             },
267             'generator' => 'Tags::HTML::Messages',
268             'tags' => $tags,
269             );
270             my $end = Tags::HTML::Page::End->new(
271             'tags' => $tags,
272             );
273             my $messages = Tags::HTML::Messages->new(
274             'css' => $css,
275             'tags' => $tags,
276             );
277              
278             # Error structure.
279             my $message_ar = [
280             Data::Message::Simple->new(
281             'text' => 'Error #1',
282             'type' => 'error',
283             ),
284             Data::Message::Simple->new(
285             'text' => 'Error #2',
286             'type' => 'error',
287             ),
288             Data::Message::Simple->new(
289             'lang' => 'en',
290             'text' => 'Ok #1',
291             ),
292             Data::Message::Simple->new(
293             'text' => 'Ok #2',
294             ),
295             ];
296              
297             # Process page.
298             $messages->process_css({
299             'error' => 'red',
300             'info' => 'green',
301             });
302             $begin->process;
303             $messages->process($message_ar);
304             $end->process;
305              
306             # Print out.
307             print $tags->flush;
308              
309             # Output:
310             # <!DOCTYPE html>
311             # <html lang="en">
312             # <head>
313             # <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
314             # <meta name="generator" content="Tags::HTML::Messages" />
315             # <meta name="viewport" content="width=device-width, initial-scale=1.0" />
316             # <title>
317             # Tags::HTML::Messages example
318             # </title>
319             # <style type="text/css">
320             # .error {
321             # color: red;
322             # }
323             # .info {
324             # color: green;
325             # }
326             # </style>
327             # </head>
328             # <body>
329             # <div class="messages">
330             # <span class="error">
331             # Error #1
332             # </span>
333             # <br />
334             # <span class="error">
335             # Error #2
336             # </span>
337             # <br />
338             # <span class="info" lang="en">
339             # Ok #1
340             # </span>
341             # <br />
342             # <span class="info">
343             # Ok #2
344             # </span>
345             # </div>
346             # </body>
347             # </html>
348              
349             =head1 DEPENDENCIES
350              
351             L<Class::Utils>,
352             L<Error::Pure>,
353             L<Scalar::Util>,
354             L<Tags::HTML>.
355              
356             =head1 REPOSITORY
357              
358             L<https://github.com/michal-josef-spacek/Tags-HTML-Messages>
359              
360             =head1 AUTHOR
361              
362             Michal Josef Špaček L<mailto:skim@cpan.org>
363              
364             L<http://skim.cz>
365              
366             =head1 LICENSE AND COPYRIGHT
367              
368             © Michal Josef Špaček 2020-2025
369              
370             BSD 2-Clause License
371              
372             =head1 VERSION
373              
374             0.10
375              
376             =cut