Module: Camping

Defined in:
lib/camping/tools.rb,
lib/camping.rb,
lib/camping/ar.rb,
lib/camping/loader.rb,
lib/camping/server.rb,
lib/camping/session.rb,
lib/camping/version.rb,
lib/camping/commands.rb,
lib/camping-unabridged.rb

Overview

If you’re new to Camping, you should probably start by reading the first chapters of The Camping Book.

Okay. So, the important thing to remember is that Camping.goes :Nuts copies the Camping module into Nuts. This means that you should never use any of these methods/classes on the Camping module, but rather on your own app. Here’s a short explanation on how Camping is organized:

  • Camping::Controllers is where your controllers live.

  • Camping::Models is where your models live.

  • Camping::Views is where your views live.

  • Camping::Base is a module which is included in all your controllers.

  • Camping::Helpers is a module with useful helpers, both for the controllers and the views. You should fill this up with your own helpers.

Camping also ships with:

  • Camping::Session adds states to your app.

  • Camping::Server starts up your app in development.

  • Camping::Reloader automatically reloads your apps when a file has changed.

More importantly, Camping also installs The Camping Server, please see Camping::Server.

Defined Under Namespace

Modules: Base, CommandsHelpers, Controllers, Helpers, Models, Session, Tools, Views Classes: Commands, Cookies, Generators, H, Loader, Server

Constant Summary collapse

C =
self
S =
IO.read(__FILE__) rescue nil
P =
"<h1>Cam\ping Problem!</h1><h2>%s</h2>"
U =
Rack::Utils
Apps =

Our array of Apps

[]
SK =

Key for r.session

"camping"
G =

Our array of Gear

[]
O =

Our Hash of Options

H.new
X =
Controllers
Reloader =
Loader
VERSION =
"3.1.3"

Class Method Summary collapse

Class Method Details

.call(e) ⇒ Object

Ruby web servers use this method to enter the Camping realm. The e argument is the environment variables hash as per the Rack specification. Array with [status, headers, body] is expected at the output.

See: github.com/rack/rack/blob/main/SPEC.rdoc



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

def call e;k,m,*a=X.D e["PATH_INFO"],e['REQUEST_METHOD'].
downcase,e;k.new(e,m,prx).service(*a).to_a;rescue;r500(:I,k,m,$!,:env=>e).to_a end

.gearObject

Helper method to list gear



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

def gear;G end

.goes(m, g = TOPLEVEL_BINDING) ⇒ Object

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

require 'camping'
Camping.goes :Nuts

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

Additionally, you can pass a Binding as the second parameter, which enables you to create a Camping-based application within another module.

Here’s an example of namespacing your web interface and code for a worker process together:

module YourApplication
  Camping.goes :Web, binding()
  module Web
    ...
  end
  module Worker
    ...
  end
end

All the applications will be available in Camping::Apps.

