module Camping

Extends and overrides Camping for convenient RESTfulness.

Have a look at:

Constants

REQUEST_METHOD

Public Class Methods

qsp(qs, d='&;', y=nil, z=H[]) click to toggle source

Overrides Camping's query parsing method so that XML input is parsed into @input as an object usable more or less in the same manner as a standard Hash input.

This is necessary for dealing with ActiveResource calls, since ActiveResource submits its POST and PUT data as XML instead of the standard CGI query string.

The method automatically determines whether input is XML or standard CGI query and parses it accordingly.

# File lib/reststop.rb, line 58
def self.qsp(qs, d='&;', y=nil, z=H[])
  if qs.kind_of?(String) && !qs.nil? && !qs.empty? && qs =~ /^<\?xml/
    qxp(qs)
  else  
    m = proc {|_,o,n|o.u(n,&m)rescue([*o]<<n)}
    (qs||'').
        split(/[#{d}] */n).
        inject((b,z=z,H[])[0]) { |h,p| k, v=un(p).split('=',2)
            h.u(k.split(/[\]\[]+/).reverse.
                inject(y||v) { |x,i| H[i,x] },&m)
        }
  end
end
qxp(qxml) click to toggle source

Parse an XML query (input) into a Hash usable more or less the same way as a Camping's standard Hash input.

# File lib/reststop.rb, line 74
def self.qxp(qxml)
  #xml = XmlSimple.xml_in_string(qxml, 'forcearray' => false)
  H.new Hash.from_xml(qxml)
end

Public Instance Methods

render(action, format = nil) click to toggle source

Overrides Camping's render method to add the ability to specify a format module when rendering a view.

The format can also be specified in other ways (shown in this order of precedence):

  1. By providing a second parameter to render() (eg: render(:foo, :HTML))

  2. By setting the @format variable

  3. By providing a 'format' parameter in the request (i.e. @input)

  4. By adding a file-format extension to the url (e.g. /items.xml or /items/2.html).

For example, you could have:

module Foobar::Views

  module HTML
    def foo
      # ... render some HTML content
    end
  end

  module RSS
    def foo
      # ... render some RSS content
    end
  end

end

Then in your controller, you would call render() like this:

render(:foo, :HTML) # render the HTML version of foo

or

render(:foo, :RSS) # render the RSS version of foo

or

@format = :RSS
render(:foo) # render the RSS version of foo

or

# url is /foobar/1?format=RSS
render(:foo) # render the RSS version of foo

or

# url is /foobar/1.rss
render(:foo) # render the RSS version of foo

If no format is specified, render() will behave like it normally does in Camping, by looking for a matching view method directly in the Views module.

You can also specify a default format module by calling default_format after the format module definition. For example:

module Foobar::Views
  module HTML
    # ... etc.
  end
  default_format :HTML
end
Calls superclass method
# File lib/reststop.rb, line 168
def render(action, format = nil)
  format ||= @format
  
  if format.nil?
    begin
      ct = CONTENT_TYPE
    rescue NameError
      ct = 'text/html'
    end
    @headers['Content-Type'] ||= ct
    
    super(action)
  else
    m = Mab.new({}, self)
    mod = "Camping::Views::#{format.to_s}".constantize
    m.extend mod
    
    begin
      ct = mod::CONTENT_TYPE
    rescue NameError
      ct = "text/#{format.to_s.downcase}"
    end
    @headers['Content-Type'] = ct
    
    s = m.capture{m.send(action)}
    s = m.capture{send(:layout){s}} if /^_/!~a[0].to_s and m.respond_to?(:layout)
    s
  end
end
service(*a) click to toggle source

This override is taken and slightly modified from the Camping mailing list; it fakes PUT/DELETE HTTP methods, since many browsers don't support them.

In your forms you will have to add:

input :name => '_method', :type => 'hidden', :value => 'VERB'

… where VERB is one of put, post, or delete. The form's actual :method parameter must be 'post' (i.e. :method => post).

Calls superclass method
# File lib/reststop.rb, line 89
def service(*a)
  
  if @env.REQUEST_METHOD == 'POST' && (input['_method'] == 'put' || input['_method'] == 'delete')
    @env.REQUEST_METHOD = input._method.upcase
    @method = input._method
  end
  
  super(*a)
end