Ticket #154 (new enhancement)

Opened 6 months ago

Last modified 6 months ago

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.

Change History

Changed 6 months ago by vaz

  • description modified (diff)
Note: See TracTickets for help on using tickets.