[DRE-commits] [SCM] camping.git branch, master, updated. debian/2.1.498-4-8-g771c63f
Paul van Tilburg
paulvt at debian.org
Thu Jun 6 19:55:10 UTC 2013
The following commit has been merged in the master branch:
commit ba280425608d0edd30c86285e8a07c97d403b3c5
Author: Paul van Tilburg <paulvt at debian.org>
Date: Thu Jun 6 21:07:13 2013 +0200
Imported Upstream version 2.1.532
diff --git a/README b/README.md
similarity index 52%
rename from README
rename to README.md
index ab8a622..b2ad3ce 100644
--- a/README
+++ b/README.md
@@ -1,4 +1,6 @@
-= Camping, a Microframework
+[](http://travis-ci.org/camping/camping)
+
+#Camping, a Microframework
Camping is a web framework which consistently stays at less than 4kB of code.
You can probably view the complete source code on a single page. But, you
@@ -9,48 +11,48 @@ file like many small CGIs. But to organize it as a Model-View-Controller
application like Rails does. You can then easily move it to Rails once you've
got it going.
-== A Camping Skeleton
+##A Camping Skeleton
A skeletal Camping blog could look like this:
- require 'camping'
+ require 'camping'
- Camping.goes :Blog
-
- module Blog::Models
- class Post < Base; belongs_to :user; end
- class Comment < Base; belongs_to :user; end
- class User < Base; end
- end
-
- module Blog::Controllers
- class Index
- def get
- @posts = Post.find :all
- render :index
- end
+ Camping.goes :Blog
+
+ module Blog::Models
+ class Post < Base; belongs_to :user; end
+ class Comment < Base; belongs_to :user; end
+ class User < Base; end
end
- end
-
- module Blog::Views
- def layout
- html do
- head { title "My Blog" }
- body do
- h1 "My Blog"
- self << yield
+
+ module Blog::Controllers
+ class Index
+ def get
+ @posts = Post.find :all
+ render :index
end
end
end
- def index
- @posts.each do |post|
- h1 post.title
+ module Blog::Views
+ def layout
+ html do
+ head { title "My Blog" }
+ body do
+ h1 "My Blog"
+ self << yield
+ end
+ end
+ end
+
+ def index
+ @posts.each do |post|
+ h1 post.title
+ end
end
end
- end
-== Installation
+##Installation
Interested yet? Luckily it's quite easy to install Camping. We'll be using
a tool called RubyGems, so if you don't have that installed yet, go grab it!
@@ -63,32 +65,32 @@ Even better, install the Camping Omnibus, a full package of recommended libs:
gem install camping-omnibus --source http://gems.judofyr.net
If not, you should be aware of that Camping itself only depends on
-Rack[http://rack.rubyforge.org], and if you're going to use the views you also
-need to install +markaby+, and if you're going to use the database you need
-+activerecord+ as well.
+[Rack](http://rack.rubyforge.org), and if you're going to use the views you also
+need to install **[markaby](http://markaby.github.com/)**, and if you're going to use the database you need
+**activerecord** as well.
gem install markaby
gem install activerecord
-== Learning
+##Learning
-First of all, you should read {the first chapters}[link:book/01_introduction.html]
+First of all, you should read [the first chapters](camping/blob/master/book/01_introduction.md)
of The Camping Book. It should hopefully get you started pretty quick. While
you're doing that, you should be aware of the _reference_ which contains
documentation for all the different parts of Camping.
-{The wiki}[http://wiki.github.com/camping/camping] is the place for all tiny,
+[The wiki](http://wiki.github.com/camping/camping) is the place for all tiny,
useful tricks that we've collected over the years. Don't be afraid to share
your own discoveries; the more, the better!
And if there's anything you're wondering about, don't be shy, but rather
-subscribe to {the mailing list}[http://rubyforge.org/mailman/listinfo/camping-list]
+subscribe to [the mailing list](http://rubyforge.org/mailman/listinfo/camping-list)
and ask there. We also have an IRC channel over at Freenode, so if you feel
-like chatting with us, you should join {#camping @ irc.freenode.net}[http://java.freenode.net/?channel=camping].
+like chatting with us, you should join [#camping @ irc.freenode.net](http://java.freenode.net/?channel=camping).
-== Authors
+##Authors
-Camping was originally crafted by {why the lucky stiff}[http://en.wikipedia.org/wiki/Why_the_lucky_stiff],
+Camping was originally crafted by [why the lucky stiff](http://en.wikipedia.org/wiki/Why_the_lucky_stiff),
but is now maintained by the _community_. This simply means that if we like your
-patch, it will be applied. Everything is managed through {the mailing list}[http://rubyforge.org/mailman/listinfo/camping-list],
-so just subscribe and you can instantly take a part in shaping Camping.
+patch, it will be applied. Everything is managed through [the mailing list](http://rubyforge.org/mailman/listinfo/camping-list),
+so just subscribe and you can instantly take a part in shaping Camping.
\ No newline at end of file
diff --git a/book/01_introduction b/book/01_introduction.md
similarity index 72%
rename from book/01_introduction
rename to book/01_introduction.md
index 77d97d7..97995e8 100644
--- a/book/01_introduction
+++ b/book/01_introduction.md
@@ -1,4 +1,4 @@
-= Introduction
+#Introduction
Camping is a small web framework, less than 4k, a little white blood cell in
the vein of Rails. This little book will start with a tutorial which takes
@@ -11,9 +11,9 @@ currently a very much work in progress, and we'll be very grateful if you want
to help out.)
If you at any moment need some help or have any questions or comments, we
-highly recommend {the mailing list}[http://rubyforge.org/mailman/listinfo/camping-list]
+highly recommend [the mailing list](http://rubyforge.org/mailman/listinfo/camping-list)
which got plenty of nice people willing to help. We also have an IRC-channel
-at {#camping @ irc.freenode.net}[http://java.freenode.net/?channel=camping]
+at [#camping @ irc.freenode.net](http://java.freenode.net/?channel=camping)
if you're into that sort of things.
-Enough talk. Ready? Let's {"get started"}[link:book/02_getting_started.html].
+Enough talk. Ready? Let's ["get started"](02_getting_started.md).
diff --git a/book/02_getting_started b/book/02_getting_started.md
similarity index 58%
rename from book/02_getting_started
rename to book/02_getting_started.md
index 199c3c4..6c6770a 100644
--- a/book/02_getting_started
+++ b/book/02_getting_started.md
@@ -1,31 +1,31 @@
-= Getting Started
+#Getting Started
Start a new text file called nuts.rb. Here's what you put inside:
- Camping.goes :Nuts
+ Camping.goes :Nuts
Save it. Then, open a command prompt in the same directory. You'll want to
run:
- $ camping nuts.rb
+ $ camping nuts.rb
And you should get a message which reads:
- ** Camping running on 0.0.0.0:3301.
+ ** Camping running on 0.0.0.0:3301.
This means that right now The Camping Server is running on port 3301 on your
machine. Open your browser and visit http://localhost:3301/.
Your browser window should show:
- Camping Problem!
+ Camping Problem!
- / Not found
+ / Not found
No problem with that. The Camping Server is running, but it doesn't know what
to show. Let's tell him.
-== Hello clock
+##Hello clock
So, you've got Camping installed and it's running. Keep it running. You can
edit files and The Camping Server will reload automatically. When you need to
@@ -33,53 +33,53 @@ stop the server, press Control-C.
Let's show something. At the bottom of nuts.rb add:
- module Nuts::Controllers
- class Index < R '/'
- def get
- Time.now.to_s
+ module Nuts::Controllers
+ class Index < R '/'
+ def get
+ Time.now.to_s
+ end
end
end
- end
Save the file and refresh the browser window. Your browser window should show
the time, e.g.
- Sun Jul 15 12:56:15 +0200 2007
+ Sun Jul 15 12:56:15 +0200 2007
-== Enjoying the view
+##Enjoying the view
The Camping microframework allows us to separate our code using the MVC
(Model-View-Controller) design pattern. Let's add a view to our Nuts
application. Replace the <tt>module Nuts::Controllers</tt> with:
- module Nuts::Controllers
- class Index < R '/'
- def get
- @time = Time.now
- render :sundial
+ module Nuts::Controllers
+ class Index < R '/'
+ def get
+ @time = Time.now
+ render :sundial
+ end
end
end
- end
- module Nuts::Views
- def layout
- html do
- head do
- title { "Nuts And GORP" }
+ module Nuts::Views
+ def layout
+ html do
+ head do
+ title { "Nuts And GORP" }
+ end
+ body { self << yield }
end
- body { self << yield }
end
- end
- def sundial
- p "The current time is: #{@time}"
+ def sundial
+ p "The current time is: #{@time}"
+ end
end
- end
Save the file and refresh your browser window and it should show a message
like:
- The current time is: Sun Jul 15 13:05:41 +0200 2007
+ The current time is: Sun Jul 15 13:05:41 +0200 2007
And the window title reads "Nuts And GORP".
@@ -94,7 +94,7 @@ Soon enough, you'll find that you can return anything from the controller, and
it will be sent to the browser. But let's keep that for later and start
investigating the routes.
-== Routes
+##Routes
You probably noticed the weird <tt>R '/'</tt> syntax in the previous page.
This is an uncommon feature of Ruby that is used in our favorite
@@ -104,89 +104,89 @@ on.
These routes can be very powerful, but we're going to have look at the
simplest ones first.
- module Nuts::Controllers
- class Words < R '/welcome/to/my/site'
- def get
- "You got here by: /welcome/to/my/site"
+ module Nuts::Controllers
+ class Words < R '/welcome/to/my/site'
+ def get
+ "You got here by: /welcome/to/my/site"
+ end
end
- end
- class Digits < R '/nuts/(\d+)'
- def get(number)
- "You got here by: /nuts/#{number}"
+ class Digits < R '/nuts/(\d+)'
+ def get(number)
+ "You got here by: /nuts/#{number}"
+ end
end
- end
- class Segment < R '/gorp/([^/]+)'
- def get(everything_else_than_a_slash)
- "You got here by: /gorp/#{everything_else_than_a_slash}"
+ class Segment < R '/gorp/([^/]+)'
+ def get(everything_else_than_a_slash)
+ "You got here by: /gorp/#{everything_else_than_a_slash}"
+ end
end
- end
- class DigitsAndEverything < R '/nuts/(\d+)/([^/]+)'
- def get(number, everything)
- "You got here by: /nuts/#{number}/#{everything}"
+ class DigitsAndEverything < R '/nuts/(\d+)/([^/]+)'
+ def get(number, everything)
+ "You got here by: /nuts/#{number}/#{everything}"
+ end
end
end
- end
-Add this to nuts.rb and try if you can hit all of the controllers.
+Add this to `nuts.rb` and try if you can hit all of the controllers.
Also notice how everything inside a parenthesis gets passed into the method,
and is ready at your disposal.
-=== Simpler routes
+###Simpler routes
This just in:
- module Nuts::Controllers
- class Index
- def get
- "You got here by: /"
+ module Nuts::Controllers
+ class Index
+ def get
+ "You got here by: /"
+ end
end
- end
- class WelcomeToMySite
- def get
- "You got here by: /welcome/to/my/site"
+ class WelcomeToMySite
+ def get
+ "You got here by: /welcome/to/my/site"
+ end
end
- end
-
- class NutsN
- def get(number)
- "You got here by: /nuts/#{number}"
+
+ class NutsN
+ def get(number)
+ "You got here by: /nuts/#{number}"
+ end
end
- end
- class GorpX
- def get(everything_else_than_a_slash)
- "You got here by: /gorp/#{everything_else_than_a_slash}"
+ class GorpX
+ def get(everything_else_than_a_slash)
+ "You got here by: /gorp/#{everything_else_than_a_slash}"
+ end
end
- end
- class NutsNX
- def get(number, everything)
- "You got here by: /nuts/#{number}/#{everything}"
+ class NutsNX
+ def get(number, everything)
+ "You got here by: /nuts/#{number}/#{everything}"
+ end
end
end
- end
Drop the <tt>< R</tt>-part and it attemps to read your mind. It won't always
succeed, but it can simplify your application once in a while.
-== Modeling the world
+## Modeling the world
You can get pretty far with what you've learned now, and hopefully you've been
playing a bit off-book, but it's time to take the next step: Storing data.
Let's start over again.
- Camping.goes :Nuts
+ Camping.goes :Nuts
- module Nuts::Models
- class Page < Base
+ module Nuts::Models
+ class Page < Base
+ end
end
- end
Obviously, this won't do anything, since we don't have any controllers, but
let's rather have a look at we _do_ have.
@@ -198,27 +198,27 @@ to do it.
However, our model is missing something essential: a skeleton.
- Camping.goes :Nuts
+ Camping.goes :Nuts
- module Nuts::Models
- class Page < Base
- end
+ module Nuts::Models
+ class Page < Base
+ end
- class BasicFields < V 1.0
- def self.up
- create_table Page.table_name do |t|
- t.string :title
- t.text :content
- # This gives us created_at and updated_at
- t.timestamps
+ class BasicFields < V 1.0
+ def self.up
+ create_table Page.table_name do |t|
+ t.string :title
+ t.text :content
+ # This gives us created_at and updated_at
+ t.timestamps
+ end
end
- end
- def self.down
- drop_table Page.table_name
+ def self.down
+ drop_table Page.table_name
+ end
end
end
- end
Now we have our first version of our model. It says:
@@ -237,23 +237,23 @@ This is called a _migration_. Whenever you want to change or add new models you
Now we just need to tell Camping to use our migration. Write this at the bottom of nuts.rb
- def Nuts.create
- Nuts::Models.create_schema
- end
+ def Nuts.create
+ Nuts::Models.create_schema
+ end
When The Camping Server boots up, it will automatically call
<tt>Nuts.create</tt>. You can put all kind of startup-code here, but right now
we only want to create our skeleton (or upgrade if needed). Start The Camping
Server again and observe:
- $ camping nuts.rb
- ** Starting Mongrel on 0.0.0.0:3301
- -- create_table("nuts_schema_infos")
- -> 0.1035s
- == Nuts::Models::BasicFields: migrating ===================================
- -- create_table(:nuts_pages)
- -> 0.0033s
- == Nuts::Models::BasicFields: migrated (0.0038s) ==========================
+ $ camping nuts.rb
+ ** Starting Mongrel on 0.0.0.0:3301
+ -- create_table("nuts_schema_infos")
+ -> 0.1035s
+ == Nuts::Models::BasicFields: migrating ===================================
+ -- create_table(:nuts_pages)
+ -> 0.0033s
+ == Nuts::Models::BasicFields: migrated (0.0038s) ==========================
Restart it, and enjoy the silence. There's no point of re-creating the
skeleton this time.
@@ -261,87 +261,87 @@ skeleton this time.
Before we go on, there's one rule you must known: Always place your models
before your migrations.
-== Using our model
+## Using our model
Let's explore how our model works by going into the _console_
- $ camping -C nuts.rb
- ** Starting console
- >>
+ $ camping -C nuts.rb
+ ** Starting console
+ >>
Now it's waiting for your input, and will give you the answer when you press
Enter. Here's what I did, leaving out the boring answers. You should add your
own pages.
- >> Page = Nuts::Models::Page
-
- >> hiking = Page.new(:title => "Hiking")
- >> hiking.content = "You can also set the values like this."
- >> hiking.save
-
- >> page = Page.find_by_title("Hiking")
- => #<Nuts::Models::Page id: 1, ... >
- >> page = Page.find(1)
- => #<Nuts::Models::Page id: 1, ... >
- >> page.title
- >> page.content
- >> page.created_at
- >> page.updated_at
-
- >> Page.find_by_title("Fishing")
- => nil
-
- ## Page.create automatically saves the page for you.
- >> Page.create(:title => "Fishing", :content => "Go fish!")
-
- >> Page.count
- => 2
+ >> Page = Nuts::Models::Page
+
+ >> hiking = Page.new(:title => "Hiking")
+ >> hiking.content = "You can also set the values like this."
+ >> hiking.save
+
+ >> page = Page.find_by_title("Hiking")
+ => #<Nuts::Models::Page id: 1, ... >
+ >> page = Page.find(1)
+ => #<Nuts::Models::Page id: 1, ... >
+ >> page.title
+ >> page.content
+ >> page.created_at
+ >> page.updated_at
+
+ >> Page.find_by_title("Fishing")
+ => nil
+
+ ## Page.create automatically saves the page for you.
+ >> Page.create(:title => "Fishing", :content => "Go fish!")
+
+ >> Page.count
+ => 2
Now I have two pages: One about hiking and one about fishing.
-== Wrapping it up
+##Wrapping it up
Wouldn't it be nice if we could show this wonderful our pages in a browser?
Update nuts.rb so it also contains something like this:
- module Nuts::Controllers
- class Pages
- def get
- # Only fetch the titles of the pages.
- @pages = Page.all(:select => "title")
- render :list
+ module Nuts::Controllers
+ class Pages
+ def get
+ # Only fetch the titles of the pages.
+ @pages = Page.all(:select => "title")
+ render :list
+ end
end
- end
-
- class PageX
- def get(title)
- @page = Page.find_by_title(title)
- render :view
+
+ class PageX
+ def get(title)
+ @page = Page.find_by_title(title)
+ render :view
+ end
end
end
- end
-
- module Nuts::Views
- def list
- h1 "All pages"
- ul do
- @pages.each do |page|
- li do
- a page.title, :href => R(PageX, page.title)
+
+ module Nuts::Views
+ def list
+ h1 "All pages"
+ ul do
+ @pages.each do |page|
+ li do
+ a page.title, :href => R(PageX, page.title)
+ end
end
end
end
- end
- def view
- h1 @page.title
- self << @page.content
+ def view
+ h1 @page.title
+ self << @page.content
+ end
end
- end
Here we meet our first _helper_:
- R(PageX, page.title)
+ R(PageX, page.title)
This is the <em>reversed router</em> and it generates a URL based on a
controller. Camping ships with a few, but very useful, helpers and you can
@@ -355,40 +355,40 @@ There's a lot of improvements you could do here. Let me suggest:
* Add a layout.
* Jazz it up a bit.
-== The last touch
+##The last touch
We have one major flaw in our little application. You can't edit or add new
pages. Let's see if we can fix that:
- module Nuts::Controllers
- class PageX
- def get(title)
- if @page = Page.find_by_title(title)
- render :view
- else
- redirect PageXEdit, title
+ module Nuts::Controllers
+ class PageX
+ def get(title)
+ if @page = Page.find_by_title(title)
+ render :view
+ else
+ redirect PageXEdit, title
+ end
end
- end
-
- def post(title)
- # If it doesn't exist, initialize it:
- @page = Page.find_or_initialize_by_title(title)
- # This is the same as:
- # @page = Page.find_by_title(title) || Page.new(:title => title)
- @page.content = @input.content
- @page.save
- redirect PageX, title
+ def post(title)
+ # If it doesn't exist, initialize it:
+ @page = Page.find_or_initialize_by_title(title)
+ # This is the same as:
+ # @page = Page.find_by_title(title) || Page.new(:title => title)
+
+ @page.content = @input.content
+ @page.save
+ redirect PageX, title
+ end
end
- end
-
- class PageXEdit
- def get(title)
- @page = Page.find_or_initialize_by_title(title)
- render :edit
+
+ class PageXEdit
+ def get(title)
+ @page = Page.find_or_initialize_by_title(title)
+ render :edit
+ end
end
end
- end
The core of this code lies in the new <tt>post</tt> method in the PageX
controller. When someone types an address or follows a link, they'll end up at
@@ -406,22 +406,22 @@ forms and those in the URL (<tt>/posts?page=50</tt>).
Here's an <tt>edit</tt>-view, but you can probably do better. See if you can
integrate all of this with what you already have.
- module Nuts::Views
- def edit
- h1 @page.title
- form :action => R(PageX, @page.title), :method => :post do
- textarea @page.content, :name => :content,
- :rows => 10, :cols => 50
-
- br
-
- input :type => :submit, :value => "Submit!"
+ module Nuts::Views
+ def edit
+ h1 @page.title
+ form :action => R(PageX, @page.title), :method => :post do
+ textarea @page.content, :name => :content,
+ :rows => 10, :cols => 50
+
+ br
+
+ input :type => :submit, :value => "Submit!"
+ end
end
end
- end
-== Phew.
+##Phew.
You've taken quite a few steps in the last minutes. You deserve a break. But
let's recap for a moment:
diff --git a/book/51_upgrading b/book/51_upgrading.md
similarity index 57%
rename from book/51_upgrading
rename to book/51_upgrading.md
index 1241489..a372172 100644
--- a/book/51_upgrading
+++ b/book/51_upgrading.md
@@ -1,36 +1,36 @@
-= Appendix I: Upgrade Notes
+# Appendix I: Upgrade Notes
This document includes everything needed in order to *upgrade* your
applications. If you're looking for all the new features in a version, please
have a look at the CHANGELOG in the Camping source.
-== From 2.0 to 2.1
-=== Options
+##From 2.0 to 2.1
+###Options
In Camping 2.1 there is now a built-in way to store options and settings. If
you use cookie session, it means that you'll now have to change to:
- module Nuts
- set :secret, "Very secret text, which no-one else should know!"
- include Camping::Session
- end
+ module Nuts
+ set :secret, "Very secret text, which no-one else should know!"
+ include Camping::Session
+ end
-== From 1.5 to 2.0
-=== Rack
+##From 1.5 to 2.0
+###Rack
-The biggest change in 2.0 is that it now uses Rack[http://rack.rubyforge.org/]
+The biggest change in 2.0 is that it now uses [Rack](http://rack.rubyforge.org/)
internally. This means that you'll now have to deploy Camping differently, but
hopefully more easily too. Now every Camping application is also a Rack
application, so simply check out the documentation to the server of your
choice.
-=== require 'camping/db'
+###`require 'camping/db'`
In earlier versions of Camping, you loaded database support by:
- require 'camping/db'
+ require 'camping/db'
Actually, this loaded a very thin layer on top of ActiveRecord, and in the
future we want to experiment with other libraries. Therefore you should now
@@ -40,48 +40,48 @@ also means you'll have to place your migrations *after* the models.
We also encourage you to use <tt>Model.table_name</tt> instead of
<tt>:appname_model</tt>, just to make sure it's named correctly.
- ## Don't require anything:
- # require 'camping/db'
-
- module Nuts::Models
- ## Just inherit Base:
- class Page < Base; end
+ ## Don't require anything:
+ # require 'camping/db'
- ## Migrations have to come *after* the models:
- class CreateTheBasics < V 0.1
- def self.up
- create_table Page.table_name do |t|
- ...
- end
- end
+ module Nuts::Models
+ ## Just inherit Base:
+ class Page < Base; end
- def self.down
- drop_table Page.table_name
+ ## Migrations have to come *after* the models:
+ class CreateTheBasics < V 0.1
+ def self.up
+ create_table Page.table_name do |t|
+ ...
+ end
+ end
+
+ def self.down
+ drop_table Page.table_name
+ end
end
end
- end
-=== Cookie Sessions
+###Cookie Sessions
Camping 2.0 now uses a cookie-based session system, which means you now longer
need a database in order to use sessions. The disadvantage of this is that
you are restricted to only around 4k of data. See below for the changes
required, and see Camping::Session more details.
- module Nuts
- ## Include Camping::Session as before:
- include Camping::Session
-
- ## But also define a secret:
- secret "Very secret text, which no-one else should know!"
- end
-
- def Nuts.create
- ## And remove the following line:
- # Camping::Models::Session.create_schema
- end
+ module Nuts
+ ## Include Camping::Session as before:
+ include Camping::Session
+
+ ## But also define a secret:
+ secret "Very secret text, which no-one else should know!"
+ end
+
+ def Nuts.create
+ ## And remove the following line:
+ # Camping::Models::Session.create_schema
+ end
-=== Error handling
+###Error handling
Camping now uses three methods in order to handle errors. These replaces the
old classes NotFound and ServerError.
@@ -93,18 +93,18 @@ old classes NotFound and ServerError.
You can override these in your application:
- module Nuts
- def r404(path)
- "Sorry, but I can't find #{path}."
- end
-
- def r501(method)
- "Sorry, but I can't respond to #{method}."
- end
-
- def r500(klass, method, ex)
- "Sorry, but #{klass}##{method} failed with #{ex}."
+ module Nuts
+ def r404(path)
+ "Sorry, but I can't find #{path}."
+ end
+
+ def r501(method)
+ "Sorry, but I can't respond to #{method}."
+ end
+
+ def r500(klass, method, ex)
+ "Sorry, but #{klass}##{method} failed with #{ex}."
+ end
end
- end
It should be noted that this might change in the future.
diff --git a/lib/camping-unabridged.rb b/lib/camping-unabridged.rb
index a9c053a..880f36e 100644
--- a/lib/camping-unabridged.rb
+++ b/lib/camping-unabridged.rb
@@ -50,6 +50,7 @@ module Camping
U = Rack::Utils
O = {}
Apps = []
+ SK = :camping #Key for r.session
# An object-like Hash.
# All Camping query string and cookie variables are loaded as this.
#
@@ -201,7 +202,7 @@ module Camping
def R(c,*g)
p,h=/\(.+?\)/,g.grep(Hash)
g-=h
- raise "bad route" unless u = c.urls.find{|x|
+ raise "bad route" if !u = c.urls.find{|x|
break x if x.scan(p).size == g.size &&
/^#{x}\/?$/ =~ (x=g.inject(x){|x,a|
x.sub p,U.escape((a.to_param rescue a))}.gsub(/\\(.)/){$1})
@@ -389,8 +390,9 @@ module Camping
end
# Serves the string +c+ with the MIME type of the filename +p+.
+ # Default text/html
def serve(p, c)
- t = Rack::Mime.mime_type(p[/\..*$/], nil) and @headers['Content-Type'] = t
+ t = Rack::Mime.mime_type(p[/\..*$/], "text/html") and @headers['Content-Type'] = t
c
end
@@ -406,7 +408,7 @@ module Camping
# end
# end
def to_a
- @env['rack.session'] = Hash[@state]
+ @env['rack.session'][SK] = Hash[@state]
r = Rack::Response.new(@body, @status, @headers)
@cookies._n.each do |k, v|
r.set_cookie(k, v)
@@ -419,8 +421,8 @@ module Camping
@root, @input, @cookies, @state,
@headers, @status, @method =
r.script_name.sub(/\/$/,''), n(r.params),
- Cookies[r.cookies], H[r.session.to_hash],
- {}, m =~ /r(\d+)/ ? $1.to_i : 200, m
+ Cookies[r.cookies], H[r.session[SK]||{}],
+ {'Content-Type'=>'text/html'}, m =~ /r(\d+)/ ? $1.to_i : 200, m
@cookies._p = self/"/"
end
@@ -615,11 +617,26 @@ module Camping
#
# module Nuts::Controllers; ... end
# module Nuts::Models; ... end
- # module Nuts::Views; ... 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, for example to namespace 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.
- def goes(m)
- Apps << a = eval(S.gsub(/Camping/,m.to_s), TOPLEVEL_BINDING)
+ def goes(m, g=TOPLEVEL_BINDING)
+ Apps << a = eval(S.gsub(/Camping/,m.to_s), g)
caller[0]=~/:/
IO.read(a.set:__FILE__,$`)=~/^__END__/ &&
(b=$'.split(/^@@\s*(.+?)\s*\r?\n/m)).shift rescue nil
diff --git a/lib/camping.rb b/lib/camping.rb
index 9eac063..7a9ba2c 100644
--- a/lib/camping.rb
+++ b/lib/camping.rb
@@ -1,7 +1,7 @@
require "uri";require "rack";class Object;def meta_def m,&b;(class<<self;self
end).send:define_method,m,&b end end;module Camping;C=self;S=IO.read(__FILE__
-)rescue nil;P="<h1>Cam\ping Problem!</h1><h2>%s</h2>";U=Rack::Utils;O={};Apps=[]
-class H<Hash;def method_missing m,*a;m.to_s=~/=$/?self[$`]=a[0]:a==[]?self[m.
+)rescue nil;P="<h1>Cam\ping Problem!</h1><h2>%s</h2>";U=Rack::Utils;O={};Apps=[];
+SK=:camping;class H<Hash;def method_missing m,*a;m.to_s=~/=$/?self[$`]=a[0]:a==[]?self[m.
to_s]:super end;undef id,type if ??==63 end;class Cookies<H;attr_accessor :_p;
def _n;@n||={}end;alias :_s :[]=;def set k,v,o={};_s(j=k.to_s,v);_n[j]=
{:value=>v,:path=>_p}.update o;end;def []=(k,v)set(k,v,v.is_a?(Hash)?v:{})end
@@ -23,12 +23,12 @@ end;end;def mab &b;extend(Mab);mab(&b) end;def r s,b,h={};b,h=
h,b if Hash===b;@status=s;@headers.merge!(h);@body=b end;def redirect *a;r 302,
'','Location'=>URL(*a).to_s end;def r404 p;P%"#{p} not found"end;def r500 k,m,e
raise e end;def r501 m;P%"#{m.upcase} not implemented"end;def serve(p,c)
-(t=Rack::Mime.mime_type p[/\..*$/],nil)&&@headers["Content-Type"]=t;c;end;def to_a;@env[
-'rack.session']=Hash[@state];r=Rack::Response.new(@body, at status, at headers)
+(t=Rack::Mime.mime_type p[/\..*$/],"text/html")&&@headers["Content-Type"]=t;c;end;def to_a;@env[
+'rack.session'][SK]=Hash[@state];r=Rack::Response.new(@body, at status, at headers)
@cookies._n.each{|k,v|r.set_cookie k,v};r.to_a end;def initialize env,m
r=@request=Rack:: Request.new(@env=env);@root, at input, at cookies, at state, at headers,
@status, at method=r.script_name.sub(/\/$/,''),n(r.params),Cookies[r.cookies],
-H[r.session.to_hash],{},m=~/r(\d+)/?$1.to_i: 200,m;@cookies._p=self/"/" end
+H[r.session[SK]||{}],{'Content-Type'=>'text/html'},m=~/r(\d+)/?$1.to_i: 200,m;@cookies._p=self/"/" end
def n h;Hash===h ?h.inject(H[]){|m,(k,v)|m[k]=
n(v);m}: h end;def service *a;r=catch(:halt){send(@method,*a)};@body||=r;self
end end;module Controllers;@r=[];class<<self;def R *u;r=@r;Class.
@@ -41,7 +41,7 @@ map{|c|k=const_get(c);k.send:include,C,X,Base,Helpers,Models
@r=[k]+ at r if @r-[k]==@r;k.meta_def(:urls){["/#{c.to_s.scan(/.[^A-Z]*/).map(&
N.method(:[]))*'/'}"]}if !k.respond_to?:urls}end end;I=R()end;X=
Controllers;class<<self;def
-goes m;Apps<<a=eval(S.gsub(/Camping/,m.to_s),TOPLEVEL_BINDING);caller[0]=~/:/
+goes m,g=TOPLEVEL_BINDING;Apps<<a=eval(S.gsub(/Camping/,m.to_s),g);caller[0]=~/:/
IO.read(a.set:__FILE__,$`)=~/^__END__/&&(b=$'.split /^@@\s*(.+?)\s*\r?\n/m).shift rescue nil
a.set :_t,H[*b||[]];end;def call e;X.M
k,m,*a=X.D e["PATH_INFO"],e['REQUEST_METHOD'].
diff --git a/lib/camping/mab.rb b/lib/camping/mab.rb
index 6091451..e832c8e 100644
--- a/lib/camping/mab.rb
+++ b/lib/camping/mab.rb
@@ -6,15 +6,28 @@ rescue LoadError => e
raise MissingLibrary, "Mab could not be loaded (is it installed?): #{e.message}"
end
-$MAB_CODE = %{
+$MAB_CODE = %q{
module Mab
include ::Mab::Mixin::HTML5
include Views
alias << text!
+ def xhtml(*a, &b)
+ warn "xhtml_strict is no longer supported (or an active standard); using HTML5 instead"
+ html(*a, &b)
+ end
+
+ def xhtml_strict(*a, &b) xhtml(*a, &b) end
+ def xhtml_transitional(*a, &b) xhtml(*a, &b) end
+ def xhtml_frameset(*a, &b) xhtml(*a, &b) end
+
+ def helpers() self end
+
+ def html(*) doctype!; super end
+
def mab_done(tag)
- h=tag.attributes
+ h=tag._attributes
[:href,:action,:src].map{|a|h[a]&&=self/h[a]}
end
end
diff --git a/lib/camping/server.rb b/lib/camping/server.rb
index 47bffa7..677938b 100644
--- a/lib/camping/server.rb
+++ b/lib/camping/server.rb
@@ -44,7 +44,7 @@ module Camping
options = {}
opt_parser = OptionParser.new("", 24, ' ') do |opts|
- opts.banner = "Usage: camping app1.rb app2.rb..."
+ opts.banner = "Usage: camping my-camping-app.rb"
opts.define_head "#{File.basename($0)}, the microframework ON-button for ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
opts.separator ""
opts.separator "Specific options:"
@@ -149,7 +149,7 @@ module Camping
end
def app
- Rack::Cascade.new([Rack::File.new(public_dir), self], [404, 403])
+ Rack::Cascade.new([Rack::File.new(public_dir), self], [405, 404, 403])
end
def current_app
diff --git a/metadata.yml b/metadata.yml
index 11953b9..3d74d9c 100644
--- a/metadata.yml
+++ b/metadata.yml
@@ -1,7 +1,7 @@
--- !ruby/object:Gem::Specification
name: camping
version: !ruby/object:Gem::Version
- version: 2.1.498
+ version: 2.1.532
prerelease:
platform: ruby
authors:
@@ -9,11 +9,11 @@ authors:
autorequire:
bindir: bin
cert_chain: []
-date: 2012-01-25 00:00:00.000000000 Z
+date: 2013-03-21 00:00:00.000000000 Z
dependencies:
- !ruby/object:Gem::Dependency
name: rack
- requirement: &70136711636780 !ruby/object:Gem::Requirement
+ requirement: !ruby/object:Gem::Requirement
none: false
requirements:
- - ! '>='
@@ -21,21 +21,31 @@ dependencies:
version: '1.0'
type: :runtime
prerelease: false
- version_requirements: *70136711636780
+ version_requirements: !ruby/object:Gem::Requirement
+ none: false
+ requirements:
+ - - ! '>='
+ - !ruby/object:Gem::Version
+ version: '1.0'
- !ruby/object:Gem::Dependency
name: mab
- requirement: &70136711636280 !ruby/object:Gem::Requirement
+ requirement: !ruby/object:Gem::Requirement
none: false
requirements:
- - ! '>='
- !ruby/object:Gem::Version
- version: '0'
+ version: 0.0.3
type: :runtime
prerelease: false
- version_requirements: *70136711636280
+ version_requirements: !ruby/object:Gem::Requirement
+ none: false
+ requirements:
+ - - ! '>='
+ - !ruby/object:Gem::Version
+ version: 0.0.3
- !ruby/object:Gem::Dependency
name: rake
- requirement: &70136711635740 !ruby/object:Gem::Requirement
+ requirement: !ruby/object:Gem::Requirement
none: false
requirements:
- - ! '>='
@@ -43,10 +53,15 @@ dependencies:
version: '0'
type: :development
prerelease: false
- version_requirements: *70136711635740
+ version_requirements: !ruby/object:Gem::Requirement
+ none: false
+ requirements:
+ - - ! '>='
+ - !ruby/object:Gem::Version
+ version: '0'
- !ruby/object:Gem::Dependency
name: rack-test
- requirement: &70136711635140 !ruby/object:Gem::Requirement
+ requirement: !ruby/object:Gem::Requirement
none: false
requirements:
- - ! '>='
@@ -54,22 +69,27 @@ dependencies:
version: '0'
type: :development
prerelease: false
- version_requirements: *70136711635140
+ version_requirements: !ruby/object:Gem::Requirement
+ none: false
+ requirements:
+ - - ! '>='
+ - !ruby/object:Gem::Version
+ version: '0'
description:
email: why at ruby-lang.org
executables:
- camping
extensions: []
extra_rdoc_files:
-- README
+- README.md
- CHANGELOG
- COPYING
-- book/01_introduction
-- book/02_getting_started
-- book/51_upgrading
+- book/01_introduction.md
+- book/02_getting_started.md
+- book/51_upgrading.md
files:
- COPYING
-- README
+- README.md
- Rakefile
- bin/camping
- test/app_cookies.rb
@@ -123,9 +143,9 @@ files:
- extras/rdoc/generator/template/flipbook/readme.rhtml
- extras/rdoc/generator/template/flipbook/reference.rhtml
- extras/rdoc/generator/template/flipbook/toc.rhtml
-- book/01_introduction
-- book/02_getting_started
-- book/51_upgrading
+- book/01_introduction.md
+- book/02_getting_started.md
+- book/51_upgrading.md
- examples/blog.rb
- CHANGELOG
homepage: http://camping.rubyforge.org/
@@ -156,7 +176,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
version: '0'
requirements: []
rubyforge_project: camping
-rubygems_version: 1.8.10
+rubygems_version: 1.8.25
signing_key:
specification_version: 3
summary: minature rails for stay-at-home moms
diff --git a/test/app_markup.rb b/test/app_markup.rb
index 69c4f45..7fdb529 100644
--- a/test/app_markup.rb
+++ b/test/app_markup.rb
@@ -23,6 +23,24 @@ module Markup::Controllers
end
end
end
+
+ class Compat < R '/compat/(.*?)'
+ def get(type)
+ mab do
+ send(type) do
+ body { h1 'Nice' }
+ end
+ end
+ end
+ end
+
+ class CompatHelpers
+ def get
+ mab do
+ helpers.R CompatHelpers
+ end
+ end
+ end
end
module Markup::Views
@@ -63,4 +81,25 @@ class Markup::Test < TestCase
get '/auto/prepend', {}, 'SCRIPT_NAME' => '/mount'
assert_body '<img src="/mount/hello.png">'
end
+
+ def test_compat
+ warning = "xhtml_strict is no longer supported (or an active standard); using HTML5 instead\n"
+
+ assert_output '', warning * 3 do
+ get '/compat/xhtml_strict'
+ assert_body '<!DOCTYPE html><html><body><h1>Nice</h1></body></html>'
+
+ get '/compat/xhtml_transitional'
+ assert_body '<!DOCTYPE html><html><body><h1>Nice</h1></body></html>'
+
+ get '/compat/xhtml_frameset'
+ assert_body '<!DOCTYPE html><html><body><h1>Nice</h1></body></html>'
+ end
+ end
+
+ def test_compat_helpers
+ get '/compat/helpers'
+ assert_body '/compat/helpers'
+ end
end
+
diff --git a/test/app_simple.rb b/test/app_simple.rb
index 7272896..fae85c3 100644
--- a/test/app_simple.rb
+++ b/test/app_simple.rb
@@ -59,6 +59,7 @@ class Simple::Test < TestCase
def test_index
get '/'
assert_body "Hello World!"
+ assert_equal "text/html", last_response.headers['Content-Type']
post '/'
assert_body "Hello Post!"
diff --git a/test/test_helper.rb b/test/test_helper.rb
index 19b8df1..8ce8a0e 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -11,10 +11,10 @@ else
require 'camping-unabridged'
end
-require 'test/unit'
+require 'minitest/autorun'
require 'rack/test'
-class TestCase < Test::Unit::TestCase
+class TestCase < MiniTest::Unit::TestCase
include Rack::Test::Methods
def self.inherited(mod)
--
camping.git
More information about the Pkg-ruby-extras-commits
mailing list