[Dancer-users] Flash Message
damien krotkine
dkrotkine at gmail.com
Fri Jan 28 10:05:43 CET 2011
Hi,
Thanks for your contribution !
I was thinking of doing something along that line. I wasn't sure
Template::Simple was supporting coderef, but it seems it is :
elsif (ref($value)) {
local $@;
eval { $value = $value->$e };
$value = "" if $@;
}
So yes, I'll change the code, along with tests.
Your trick with $flashes staying in the scope longer than the token
leaves in the hash is clever
On 28 January 2011 09:02, Flavio Poletti <polettix at gmail.com> wrote:
> Hi,
> I thought a bit about it and I think that the current implementation is a
> bit too limited (this seems also what brian thinks in the bug
> report http://rt.cpan.org/Public/Bug/Display.html?id=65009 - at least from
> what I understand).
> The problem is that the flash message might have to be displayed in the next
> request, which happens when redirections kick in. In this case, the flash
> message should be set, kept in the session and removed only when it is
> actually displayed; this should happen automatically, i.e. without playing
> with the $persistent variable - which is global - or with further overhead
> on the controller side.
> Following brian's feedback, I tried to re-code the plugin with the following
> criteria:
> * the "flash" method only adds messages (and handles many of them for every
> category - you might have more than one error in a page). I see no point in
> removing messages while inside the controller;
> * the message removal logic is shifted in the template via an anonymous sub.
> If the sub is called then the flash cache is cleared, otherwise it remains
> there. This should guarantee that the messages are not removed until they
> get the chance to be displayed.
> This is the core of the recoding - not tested but should suffice to give you
> the idea:
> register flash => sub {
> my ($key, $value) = @_;
> my $flash = session($session_hash_key);
> if (! $flash) { # initialise the container for flash messages
> $flash = {};
> session($session_hash_key, $flash);
> }
> push @{$flash->{$key}}, $value;
> return;
> };
> before_template sub {
> my $obj = shift;
> my $flashes;
> $obj->{$token_name} = sub {
> if (! $flashes) { # first call, get messages and clear
> $flashes = session($session_hash_key) || {};
> session($session_hash_key, {});
> }
> return $flashes;
> };
> return;
> };
>
> IMHO there is no need for an "exists", in the template you can do like this:
> <% IF flash.errors %>...<% END %>
> The important thing to remember is that even checking for the presence of
> something inside "flash" clears the messages, which is consistent with the
> semantics that "they get cleared as soon as they have a chance to be
> displayed". The $flashes variable guarantees that they survive at least
> until the end of the request, i.e. you are able to call "flash" multiple
> times while handling a request and always get all messages.
> If you think that this makes sense, I can propose a pull request on GitHub
> or you can make the changes directly.
> Cheers,
> Flavio.
>
>
> On Tue, Jan 11, 2011 at 5:48 PM, damien krotkine <dkrotkine at gmail.com>
> wrote:
>>
>> I've re-implemented it to be more Rails-like, as sukria said.
>>
>> https://github.com/dams/Dancer-Plugin-FlashMessage
>>
>> and on CPAN, pending mirrors refresh.
>>
>> The funny part of the story ? the effective code is only 30 lines
>> long. Talking about Perl and Dancer expressiveness...
>>
>> dams.
>>
>> On 11 January 2011 14:40, Alexis Sukrieh <sukria at sukria.net> wrote:
>> > Hi list!
>> >
>> > Le 11/01/2011 14:29, damien krotkine a écrit :
>> >>
>> >> Hi,
>> >>
>> >> following previous thread, I've done a first implementation of
>> >> Dancer::Plugin::FlashMessage :
>> >>
>> >> https://github.com/dams/Dancer-Plugin-FlashMessage
>> >
>> > Great! Thanks a lot for your time dams, the myth is still alived!
>> > (Dancer's
>> > community)++
>> >
>> >
>> >
>> >> Some parts need to be improved, for instance :
>> >>
>> >> - it supports only one flash message
>> >> - the keywords are not short enough.
>> >>
>> >> So I think I'll change the implementation so that the template token is
>> >> simply called 'flash', and it'll be a hash, like in Rails. I'll also
>> >> change the registered method so that it's just flash() instead of
>> >> get_flash()
>> >
>> > I agree. I'd like to behave just like Rails' flash feature. The idea is
>> > pretty straight forward:
>> >
>> > "flash" is an accessor to a particular session hash table whose values
>> > can
>> > only be accessed once. Nothing more complicated than that.
>> >
>> > So to conclude, IMO, flash should be a wrapper like the following:
>> >
>> > sub flash {
>> > my ($key, $value) = @_;
>> > my $flash = session('_flash');
>> >
>> > # write
>> > if (@_ == 2) {
>> > $flash->{$key} = $value;
>> > session('_flash' => $flash);
>> > }
>> >
>> > # read (+ delete)
>> > else {
>> > my $value = $flash->{$key};
>> > delete $flash->{$key} if defined $value;
>> > session('_flash' => $flash);
>> > }
>> >
>> > return $value;
>> > }
>> >
>> > This is it, I think. This allows for the following code in a Dancer app:
>> >
>> >
>> > get '/' => sub {
>> > flash welcome => "This is a welcome message, only shown once";
>> > }
>> >
>> > Then, as soon as the key 'welcome' is accesed via flash('welcome'), the
>> > entry will be purged.
>> >
>> > This will be very helpful for authentication stuff in before filters,
>> > error
>> > messages, notifications, ....
>> >
>> >
>> > Kudos to dams!
>> >
>> > (BTW I haven't read the code yet)
>> >
>> > --
>> > Alexis Sukrieh
>> > _______________________________________________
>> > Dancer-users mailing list
>> > Dancer-users at perldancer.org
>> > http://www.backup-manager.org/cgi-bin/listinfo/dancer-users
>> >
>> _______________________________________________
>> Dancer-users mailing list
>> Dancer-users at perldancer.org
>> http://www.backup-manager.org/cgi-bin/listinfo/dancer-users
>
>
More information about the Dancer-users
mailing list