Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 657 lines (624 sloc) 22.606 kB
d5f0d99 * lib/camping.rb: debugged qs_parse further, added multiple value su…
_why authored
1 # == About camping.rb
2 #
3 # Camping comes with two versions of its source code. The code contained in
4 # lib/camping.rb is compressed, stripped of whitespace, using compact algorithms
5 # to keep it tight. The unspoken rule is that camping.rb should be flowed with
6 # no more than 80 characters per line and must not exceed four kilobytes.
7 #
8 # On the other hand, lib/camping-unabridged.rb contains the same code, laid out
9 # nicely with piles of documentation everywhere. This documentation is entirely
10 # generated from lib/camping-unabridged.rb using RDoc and our "flipbook" template
11 # found in the extras directory of any camping distribution.
cca5586 lib/camping-unabridged.rb: further documenting of the dependencies in…
_why authored
12 #
13 # == Requirements
14 #
15 # Camping requires at least Ruby 1.8.2.
16 #
17 # Camping depends on the following libraries. If you install through RubyGems,
18 # these will be automatically installed for you.
19 #
20 # * ActiveRecord, used in your models.
21 # ActiveRecord is an object-to-relational database mapper with adapters
22 # for SQLite3, MySQL, PostgreSQL, SQL Server and more.
23 # * Markaby, used in your views to describe HTML in plain Ruby.
24 # * MetAid, a few metaprogramming methods which Camping uses.
25 # * Tempfile, for storing file uploads.
26 #
27 # Camping also works well with Mongrel, the swift Ruby web server.
28 # http://rubyforge.org/projects/mongrel Mongrel comes with examples
29 # in its <tt>examples/camping</tt> directory.
30 #
d55d735 @judofyr First attempt to use Rack
judofyr authored
31 %w[tempfile uri rack].map { |l| require l }
6724a04 @zimbatm Removed Markaby as a direct dependency. As AR, it is loaded on demand.
zimbatm authored
32
d485565 @zimbatm * Introduced error 501 handling and changed NotFound and ServerError …
zimbatm authored
33 class Object #:nodoc:
34 def meta_def(m,&b) #:nodoc:
4b6a2c8 @zimbatm micro-optimizations and fix for ticket #96 : more strictness for Help…
zimbatm authored
35 (class<<self;self end).send(:define_method,m,&b)
6724a04 @zimbatm Removed Markaby as a direct dependency. As AR, it is loaded on demand.
zimbatm authored
36 end
37 end
abc7043 Initial import.
_why authored
38
c3e919e lib/camping.rb: docs!
_why authored
39 # == Camping
31e25ad README: top-level docs.
_why authored
40 #
41 # The camping module contains three modules for separating your application:
42 #
cca5586 lib/camping-unabridged.rb: further documenting of the dependencies in…
_why authored
43 # * Camping::Models for your database interaction classes, all derived from ActiveRecord::Base.
31e25ad README: top-level docs.
_why authored
44 # * Camping::Controllers for storing controller classes, which map URLs to code.
45 # * Camping::Views for storing methods which generate HTML.
46 #
47 # Of use to you is also one module for storing helpful additional methods:
48 #
49 # * Camping::Helpers which can be used in controllers and views.
50 #
f062c5b * lib/camping-unabridged.rb: remove most of the postamble docs, exce…
_why authored
51 # == The Camping Server
31e25ad README: top-level docs.
_why authored
52 #
f062c5b * lib/camping-unabridged.rb: remove most of the postamble docs, exce…
_why authored
53 # How do you run Camping apps? Oh, uh... The Camping Server!
31e25ad README: top-level docs.
_why authored
54 #
f062c5b * lib/camping-unabridged.rb: remove most of the postamble docs, exce…
_why authored
55 # The Camping Server is, firstly and thusly, a set of rules. At the very least, The Camping Server must:
31e25ad README: top-level docs.
_why authored
56 #
f062c5b * lib/camping-unabridged.rb: remove most of the postamble docs, exce…
_why authored
57 # * Load all Camping apps in a directory.
58 # * Load new apps that appear in that directory.
59 # * Mount those apps according to their filename. (e.g. blog.rb is mounted at /blog.)
60 # * Run each app's <tt>create</tt> method upon startup.
61 # * Reload the app if its modification time changes.
62 # * Reload the app if it requires any files under the same directory and one of their modification times changes.
63 # * Support the X-Sendfile header.
31e25ad README: top-level docs.
_why authored
64 #
f062c5b * lib/camping-unabridged.rb: remove most of the postamble docs, exce…
_why authored
65 # In fact, Camping comes with its own little The Camping Server.
66 #
67 # At a command prompt, run: <tt>camping examples/</tt> and the entire <tt>examples/</tt> directory will be served.
68 #
69 # Configurations also exist for Apache and Lighttpd. See http://code.whytheluckystiff.net/camping/wiki/TheCampingServer.
cca5586 lib/camping-unabridged.rb: further documenting of the dependencies in…
_why authored
70 #
71 # == The <tt>create</tt> method
72 #
73 # Many postambles will check for your application's <tt>create</tt> method and will run it
74 # when the web server starts up. This is a good place to check for database tables and create
75 # those tables to save users of your application from needing to manually set them up.
76 #
77 # def Blog.create
78 # unless Blog::Models::Post.table_exists?
79 # ActiveRecord::Schema.define do
80 # create_table :blog_posts, :force => true do |t|
81 # t.column :user_id, :integer, :null => false
82 # t.column :title, :string, :limit => 255
83 # t.column :body, :text
84 # end
85 # end
86 # end
87 # end
88 #
89 # For more tips, see http://code.whytheluckystiff.net/camping/wiki/GiveUsTheCreateMethod.
abc7043 Initial import.
_why authored
90 module Camping
616d685 lib/camping.rb: redirect now picks the route most likely.
_why authored
91 C = self
fa83d7b @zimbatm -40 octets, we're now at 4040
zimbatm authored
92 S = IO.read(__FILE__) rescue nil
d1c2c7f @judofyr Small fixes
judofyr authored
93 P = "<h1>Cam\ping Problem!</h1><h2>%s</h2>"
819f584 @zimbatm ActiveSupport dependency gone ! H is now simply inheriting from Hash.
zimbatm authored
94 # An object-like Hash.
427f085 * lib/camping-unabridged.rb: switched from OpenStruct to HashWithInd…
_why authored
95 # All Camping query string and cookie variables are loaded as this.
cca5586 lib/camping-unabridged.rb: further documenting of the dependencies in…
_why authored
96 #
97 # To access the query string, for instance, use the <tt>@input</tt> variable.
98 #
c92fece @zimbatm Fixed ticket #132. Documentation issue.
zimbatm authored
99 # module Blog::Controllers
cca5586 lib/camping-unabridged.rb: further documenting of the dependencies in…
_why authored
100 # class Index < R '/'
101 # def get
102 # if page = @input.page.to_i > 0
103 # page -= 1
104 # end
105 # @posts = Post.find :all, :offset => page * 20, :limit => 20
106 # render :index
107 # end
108 # end
109 # end
110 #
111 # In the above example if you visit <tt>/?page=2</tt>, you'll get the second
112 # page of twenty posts. You can also use <tt>@input[:page]</tt> or <tt>@input['page']</tt>
113 # to get the value for the <tt>page</tt> query variable.
114 #
115 # Use the <tt>@cookies</tt> variable in the same fashion to access cookie variables.
819f584 @zimbatm ActiveSupport dependency gone ! H is now simply inheriting from Hash.
zimbatm authored
116 class H < Hash
08f3318 * lib/camping.rb: allow markaby fragments to come out of controllers…
_why authored
117 # Gets or sets keys in the hash.
118 #
119 # @cookies.my_favorite = :macadamian
120 # @cookies.my_favorite
121 # => :macadamian
122 #
a5c5561 * lib/camping.rb: trimmed about 100 bytes here and there. also, patc…
_why authored
123 def method_missing(m,*a)
819f584 @zimbatm ActiveSupport dependency gone ! H is now simply inheriting from Hash.
zimbatm authored
124 m.to_s=~/=$/?self[$`]=a[0]:a==[]?self[m.to_s]:super
66f83dd lib/camping.rb: trying to get the HashWithIndifferentAccess to work m…
_why authored
125 end
819f584 @zimbatm ActiveSupport dependency gone ! H is now simply inheriting from Hash.
zimbatm authored
126 alias u merge!
4b6a2c8 @zimbatm micro-optimizations and fix for ticket #96 : more strictness for Help…
zimbatm authored
127 undef id, type
427f085 * lib/camping-unabridged.rb: switched from OpenStruct to HashWithInd…
_why authored
128 end
129
cca5586 lib/camping-unabridged.rb: further documenting of the dependencies in…
_why authored
130 # Helpers contains methods available in your controllers and views. You may add
131 # methods of your own to this module, including many helper methods from Rails.
132 # This is analogous to Rails' <tt>ApplicationHelper</tt> module.
133 #
134 # == Using ActionPack Helpers
135 #
136 # If you'd like to include helpers from Rails' modules, you'll need to look up the
137 # helper module in the Rails documentation at http://api.rubyonrails.org/.
138 #
139 # For example, if you look up the <tt>ActionView::Helpers::FormHelper</tt> class,
140 # you'll find that it's loaded from the <tt>action_view/helpers/form_helper.rb</tt>
141 # file. You'll need to have the ActionPack gem installed for this to work.
142 #
143 # require 'action_view/helpers/form_helper.rb'
144 #
145 # # This example is unfinished.. soon..
146 #
616d685 lib/camping.rb: redirect now picks the route most likely.
_why authored
147 module Helpers
c3e919e lib/camping.rb: docs!
_why authored
148 # From inside your controllers and views, you will often need to figure out
149 # the route used to get to a certain controller +c+. Pass the controller class
150 # and any arguments into the R method, a string containing the route will be
151 # returned to you.
152 #
153 # Assuming you have a specific route in an edit controller:
154 #
155 # class Edit < R '/edit/(\d+)'
156 #
157 # A specific route to the Edit controller can be built with:
158 #
159 # R(Edit, 1)
160 #
161 # Which outputs: <tt>/edit/1</tt>.
162 #
163 # You may also pass in a model object and the ID of the object will be used.
164 #
165 # If a controller has many routes, the route will be selected if it is the
166 # first in the routing list to have the right number of arguments.
167 #
9a2308d * lib/camping.rb: added Helpers.URL, which builds a complete URL to …
_why authored
168 # == Using R in the View
169 #
170 # Keep in mind that this route doesn't include the root path.
171 # You will need to use <tt>/</tt> (the slash method above) in your controllers.
172 # Or, go ahead and use the Helpers#URL method to build a complete URL for a route.
173 #
174 # However, in your views, the :href, :src and :action attributes automatically
175 # pass through the slash method, so you are encouraged to use <tt>R</tt> or
176 # <tt>URL</tt> in your views.
177 #
178 # module Blog::Views
179 # def menu
180 # div.menu! do
181 # a 'Home', :href => URL()
182 # a 'Profile', :href => "/profile"
183 # a 'Logout', :href => R(Logout)
184 # a 'Google', :href => 'http://google.com'
185 # end
186 # end
187 # end
188 #
189 # Let's say the above example takes place inside an application mounted at
190 # <tt>http://localhost:3301/frodo</tt> and that a controller named <tt>Logout</tt>
191 # is assigned to route <tt>/logout</tt>. The HTML will come out as:
192 #
193 # <div id="menu">
98e4333 * lib: hiding useless things in the docs.
_why authored
194 # <a href="//localhost:3301/frodo/">Home</a>
9a2308d * lib/camping.rb: added Helpers.URL, which builds a complete URL to …
_why authored
195 # <a href="/frodo/profile">Profile</a>
196 # <a href="/frodo/logout">Logout</a>
197 # <a href="http://google.com">Google</a>
198 # </div>
199 #
a1fa3d7 * lib/camping.rb: new support for ordered controllers. uses the `in…
_why authored
200 def R(c,*g)
696e702 * lib/camping.rb: added query-string building to `R()`.
_why authored
201 p,h=/\(.+?\)/,g.grep(Hash)
4b6a2c8 @zimbatm micro-optimizations and fix for ticket #96 : more strictness for Help…
zimbatm authored
202 g-=h
203 raise "bad route" unless u = c.urls.find{|x|
204 break x if x.scan(p).size == g.size &&
205 /^#{x}\/?$/ =~ (x=g.inject(x){|x,a|
206 x.sub p,C.escape((a[a.class.primary_key]rescue a))})
207 }
208 h.any?? u+"?"+h[0].map{|x|x.map{|z|C.escape z}*"="}*"&": u
616d685 lib/camping.rb: redirect now picks the route most likely.
_why authored
209 end
5723cd8 * lib/camping.rb: allow the Camping scriptable dispatcher (Camping.m…
_why authored
210
2989e76 * lib/camping-unabridged.rb: corrected the docs for URL(), which giv…
_why authored
211 # Simply builds a complete path from a path +p+ within the app. If your application is
212 # mounted at <tt>/blog</tt>:
c3e919e lib/camping.rb: docs!
_why authored
213 #
61e9b19 lib/camping.rb: added Camping.goes, bug in routing.
_why authored
214 # self / "/view/1" #=> "/blog/view/1"
215 # self / "styles.css" #=> "styles.css"
663796c camping.gemspec: generate rdoc.
_why authored
216 # self / R(Edit, 1) #=> "/blog/edit/1"
c3e919e lib/camping.rb: docs!
_why authored
217 #
7ca56b0 lib/camping.rb: have Helpers./ throw an error on nil. shorten Mab.ta…
_why authored
218 def /(p); p[/^\//]?@root+p:p end
43fbe7c * lib/camping.rb: Helpers#URL returns a URI object. This way relati…
_why authored
219 # Builds a URL route to a controller or a path, returning a URI object.
220 # This way you'll get the hostname and the port number, a complete URL.
9a2308d * lib/camping.rb: added Helpers.URL, which builds a complete URL to …
_why authored
221 #
222 # You can use this to grab URLs for controllers using the R-style syntax.
223 # So, if your application is mounted at <tt>http://test.ing/blog/</tt>
224 # and you have a View controller which routes as <tt>R '/view/(\d+)'</tt>:
225 #
04eeaf4 @judofyr Helpers#URL will now prepend the scheme
judofyr authored
226 # URL(View, @post.id) #=> #<URL:http://test.ing/blog/view/12>
9a2308d * lib/camping.rb: added Helpers.URL, which builds a complete URL to …
_why authored
227 #
228 # Or you can use the direct path:
229 #
04eeaf4 @judofyr Helpers#URL will now prepend the scheme
judofyr authored
230 # self.URL #=> #<URL:http://test.ing/blog/>
231 # self.URL + "view/12" #=> #<URL:http://test.ing/blog/view/12>
232 # URL("/view/12") #=> #<URL:http://test.ing/blog/view/12>
9a2308d * lib/camping.rb: added Helpers.URL, which builds a complete URL to …
_why authored
233 #
43fbe7c * lib/camping.rb: Helpers#URL returns a URI object. This way relati…
_why authored
234 # It's okay to pass URL strings through this method as well:
235 #
04eeaf4 @judofyr Helpers#URL will now prepend the scheme
judofyr authored
236 # URL("http://google.com") #=> #<URL:http://google.com>
43fbe7c * lib/camping.rb: Helpers#URL returns a URI object. This way relati…
_why authored
237 #
238 # Any string which doesn't begin with a slash will pass through
239 # unscathed.
9a2308d * lib/camping.rb: added Helpers.URL, which builds a complete URL to …
_why authored
240 def URL c='/',*a
241 c = R(c, *a) if c.respond_to? :urls
242 c = self/c
04eeaf4 @judofyr Helpers#URL will now prepend the scheme
judofyr authored
243 c = @request.url.split("/",4)[0..-2].join("/")+c if c[/^\//]
43fbe7c * lib/camping.rb: Helpers#URL returns a URI object. This way relati…
_why authored
244 URI(c)
9a2308d * lib/camping.rb: added Helpers.URL, which builds a complete URL to …
_why authored
245 end
616d685 lib/camping.rb: redirect now picks the route most likely.
_why authored
246 end
c3e919e lib/camping.rb: docs!
_why authored
247
a948a00 * lib/camping.rb: moved Controllers::Base to Base and Controllers::R…
_why authored
248 # Camping::Base is built into each controller by way of the generic routing
249 # class Camping::R. In some ways, this class is trying to do too much, but
250 # it saves code for all the glue to stay in one place.
251 #
252 # Forgivable, considering that it's only really a handful of methods and accessors.
253 #
254 # == Treating controller methods like Response objects
255 #
256 # Camping originally came with a barebones Response object, but it's often much more readable
257 # to just use your controller as the response.
258 #
259 # Go ahead and alter the status, cookies, headers and body instance variables as you
260 # see fit in order to customize the response.
c3e919e lib/camping.rb: docs!
_why authored
261 #
262 # module Camping::Controllers
a948a00 * lib/camping.rb: moved Controllers::Base to Base and Controllers::R…
_why authored
263 # class SoftLink
264 # def get
265 # redirect "/"
266 # end
c3e919e lib/camping.rb: docs!
_why authored
267 # end
268 # end
269 #
a948a00 * lib/camping.rb: moved Controllers::Base to Base and Controllers::R…
_why authored
270 # Is equivalent to:
c3e919e lib/camping.rb: docs!
_why authored
271 #
a948a00 * lib/camping.rb: moved Controllers::Base to Base and Controllers::R…
_why authored
272 # module Camping::Controllers
273 # class SoftLink
274 # def get
275 # @status = 302
276 # @headers['Location'] = "/"
277 # end
278 # end
279 # end
c3e919e lib/camping.rb: docs!
_why authored
280 #
a948a00 * lib/camping.rb: moved Controllers::Base to Base and Controllers::R…
_why authored
281 module Base
b09de27 @judofyr Removing @env - use @headers and @request instead
judofyr authored
282 attr_accessor :input, :cookies, :headers, :body, :status, :root
5723cd8 * lib/camping.rb: allow the Camping scriptable dispatcher (Camping.m…
_why authored
283
a948a00 * lib/camping.rb: moved Controllers::Base to Base and Controllers::R…
_why authored
284 # Display a view, calling it by its method name +m+. If a <tt>layout</tt>
285 # method is found in Camping::Views, it will be used to wrap the HTML.
c3e919e lib/camping.rb: docs!
_why authored
286 #
287 # module Camping::Controllers
a948a00 * lib/camping.rb: moved Controllers::Base to Base and Controllers::R…
_why authored
288 # class Show
c3e919e lib/camping.rb: docs!
_why authored
289 # def get
a948a00 * lib/camping.rb: moved Controllers::Base to Base and Controllers::R…
_why authored
290 # @posts = Post.find :all
291 # render :index
c3e919e lib/camping.rb: docs!
_why authored
292 # end
293 # end
294 # end
295 #
a948a00 * lib/camping.rb: moved Controllers::Base to Base and Controllers::R…
_why authored
296 def render(m); end; undef_method :render
297
298 # Any stray method calls will be passed to Markaby. This means you can reply
299 # with HTML directly from your controller for quick debugging.
c3e919e lib/camping.rb: docs!
_why authored
300 #
301 # module Camping::Controllers
a948a00 * lib/camping.rb: moved Controllers::Base to Base and Controllers::R…
_why authored
302 # class Info
b09de27 @judofyr Removing @env - use @headers and @request instead
judofyr authored
303 # def get; code @headers.inspect end
c3e919e lib/camping.rb: docs!
_why authored
304 # end
305 # end
306 #
a948a00 * lib/camping.rb: moved Controllers::Base to Base and Controllers::R…
_why authored
307 # If you have a <tt>layout</tt> method in Camping::Views, it will be used to
308 # wrap the HTML.
5723cd8 * lib/camping.rb: allow the Camping scriptable dispatcher (Camping.m…
_why authored
309 def method_missing(*a,&b)
310 a.shift if a[0]==:render
2a606f7 * lib/camping.rb: novaa saves us 54 pennybits.
_why authored
311 m=Mab.new({},self)
5723cd8 * lib/camping.rb: allow the Camping scriptable dispatcher (Camping.m…
_why authored
312 s=m.capture{send(*a,&b)}
ae02dd3 @zimbatm * Rakefile : Clean the generated test.log in test/, new test task.
zimbatm authored
313 s=m.capture{send(:layout){s}} if /^_/!~a[0].to_s and m.respond_to?:layout
5a49057 * lib/camping.rb: let's not cast Markaby to a string by default, tha…
_why authored
314 s
a948a00 * lib/camping.rb: moved Controllers::Base to Base and Controllers::R…
_why authored
315 end
c3e919e lib/camping.rb: docs!
_why authored
316
d485565 @zimbatm * Introduced error 501 handling and changed NotFound and ServerError …
zimbatm authored
317 # A quick means of setting this controller's status, body and headers.
318 # Used internally by Camping, but... by all means...
319 #
320 # r(302, '', 'Location' => self / "/view/12")
321 #
322 # Is equivalent to:
323 #
324 # redirect "/view/12"
325 #
7b0c6f7 @judofyr Base#r supports the Rack-array too
judofyr authored
326 # You can also switch the body and the header in order to support Rack:
327 #
328 # r(302, {'Location' => self / "/view/12"}, '')
329 #
d485565 @zimbatm * Introduced error 501 handling and changed NotFound and ServerError …
zimbatm authored
330 # See also: #r404, #r500 and #r501
d55d735 @judofyr First attempt to use Rack
judofyr authored
331 def r(s, b, h = {})
7b0c6f7 @judofyr Base#r supports the Rack-array too
judofyr authored
332 if Hash===b
333 t = b.dup
334 b = h.dup
335 h = t
336 end
d55d735 @judofyr First attempt to use Rack
judofyr authored
337 @status = s
338 @headers.merge!(h)
339 @body = b
340 end
d485565 @zimbatm * Introduced error 501 handling and changed NotFound and ServerError …
zimbatm authored
341
a948a00 * lib/camping.rb: moved Controllers::Base to Base and Controllers::R…
_why authored
342 # Formulate a redirect response: a 302 status with <tt>Location</tt> header
343 # and a blank body. Uses Helpers#URL to build the location from a controller
344 # route or path.
345 #
346 # So, given a root of <tt>http://localhost:3301/articles</tt>:
347 #
98e4333 * lib: hiding useless things in the docs.
_why authored
348 # redirect "view/12" # redirects to "//localhost:3301/articles/view/12"
349 # redirect View, 12 # redirects to "//localhost:3301/articles/view/12"
a948a00 * lib/camping.rb: moved Controllers::Base to Base and Controllers::R…
_why authored
350 #
08f3318 * lib/camping.rb: allow markaby fragments to come out of controllers…
_why authored
351 # <b>NOTE:</b> This method doesn't magically exit your methods and redirect.
352 # You'll need to <tt>return redirect(...)</tt> if this isn't the last statement
353 # in your code.
a948a00 * lib/camping.rb: moved Controllers::Base to Base and Controllers::R…
_why authored
354 def redirect(*a)
d1c2c7f @judofyr Small fixes
judofyr authored
355 r(302,'','Location'=>URL(*a).to_s)
a948a00 * lib/camping.rb: moved Controllers::Base to Base and Controllers::R…
_why authored
356 end
c3e919e lib/camping.rb: docs!
_why authored
357
d485565 @zimbatm * Introduced error 501 handling and changed NotFound and ServerError …
zimbatm authored
358 # Called when a controller was not found. It is mainly used internally, but it can
359 # also be useful for you, if you want to filter some parameters.
360 #
361 # module Camping
362 # def r404(p=env.PATH)
363 # @status = 404
364 # div do
365 # h1 'Camping Problem!'
366 # h2 "#{p} not found"
367 # end
368 # end
369 # end
a948a00 * lib/camping.rb: moved Controllers::Base to Base and Controllers::R…
_why authored
370 #
d485565 @zimbatm * Introduced error 501 handling and changed NotFound and ServerError …
zimbatm authored
371 # See: I
372 def r404(p=env.PATH)
373 r(404, P % "#{p} not found")
374 end
375
376 # If there is a parse error in Camping or in your application's source code, it will not be caught
377 # by Camping. The controller class +k+ and request method +m+ (GET, POST, etc.) where the error
378 # took place are passed in, along with the Exception +e+ which can be mined for useful info.
a948a00 * lib/camping.rb: moved Controllers::Base to Base and Controllers::R…
_why authored
379 #
d485565 @zimbatm * Introduced error 501 handling and changed NotFound and ServerError …
zimbatm authored
380 # You can overide it, but if you have an error in here, it will be uncaught !
a948a00 * lib/camping.rb: moved Controllers::Base to Base and Controllers::R…
_why authored
381 #
d485565 @zimbatm * Introduced error 501 handling and changed NotFound and ServerError …
zimbatm authored
382 # See: I
383 def r500(k,m,x)
384 r(500, P % "#{k}.#{m}" + "<h3>#{x.class} #{x.message}: <ul>#{x.backtrace.map{|b|"<li>#{b}</li>"}}</ul></h3>")
385 end
386
387 # Called if an undefined method is called on a Controller, along with the request method +m+ (GET, POST, etc.)
a948a00 * lib/camping.rb: moved Controllers::Base to Base and Controllers::R…
_why authored
388 #
d485565 @zimbatm * Introduced error 501 handling and changed NotFound and ServerError …
zimbatm authored
389 # See: I
390 def r501(m=@method)
391 r(501, P % "#{m.upcase} not implemented")
392 end
c3e919e lib/camping.rb: docs!
_why authored
393
864472e * lib/camping.rb: committing Base#to_a (discussed at http://redhande…
_why authored
394 # Turn a controller into an array. This is designed to be used to pipe
395 # controllers into the <tt>r</tt> method. A great way to forward your
396 # requests!
397 #
398 # class Read < '/(\d+)'
399 # def get(id)
400 # Post.find(id)
401 # rescue
b09de27 @judofyr Removing @env - use @headers and @request instead
judofyr authored
402 # r *Blog.get(:NotFound, @headers.REQUEST_URI)
864472e * lib/camping.rb: committing Base#to_a (discussed at http://redhande…
_why authored
403 # end
404 # end
405 #
d55d735 @judofyr First attempt to use Rack
judofyr authored
406 def to_a
d1c2c7f @judofyr Small fixes
judofyr authored
407 @response.to_a
d55d735 @judofyr First attempt to use Rack
judofyr authored
408 end
409
410 def initialize(env) #:nodoc:
411 @request = Rack::Request.new(env)
412 @root = @request.script_name.sub(/\/$/,'')
d1c2c7f @judofyr Small fixes
judofyr authored
413 @input = H[@request.params]
414 @cookies = H[@request.cookies]
d55d735 @judofyr First attempt to use Rack
judofyr authored
415
416 @response = Rack::Response.new
417 @headers = @response.headers
418 @body = @response.body
419 @status = @response.status
4f59949 @judofyr Cleaning up @input after Rack
judofyr authored
420
421 @input.each do |key, value|
422 if key[-2..-1] == "[]"
423 @input[key[0..-3]] = @input.delete(key)
424 elsif key =~ /(.*)\[([^\]])\]$/
425 (@input[$1] ||= {})[$2] = @input.delete(key)
426 end
427 end
a948a00 * lib/camping.rb: moved Controllers::Base to Base and Controllers::R…
_why authored
428 end
abc7043 Initial import.
_why authored
429
08f3318 * lib/camping.rb: allow markaby fragments to come out of controllers…
_why authored
430 # All requests pass through this method before going to the controller. Some magic
431 # in Camping can be performed by overriding this method.
432 #
433 # See http://code.whytheluckystiff.net/camping/wiki/BeforeAndAfterOverrides for more
434 # on before and after overrides with Camping.
435 def service(*a)
d55d735 @judofyr First attempt to use Rack
judofyr authored
436 @response.body = send(@request.request_method.downcase, *a) || @body
437 @response.status = @status
438 @response.headers.merge!(@headers)
439 @cookies.each do |key, value|
440 @response.set_cookie(key, value)
441 end
a948a00 * lib/camping.rb: moved Controllers::Base to Base and Controllers::R…
_why authored
442 self
443 end
444 end
c3e919e lib/camping.rb: docs!
_why authored
445
a948a00 * lib/camping.rb: moved Controllers::Base to Base and Controllers::R…
_why authored
446 # Controllers is a module for placing classes which handle URLs. This is done
447 # by defining a route to each class using the Controllers::R method.
448 #
449 # module Camping::Controllers
450 # class Edit < R '/edit/(\d+)'
451 # def get; end
452 # def post; end
453 # end
454 # end
455 #
456 # If no route is set, Camping will guess the route from the class name.
457 # The rule is very simple: the route becomes a slash followed by the lowercased
458 # class name. See Controllers::D for the complete rules of dispatch.
459 #
460 # == Special classes
461 #
462 # There are two special classes used for handling 404 and 500 errors. The
463 # NotFound class handles URLs not found. The ServerError class handles exceptions
464 # uncaught by your application.
0777ceb @zimbatm Synched camping and unabridged by using `rake diff`. Used attr_reader…
zimbatm authored
465 X = module Controllers
5723cd8 * lib/camping.rb: allow the Camping scriptable dispatcher (Camping.m…
_why authored
466 @r = []
8771109 * lib/camping.rb: protect ServerError and NotFound (from zimbatm's #…
_why authored
467 class << self
98e4333 * lib: hiding useless things in the docs.
_why authored
468 def r #:nodoc:
469 @r
470 end
8771109 * lib/camping.rb: protect ServerError and NotFound (from zimbatm's #…
_why authored
471 # Add routes to a controller class by piling them into the R method.
472 #
473 # module Camping::Controllers
474 # class Edit < R '/edit/(\d+)', '/new'
475 # def get(id)
476 # if id # edit
477 # else # new
478 # end
479 # end
480 # end
481 # end
482 #
483 # You will need to use routes in either of these cases:
484 #
485 # * You want to assign multiple routes to a controller.
486 # * You want your controller to receive arguments.
487 #
488 # Most of the time the rules inferred by dispatch method Controllers::D will get you
489 # by just fine.
5723cd8 * lib/camping.rb: allow the Camping scriptable dispatcher (Camping.m…
_why authored
490 def R *u
491 r=@r
492 Class.new {
493 meta_def(:urls){u}
494 meta_def(:inherited){|x|r<<x}
495 }
496 end
8771109 * lib/camping.rb: protect ServerError and NotFound (from zimbatm's #…
_why authored
497
5723cd8 * lib/camping.rb: allow the Camping scriptable dispatcher (Camping.m…
_why authored
498 # Dispatch routes to controller classes.
8771109 * lib/camping.rb: protect ServerError and NotFound (from zimbatm's #…
_why authored
499 # For each class, routes are checked for a match based on their order in the routing list
500 # given to Controllers::R. If no routes were given, the dispatcher uses a slash followed
501 # by the name of the controller lowercased.
5723cd8 * lib/camping.rb: allow the Camping scriptable dispatcher (Camping.m…
_why authored
502 #
503 # Controllers are searched in this order:
504 #
505 # # Classes without routes, since they refer to a very specific URL.
506 # # Classes with routes are searched in order of their creation.
507 #
508 # So, define your catch-all controllers last.
d485565 @zimbatm * Introduced error 501 handling and changed NotFound and ServerError …
zimbatm authored
509 def D(p, m)
5723cd8 * lib/camping.rb: allow the Camping scriptable dispatcher (Camping.m…
_why authored
510 r.map { |k|
511 k.urls.map { |x|
d485565 @zimbatm * Introduced error 501 handling and changed NotFound and ServerError …
zimbatm authored
512 return (k.instance_method(m) rescue nil) ?
513 [k, m, *$~[1..-1]] : [I, 'r501', m] if p =~ /^#{x}\/?$/
5723cd8 * lib/camping.rb: allow the Camping scriptable dispatcher (Camping.m…
_why authored
514 }
515 }
d485565 @zimbatm * Introduced error 501 handling and changed NotFound and ServerError …
zimbatm authored
516 [I, 'r404', p]
8771109 * lib/camping.rb: protect ServerError and NotFound (from zimbatm's #…
_why authored
517 end
5723cd8 * lib/camping.rb: allow the Camping scriptable dispatcher (Camping.m…
_why authored
518
519 # The route maker, this is called by Camping internally, you shouldn't need to call it.
520 #
521 # Still, it's worth know what this method does. Since Ruby doesn't keep track of class
522 # creation order, we're keeping an internal list of the controllers which inherit from R().
523 # This method goes through and adds all the remaining routes to the beginning of the list
524 # and ensures all the controllers have the right mixins.
525 #
526 # Anyway, if you are calling the URI dispatcher from outside of a Camping server, you'll
527 # definitely need to call this at least once to set things up.
528 def M
98e4333 * lib: hiding useless things in the docs.
_why authored
529 def M #:nodoc:
530 end
5723cd8 * lib/camping.rb: allow the Camping scriptable dispatcher (Camping.m…
_why authored
531 constants.map { |c|
532 k=const_get(c)
596f092 @zimbatm Gained 7 octets :)
zimbatm authored
533 k.send :include,C,Base,Helpers,Models
d485565 @zimbatm * Introduced error 501 handling and changed NotFound and ServerError …
zimbatm authored
534 @r=[k]+r if r-[k]==r
5723cd8 * lib/camping.rb: allow the Camping scriptable dispatcher (Camping.m…
_why authored
535 k.meta_def(:urls){["/#{c.downcase}"]}if !k.respond_to?:urls
536 }
537 end
8771109 * lib/camping.rb: protect ServerError and NotFound (from zimbatm's #…
_why authored
538 end
539
d485565 @zimbatm * Introduced error 501 handling and changed NotFound and ServerError …
zimbatm authored
540
541 # Internal controller with no route. Used by #D and C.run to show internal messages.
542 class I < R()
abc7043 Initial import.
_why authored
543 end
0777ceb @zimbatm Synched camping and unabridged by using `rake diff`. Used attr_reader…
zimbatm authored
544
545 self
abc7043 Initial import.
_why authored
546 end
547
548 class << self
61e9b19 lib/camping.rb: added Camping.goes, bug in routing.
_why authored
549 # When you are running many applications, you may want to create independent
550 # modules for each Camping application. Namespaces for each. Camping::goes
551 # defines a toplevel constant with the whole MVC rack inside.
552 #
553 # require 'camping'
554 # Camping.goes :Blog
555 #
556 # module Blog::Controllers; ... end
557 # module Blog::Models; ... end
558 # module Blog::Views; ... end
559 #
560 def goes(m)
da3ed28 @zimbatm -50 octets gained by removing Camping::Apps.
zimbatm authored
561 eval S.gsub(/Camping/,m.to_s), TOPLEVEL_BINDING
61e9b19 lib/camping.rb: added Camping.goes, bug in routing.
_why authored
562 end
563
c3e919e lib/camping.rb: docs!
_why authored
564 # URL escapes a string.
565 #
566 # Camping.escape("I'd go to the museum straightway!")
567 # #=> "I%27d+go+to+the+museum+straightway%21"
568 #
d55d735 @judofyr First attempt to use Rack
judofyr authored
569 def escape(s); Rack::Utils.escape(s) end
8771109 * lib/camping.rb: protect ServerError and NotFound (from zimbatm's #…
_why authored
570
c3e919e lib/camping.rb: docs!
_why authored
571 # Unescapes a URL-encoded string.
572 #
f8744c2 * lib/camping.rb: store request body always in @in; unescape paths b…
_why authored
573 # Camping.un("I%27d+go+to+the+museum+straightway%21")
c3e919e lib/camping.rb: docs!
_why authored
574 # #=> "I'd go to the museum straightway!"
575 #
d55d735 @judofyr First attempt to use Rack
judofyr authored
576 def un(s); Rack::Utils.unescape(s) end
577
578 def call(env)
5723cd8 * lib/camping.rb: allow the Camping scriptable dispatcher (Camping.m…
_why authored
579 X.M
d55d735 @judofyr First attempt to use Rack
judofyr authored
580 e = H[env.to_hash]
581 k,m,*a=X.D e.PATH_INFO,(e.REQUEST_METHOD||'get').downcase
582 e.REQUEST_METHOD = m
583 con = k.new(e).service(*a)
584 con.to_a
abc7043 Initial import.
_why authored
585 end
1109984 * lib/camping.rb: experimenting with Camping.method_missing as an an…
_why authored
586
5723cd8 * lib/camping.rb: allow the Camping scriptable dispatcher (Camping.m…
_why authored
587 # The Camping scriptable dispatcher. Any unhandled method call to the app module will
588 # be sent to a controller class, specified as an argument.
589 #
590 # Blog.get(:Index)
591 # #=> #<Blog::Controllers::Index ... >
592 #
593 # The controller object contains all the @cookies, @body, @headers, etc. formulated by
594 # the response.
595 #
596 # You can also feed environment variables and query variables as a hash, the final
597 # argument.
598 #
599 # Blog.post(:Login, :input => {'username' => 'admin', 'password' => 'camping'})
600 # #=> #<Blog::Controllers::Login @user=... >
601 #
819f584 @zimbatm ActiveSupport dependency gone ! H is now simply inheriting from Hash.
zimbatm authored
602 # Blog.get(:Info, :env => {'HTTP_HOST' => 'wagon'})
b09de27 @judofyr Removing @env - use @headers and @request instead
judofyr authored
603 # #=> #<Blog::Controllers::Info @headers={'HTTP_HOST'=>'wagon'} ...>
5723cd8 * lib/camping.rb: allow the Camping scriptable dispatcher (Camping.m…
_why authored
604 #
1109984 * lib/camping.rb: experimenting with Camping.method_missing as an an…
_why authored
605 def method_missing(m, c, *a)
5723cd8 * lib/camping.rb: allow the Camping scriptable dispatcher (Camping.m…
_why authored
606 X.M
3065665 @judofyr Camping#method_missing should work now
judofyr authored
607 h=Hash===a[-1]?H[a.pop]:{}
608 e=H[h[:env]||{}].u({'rack.input'=>StringIO.new,'REQUEST_METHOD'=>m.to_s})
609 k = X.const_get(c).new(H[e])
610 k.send("input=",h[:input]) if h[:input]
5093efa @zimbatm +2 octets for the sake of ruby -w strickness validity
zimbatm authored
611 k.service(*a)
1109984 * lib/camping.rb: experimenting with Camping.method_missing as an an…
_why authored
612 end
abc7043 Initial import.
_why authored
613 end
c3e919e lib/camping.rb: docs!
_why authored
614
0777ceb @zimbatm Synched camping and unabridged by using `rake diff`. Used attr_reader…
zimbatm authored
615 # Views is an empty module for storing methods which create HTML. The HTML is described
616 # using the Markaby language.
617 #
618 # == Using the layout method
619 #
620 # If your Views module has a <tt>layout</tt> method defined, it will be called with a block
621 # which will insert content from your view.
622 module Views; include X, Helpers end
623
d3c7efe lib/camping.rb: trying to speed-up Markaby by creating the Mab class …
_why authored
624 # Models is an empty Ruby module for housing model classes derived
625 # from ActiveRecord::Base. As a shortcut, you may derive from Base
626 # which is an alias for ActiveRecord::Base.
627 #
628 # module Camping::Models
629 # class Post < Base; belongs_to :user end
630 # class User < Base; has_many :posts end
631 # end
632 #
633 # == Where Models are Used
634 #
635 # Models are used in your controller classes. However, if your model class
636 # name conflicts with a controller class name, you will need to refer to it
637 # using the Models module.
638 #
639 # module Camping::Controllers
640 # class Post < R '/post/(\d+)'
641 # def get(post_id)
642 # @post = Models::Post.find post_id
643 # render :index
644 # end
645 # end
646 # end
647 #
648 # Models cannot be referred to in Views at this time.
377bc91 * lib/camping/db.rb: support for tracking migrations and the schema_…
_why authored
649 module Models
864472e * lib/camping.rb: committing Base#to_a (discussed at http://redhande…
_why authored
650 autoload :Base,'camping/db'
377bc91 * lib/camping/db.rb: support for tracking migrations and the schema_…
_why authored
651 def Y;self;end
fdbf7ed * lib/camping.rb: auto-prefix tables to prevent name clash between s…
_why authored
652 end
0777ceb @zimbatm Synched camping and unabridged by using `rake diff`. Used attr_reader…
zimbatm authored
653
6724a04 @zimbatm Removed Markaby as a direct dependency. As AR, it is loaded on demand.
zimbatm authored
654 autoload :Mab, 'camping/mab'
abc7043 Initial import.
_why authored
655 end
5723cd8 * lib/camping.rb: allow the Camping scriptable dispatcher (Camping.m…
_why authored
656
Something went wrong with that request. Please try again.