Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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