File Coverage

blib/lib/Dancer/Plugin/FlashNote.pm
Criterion Covered Total %
statement 37 42 88.1
branch 9 16 56.2
condition 7 9 77.7
subroutine 9 9 100.0
pod n/a
total 62 76 81.5


line stmt bran cond sub pod time code
1             package Dancer::Plugin::FlashNote;
2             {
3             $Dancer::Plugin::FlashNote::VERSION = '1.0.4';
4             }
5              
6             # ABSTRACT: support notifications in your Dancer web application
7              
8 15     15   449288 use strict;
  15         50  
  15         655  
9 15     15   87 use warnings;
  15         26  
  15         454  
10 15     15   75 use Carp;
  15         35  
  15         1106  
11              
12 15     15   4101 use Dancer ':syntax';
  15         393404  
  15         98  
13 15     15   33678 use Dancer::Plugin;
  15         22453  
  15         19162  
14              
15             my $conf = plugin_setting;
16              
17             my %is_allowed_setting = map { $_ => 1 }
18             qw( token_name session_hash_key queue arguments dequeue );
19             if (my @extra = grep { !$is_allowed_setting{$_} } keys %$conf) {
20             croak __PACKAGE__ . ": invalid configuration keys (@extra)";
21             }
22              
23             my $token_name = $conf->{token_name} || 'flash';
24             my $session_hash_key = $conf->{session_hash_key} || '_flash';
25             my $queue = $conf->{queue} || 'multiple';
26             my $arguments = $conf->{arguments} || 'auto';
27             my $dequeue = $conf->{dequeue} || 'when_used';
28              
29             $arguments =~ m{\A(?: single | join | auto | array )\z}mxs
30             or croak "invalid arguments setting '$arguments'";
31              
32             sub _get_parameters {
33 42 100   42   313 if ($arguments eq 'single') { return shift }
  1 100       3  
    100          
34 3   100     22 elsif ($arguments eq 'join') { return join $, || '', @_ }
35 3         12 elsif ($arguments eq 'array') { return [@_] }
36 35 50       136 return @_ > 1 ? [@_] : shift;
37             } ## end sub _get_parameters
38              
39             if ($queue eq 'single') {
40             register flash => sub {
41 14     14   70018 my $value = _get_parameters(@_);
42 14         46 session $session_hash_key, $value;
43 14         59 return $value;
44             };
45             } ## end if ($queue eq 'single')
46             elsif ($queue eq 'multiple') {
47             register flash => sub {
48 28     28   85501 my $value = _get_parameters(@_);
49 28   100     117 my $flash = session($session_hash_key) || [];
50 28         6500 push @$flash, $value;
51 8         27 session($session_hash_key, $flash);
52 8         1310 return $value;
53             };
54             } ## end elsif ($queue eq 'multiple')
55             elsif ($queue eq 'key_single') {
56             register flash => sub {
57 14         3706 my $key = shift;
58 14         50 my $value = _get_parameters(@_);
59 14   100     1230 my $flash = session($session_hash_key) || {};
60 6         1214 $flash->{$key} = $value;
61             session($session_hash_key, $flash);
62             return $value;
63             };
64             } ## end elsif ($queue eq 'key_single')
65             elsif ($queue eq 'key_multiple') {
66             register flash => sub {
67             my $key = shift;
68             my $value = _get_parameters(@_);
69             my $flash = session($session_hash_key) || {};
70             push @{$flash->{$key}}, $value;
71             session($session_hash_key, $flash);
72             return $value;
73             };
74             } ## end elsif ($queue eq 'key_multiple')
75             else {
76             croak "invalid queueing style '$queue'";
77             }
78              
79             if ($dequeue eq 'by_key' and $queue !~ m{\Akey_}mxs) {
80             croak "dequeuing style 'by_key' only available "
81             . "with 'key_*' queueing styles";
82             }
83             if ($dequeue eq 'always') {
84             hook after => sub {
85             session $session_hash_key, undef;
86             };
87             }
88             my $template_sub = {
89             never => sub {
90             shift->{$token_name} = session $session_hash_key;
91             return;
92             },
93             always => sub {
94             shift->{$token_name} = session $session_hash_key;
95             return;
96             },
97             when_used => sub {
98             my $cache;
99             shift->{$token_name} = sub {
100             if (!$cache) {
101             $cache = session $session_hash_key;
102             session $session_hash_key, undef;
103             }
104             return $cache;
105             };
106             return;
107             },
108             by_key => sub {
109             my $flash = session($session_hash_key) || {};
110             shift->{$token_name} = {
111             map {
112             my $key = $_;
113             my $cache;
114             $key => sub {
115             if (!$cache) {
116             $cache = delete $flash->{$key};
117             }
118             return $cache;
119             };
120             } keys %$flash,
121             };
122             },
123             }->{$dequeue}
124             or croak "invalid dequeuing style '$dequeue'";
125             hook before_template => $template_sub;
126              
127             register flash_flush => sub {
128 2     2   2883 my $flash = session $session_hash_key;
129 2 50       344 return unless defined $flash;
130 2 50 33     12 if ((ref($flash) eq 'HASH') && @_) {
131 0         0 my @values = map { delete $flash->{$_} } @_;
  0         0  
132 0 0       0 return unless defined wantarray();
133 0 0       0 return $values[0] unless wantarray();
134 0         0 return @values;
135             } ## end if ((ref($flash) eq 'HASH'...
136             else {
137 2         5 session $session_hash_key, undef;
138 2         283 return $flash;
139             }
140             };
141              
142             register_plugin;
143              
144             1;
145              
146              
147              
148             =pod
149              
150             =head1 NAME
151              
152             Dancer::Plugin::FlashNote - support notifications in your Dancer web application
153              
154             =head1 VERSION
155              
156             version 1.0.4
157              
158             =head1 SYNOPSIS
159              
160             # In the configuration you choose a "flash style", e.g.
161             # notifications stored in an array and automatically
162             # removed from the session when used
163             plugins:
164             FlashNote:
165             queue: multiple
166             dequeue: when_used
167              
168              
169             # In the application you generate flash notifications
170             package MyWebService;
171              
172             use Dancer;
173             use Dancer::Plugin::FlashNote;
174              
175             get '/hello/:id/:who' => sub {
176             flash 'A first error message'
177             unless params->{id} =~ /\A\d+\z/mxs;
178             flash 'A second error message'
179             unless params->{who} =~ /\A(?: you | me )\z/mxs;
180             # ...
181             template 'index';
182             };
183              
184              
185             # Then, in the layout you consume them and they are flushed
186             <% IF flash %>
187            
188             <% FOR notice = flash %>
189            
  • <% notice | html %>
  • 190             <% END %>
    191            
    192             <% END %>
    193              
    194             =head1 DESCRIPTION
    195              
    196             This plugin helps you display temporary messages, so called "flash messages".
    197             It provides a C method to define the message. The plugin then takes
    198             care of attaching the content to the session, propagating it to the templating
    199             system, and then removing it from the session. On the other hand, you still
    200             have to take care to find a suitable place to put the messages.
    201              
    202             =head2 Dancer::Plugin::FlashMessage
    203              
    204             This plugin originages from L by
    205             Damien "dams" Krotkine. While I appreciated the idea and the implementation,
    206             I felt that the way of use did not fit my needs and after some discussion
    207             we decided to go for different modules: he would retain only the one
    208             single behaviour that he thought was the best, and I would implement the
    209             different variations. I learned a lot from the discussion, so beware: the
    210             Dancer people can teach you a lot!
    211              
    212             This configuration should give you a behaviour equivalent to
    213             L:
    214              
    215             plugins:
    216             FlashNote:
    217             queue: key_single
    218             arguments: single
    219             dequeue: by_key
    220              
    221             but if you need it you can probably stick to L.
    222             Also note that with the configuration above the C function will
    223             not work in the same way as L when called
    224             with only one parameter: in dams' module this kind of call deletes the
    225             value associated to the key, in this module this just pushes an undef
    226             message.
    227              
    228             =head2 Styles
    229              
    230             Dancer::Plugin::FlashNote lets you decide the I