Ticket #154 (new enhancement)
flash, similar to Rails' ActionController::Flash
| Reported by: | vaz | Owned by: | somebody |
|---|---|---|---|
| Priority: | minor | Milestone: | |
| Component: | camping/session.rb | Version: | |
| Keywords: | flash session store | Cc: |
Description (last modified by vaz) (diff)
(I searched and didn't find anything about this, but sorry if it's been brought up already.)
I wanted some really handy shortcut kind of like the flash object in Rails, a bit more brief than writing @state[:msg]=thing to store a little message for the next request. So this is what I came up with:
# Flash is for storing a temporary message, for the next request
# cycle to use.
# *Differences from Rails*: can be any object, not just a hash
# of objects, which is convenient if you just want to pass
# one message along. It's initialized as a HashWithIndifferentAccess
# anyhow, so you can start using it like 'flash[:notice]=...' if you want.
# More concise and useful is simply 'flash 'my message'.
#
# Also note we have flash!(msg) instead of flash.now[:key]=msg.
#
# Because there may be a lot of requests (static content, etc)
# per page access, the flash sticks around until after you actually
# render something, or until it's replaced.
#
# With flash you can do this:
# flash 'my message' # <= set flash for next request
# flash[:notice] = 'msg' # <= Rails style...
# flash.notice = 'msg' # <= ...better.
# flash(any_object) # <= hey, why not.
# flash! 'my message' # <= set flash for this request
# flash? 'default msg' # <= set flash for this request, if it's empty
# flash # <= returns flash for this request
# @flash # <= same as flash()
#
module Camping::Session::Flash
# Rendering a view causes the flash to clear after this request.
def render(*a) r=super(*a); @state[:f_] = nil; r end
# Retrieves the flash before a request and stores the next one after, if there is one.
def service(*a)
@flash = @state[:f_].nil? ? Camping::H.new : @state[:f_]
r=super(*a)
@state[:f_] = @f_n_ if instance_variable_defined?('@f_n_')
r
end
# Sets the flash for the next request, or
# returns the flash if no arguments.
def flash(*a) a==[]?@flash:@f_n_=a.last end
# Sets the flash for this request.
def flash!(f) @f_n_=f; end
# Sets the flash for this request, if it's nil.
def flash?(f)
@flash.nil? or (@flash.is_a?(Hash) && @flash.empty?) ? @flash=f : @flash
end
end
I think it gives more flexibility than Rails' ActionController::Flash, you don't need to key your message as :notice if you're just going to use one, but you can use it basically the same as in Rails if you want to, too.
The use of the ! and ? are a bit non-standard, but I think they feel right.
Like?
Anyone can feel free to mess with it or do whatever they want with it.