Camping offers a shortcut for adding thin files, and templates to your apps. Add them at the end of the same ruby file that you call ‘Camping.goes`:

require 'camping'
Camping.goes :Nuts

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

__END__

@@ /style.css
* { margin: 0; padding: 0 }

@@ /test.foo
<H1>Hello friends! Nice to meet you.<H1>

@@ index.erb
Hello <%= @world %>

Also sets the apps Meta Data. Can be found at O

@app: String - The app in question @parent: String - @root: String - @line_number: Int - The line number that the app was declared @file: String - The file location for this



912
913
914
915
916
917
# File 'lib/camping-unabridged.rb', line 912

def goes m,g=TOPLEVEL_BINDING;sp=caller[0].split('`')[0].split(":");fl,ln,pr=
sp[0],sp[1].to_i,nil;Apps<< a=eval(S.gsub(/Camping/,m.to_s),g,fl,ln);caller[0]=~/:/
IO.read(a.set:__FILE__,$`)=~/^__END__/&&(b=$'.split(/^@@\s*(.+?)\s*\r?\n/m)
).shift rescue nil;a.set :_t,H[*b||[]]
a.set :_meta, H[file: fl, line_number: ln, parent: self,
root: (name != "Cam\ping" ? '/' + CampTools.to_snake(name) : '/')];C.configure(a)end

.make_campObject

Create method to setup routes for Camping upon reload.



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

def make_camp;X.M prx;Apps.map(&:make_camp) end

.method_missing(m, c, *a) ⇒ Object

The Camping scriptable dispatcher. Any unhandled method call to the app module will be sent to a controller class, specified as an argument.

Blog.get(:Index)
#=> #<Blog::Controllers::Index ... >

The controller object contains all the @cookies, @body, @headers, etc. formulated by the response.

You can also feed environment variables and query variables as a hash, the final argument.

Blog.post(:Login, :input => {'username' => 'admin', 'password' => 'camping'})
#=> #<Blog::Controllers::Login @user=... >

Blog.get(:Info, :env => {'HTTP_HOST' => 'wagon'})
#=> #<Blog::Controllers::Info @headers={'HTTP_HOST'=>'wagon'} ...>


751
752
753
# File 'lib/camping-unabridged.rb', line 751

def method_missing m,c,*a;h=Hash===a[-1]?a.pop : {};e=H[Rack::MockRequest.
env_for('',h.delete(:env)||{})];k=X.const_get(c).new(e,m.to_s,prx);h.each{|i,v|
k.send"#{i}=",v};k.service(*a)end

.optionsObject

A hash where you can set different settings.



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

def options;O;end

.pack(*a, &b) ⇒ Object

Add gear to your app:

module Blog
  pack Camping::Gear::CSRF
end

Why have plugins in the first place if we can just include and extend our modules and classes directly? To perform setup actions!

Sometimes you might have ClassMethods that you want to modify Camping with, This gives us a way to do that. In your gear:

module MyGear
  module ClassMethods
    # Define Class Methods here
  end
  def self.included(mod)
    mod.extend(ClassMethods)
  end
end

Optionally a plugin may have a setup method and a ClassMethods module:

module MyGear
  def self.setup(s)
    # Perform setup actions
  end
  module ClassMethods
    # Define Class Methods here
  end
end


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

def pack*a,&b;G<< g=a.shift;include g;g.setup(self,*a,&b)end

.prxObject

An internal method used to return the current app’s url_prefix. the prefix is processed to make sure that it’s not all wonky. excessive trailing and leading slashes are removed. A trailing slash is added.



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

def prx;@_prx||=CampTools.normalize_slashes(O[:url_prefix])end

.routesObject

Helper method for getting routes from the controllers. helps Camping::Server map routes to multiple apps. Usage:

Nuts.routes
Camping.routes
Nuts.routes


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

def routes;(Apps.map(&:routes)<<X.v).flatten end

.set(k, v) ⇒ Object

Shortcut for setting options:

module Blog
  set :secret, "Hello!"
end


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

def set k,v;O[k]=v end

.use(*a, &b) ⇒ Object

Injects a middleware:

module Blog
  use Rack::MethodOverride
  use Rack::Session::Memcache, :key => "session"
end

This piece of code feels a bit confusing, but let’s walk through it. Rack apps all implement a Call method. This is how Rub web servers pass call the app, or code that you’re set up. In our case, our camping apps.

The Use method is setting up a new middleware, it first shifts the first argument supplied to Use, which should be the Middleware name, then initializes it. That’s your new middleware. Rack based middleware accept a single argument to their initialize methods, which is an app. Optionally settings and a block are supplied.

So a new app is made, and its settings are supplied, then immediately sent to the new middleware we just added. But the cool part is where we call meta_def. meta_def takes a symbol and a block, and defines a class method into the current context. Our current context is our camping app. So when we call it below we’re redefining the call method to call the new middleware that we just added. The ‘m` variable below represents our newly created middleware object, that we initialized with our old app. and because we’re defining a new call method with a block, it’s captured in that block.

This creates a sequence of middleware that isn’t recorded anywhere, but nonetheless is set up in the proper order and called in the proper order.



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

def use*a,&b;m=a.shift.new(method(:call),*a,&b);meta_def(:call){|e|m.call(e)}end

.versionObject



3
4
5
# File 'lib/camping/version.rb', line 3

def self.version
  VERSION
end