Module: Camping

Defined in:
lib/camping-unabridged.rb,
lib/camping.rb

Overview

Camping

The camping module contains three modules for separating your application:

  • Camping::Models for your database interaction classes, all derived from ActiveRecord::Base.

  • Camping::Controllers for storing controller classes, which map URLs to code.

  • Camping::Views for storing methods which generate HTML.

Of use to you is also one module for storing helpful additional methods:

  • Camping::Helpers which can be used in controllers and views.

The postamble

Most Camping applications contain the entire application in a single script. The script begins by requiring Camping, then fills each of the three modules described above with classes and methods. Finally, a postamble puts the wheels in motion.

if __FILE__ == $0
  Camping::Models::Base.establish_connection :adapter => 'sqlite3',
      :database => 'blog3.db'
  Camping::Models::Base.logger = Logger.new('camping.log')
  Camping.create if Camping.respond_to? :create
  puts Camping.run
end

In the postamble, your job is to setup Camping::Models::Base (see: ActiveRecord::Base) and call Camping::run in a request loop. The above postamble is for a standard CGI setup, where the web server manages the request loop and calls the script once for every request.

For other configurations, see code.whytheluckystiff.net/camping/wiki/PostAmbles

The create method

Many postambles will check for your application’s create method and will run it when the web server starts up. This is a good place to check for database tables and create those tables to save users of your application from needing to manually set them up.

def Blog.create
  unless Blog::Models::Post.table_exists?
    ActiveRecord::Schema.define do
      create_table :blog_posts, :force => true do |t|
        t.column :id,       :integer, :null => false
        t.column :user_id,  :integer, :null => false
        t.column :title,    :string,  :limit => 255
        t.column :body,     :text
      end
    end
  end
end

For more tips, see code.whytheluckystiff.net/camping/wiki/GiveUsTheCreateMethod.

Defined Under Namespace

Modules: Controllers, Helpers, Models, Views Classes: H, Mab

Constant Summary collapse

C =
self
F =
__FILE__
S =
IO.read(F).gsub(/_+FILE_+/,F.dump)

Class Method Summary collapse

Class Method Details

.escape(s) ⇒ Object

URL escapes a string.

Camping.escape("I'd go to the museum straightway!")  
  #=> "I%27d+go+to+the+museum+straightway%21"


464
465
466
# File 'lib/camping-unabridged.rb', line 464

def 
escape s;s.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/n){'%'+$1.unpack('H2'*$1.size).join(
'%').upcase}.tr(' ','+') end

.goes(m) ⇒ Object

When you are running many applications, you may want to create independent modules for each Camping application. Namespaces for each. Camping::goes defines a toplevel constant with the whole MVC rack inside.

require 'camping'
Camping.goes :Blog

module Blog::Controllers; ... end
module Blog::Models;      ... end
module Blog::Views;       ... end


454
# File 'lib/camping-unabridged.rb', line 454

def goes m;eval(S.gsub(/Camping/,m.to_s),TOPLEVEL_BINDING)end

.kp(s) ⇒ Object

Parses a string of cookies from the Cookie header.



495
# File 'lib/camping-unabridged.rb', line 495

def kp(s);c=qs_parse(s,';,');end

.qs_parse(qs, d = '&;') ⇒ Object

Parses a query string into an Camping::H object.

input = Camping.qs_parse("name=Philarp+Tremain&hair=sandy+blonde")
input.name
  #=> "Philarp Tremaine"

Also parses out the Hash-like syntax used in PHP and Rails and builds nested hashes from it.

input = Camping.qs_parse("post[id]=1&post[user]=_why")
  #=> {'post' => {'id' => '1', 'user' => '_why'}}


484
485
486
487
# File 'lib/camping-unabridged.rb', line 484

def qs_parse qs,d='&;';m=proc{
|_,o,n|o.merge(n,&m)rescue([*o]<<n)};qs.to_s.split(/[#{d}] */n).inject(H[]){
|h,p|k,v=unescape(p).split('=',2);h.merge(k.split(/[\]\[]+/).reverse.inject(v){
|x,i|H[i,x]},&m)}end

.run(r = $stdin) ⇒ Object

Fields a request through Camping. For traditional CGI applications, the method can be executed without arguments.

if __FILE__ == $0
  Camping::Models::Base.establish_connection :adapter => 'sqlite3',
      :database => 'blog3.db'
  Camping::Models::Base.logger = Logger.new('camping.log')
  puts Camping.run
end

The Camping controller returned from run has a to_s method in case you are running from CGI or want to output the full HTTP output. In the above example, puts will call to_s for you.

For FastCGI and Webrick-loaded applications, you will need to use a request loop, with run at the center, passing in the read r and write w streams. You will also need to mimick or pass in the ENV replacement as part of your wrapper.

if __FILE__ == $0
  require 'fcgi'
    Camping::Models::Base.establish_connection :adapter => 'sqlite3',
        :database => 'blog3.db'
    Camping::Models::Base.logger = Logger.new('camping.log')
    FCGI.each do |req|
      req.out << Camping.run req.in, req.env
      req.finish
    end
  end
end


527
528
529
530
# File 'lib/camping-unabridged.rb', line 527

def run(r=$stdin,e=ENV);begin;k,a=Controllers.D "/#{e['PATH_INFO']}".
gsub(%r!/+!,'/');m=e['REQUEST_METHOD']||"GET";k.send :include,C,Controllers::Base,
Models;o=k.new;o.service(r,e,m.downcase,a);rescue\
=>x;Controllers::ServerError.new.service(r,e,"get",[k,m,x]);end;end

.unescape(s) ⇒ Object

Unescapes a URL-encoded string.

Camping.unescape("I%27d+go+to+the+museum+straightway%21") 
  #=> "I'd go to the museum straightway!"


470
471
# File 'lib/camping-unabridged.rb', line 470

def unescape(s);s.tr('+', ' ').gsub(/((?:%[0-9a-f\
A-F]{2})+)/n){[$1.delete('%')].pack('H*')} end