module Camping
Extends and overrides Camping for convenient RESTfulness.
Have a look at:
-
Camping::Controllers#REST for help on using RESTful controllers
-
#render for help on grouping your views by output format
Constants
- REQUEST_METHOD
Public Class Methods
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
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
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):
-
By providing a second parameter to render() (eg:
render(:foo, :HTML)
) -
By setting the @format variable
-
By providing a 'format' parameter in the request (i.e. @input)
-
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
# 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
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).
# 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