camping 2.1.532 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +72 -53
  3. data/Rakefile +25 -20
  4. data/bin/camping +1 -0
  5. data/book/01_introduction.md +6 -6
  6. data/book/02_getting_started.md +348 -267
  7. data/book/03_more_about_controllers.md +124 -0
  8. data/book/04_more_about_views.md +118 -0
  9. data/book/05_more_about_markaby.md +173 -0
  10. data/book/06_more_about_models.md +58 -0
  11. data/book/06_rules_of_thumb.md +143 -0
  12. data/book/07_philosophy.md +23 -0
  13. data/book/08_publishing_an_app.md +118 -0
  14. data/book/09_upgrade_notes.md +96 -0
  15. data/book/10_middleware.md +69 -0
  16. data/book/11_gear.md +50 -0
  17. data/examples/blog.rb +38 -38
  18. data/lib/camping/ar.rb +20 -5
  19. data/lib/camping/commands.rb +388 -0
  20. data/lib/camping/gear/filters.rb +48 -0
  21. data/lib/camping/gear/inspection.rb +32 -0
  22. data/lib/camping/gear/kuddly.rb +178 -0
  23. data/lib/camping/gear/nancy.rb +170 -0
  24. data/lib/camping/loads.rb +15 -0
  25. data/lib/camping/mab.rb +1 -1
  26. data/lib/camping/reloader.rb +22 -17
  27. data/lib/camping/server.rb +145 -70
  28. data/lib/camping/session.rb +8 -5
  29. data/lib/camping/template.rb +1 -2
  30. data/lib/camping/tools.rb +43 -0
  31. data/lib/camping/version.rb +6 -0
  32. data/lib/camping-unabridged.rb +360 -133
  33. data/lib/camping.rb +78 -47
  34. data/lib/campingtrip.md +341 -0
  35. data/test/app_camping_gear.rb +121 -0
  36. data/test/app_camping_tools.rb +1 -0
  37. data/test/app_config.rb +30 -0
  38. data/test/app_cookies.rb +1 -1
  39. data/test/app_file.rb +3 -3
  40. data/test/app_goes_meta.rb +23 -0
  41. data/test/app_inception.rb +39 -0
  42. data/test/app_markup.rb +5 -20
  43. data/test/app_migrations.rb +16 -0
  44. data/test/app_partials.rb +1 -1
  45. data/test/app_prefixed.rb +88 -0
  46. data/test/app_reloader.rb +1 -2
  47. data/test/app_route_generating.rb +69 -2
  48. data/test/app_sessions.rb +24 -2
  49. data/test/app_simple.rb +18 -18
  50. data/test/apps/migrations.rb +82 -82
  51. data/test/apps/misc.rb +1 -1
  52. data/test/gear/gear_nancy.rb +129 -0
  53. data/test/test_helper.rb +69 -12
  54. metadata +152 -92
  55. data/CHANGELOG +0 -145
  56. data/book/51_upgrading.md +0 -110
@@ -0,0 +1,124 @@
1
+ # Controllers
2
+
3
+ What are these _controllers_? This is a good question for a Camping newb. In the [MVC
4
+ paradigm](http://en.wikipedia.org/wiki/Model%E2%80%93View%E2%80%93Controller#Overview)
5
+ a Models could be described as a very weird and hard to understand thing.
6
+
7
+ When you look in the browser's navigation bar, you will see something like:
8
+
9
+ `http://localhost:3301/welcome/to/my/site`
10
+
11
+ The Universal Resource Locator (URL) is showing you a "structured" web site
12
+ running inside a server that listening in the `3301` port. The site's internal
13
+ routes are "drawing" the path: Inside the `root_dir/` is the directory `/welcome/`
14
+ and it recursively adds the names of the deeper directories: "to", "my", and "site" (`./to/my/site`).
15
+
16
+ But that is virtual, the site doesn't really have a directory structure like that...
17
+ That would be useless. The site uses a "route drawing system" to get _control_
18
+ of that route; this is what *the controller* does.
19
+
20
+ ## Camping Routes and Controllers
21
+
22
+ In camping, each _capitalized_ word in a camel-cased contoller declaration is like the
23
+ words between each slash in a URL. For example:
24
+
25
+ ```ruby
26
+ WelcomeToMySite
27
+ ```
28
+ will draw the route:
29
+
30
+ ```
31
+ /welcome/to/my/site
32
+ ```
33
+
34
+ Or you could instead use the weird R helper to get more specific control of your routes:
35
+
36
+ ```ruby
37
+ Welcome < R '/welcome/to/my/site'
38
+ ```
39
+
40
+ All of this will be declared inside the Nuts::Controllers module.
41
+
42
+ ## Controller Parameters
43
+
44
+ Controllers can also handle your application's parameters. For example,
45
+ when the client asks for a route like `/post/1`, a static web server would
46
+ look out for the directory named "1" and serve the content in that directory.
47
+ It would need a lot of "number-named" directories to do that simple job.
48
+
49
+ But in our case, the controller draws a dynamic path for every asked post. We just need
50
+ to tell him about the size of the flock.
51
+
52
+ In camping, adding `N` or `X` to a controller's declaration tells it to expect a parameter.
53
+ The `N` suffix, which will match a numbered route, is declared like this:
54
+
55
+ ```ruby
56
+ class PostN
57
+ ```
58
+
59
+ With this controller, adding a number to the simple `/post` route in your browser will trigger this route. For example,
60
+ either of these will work:
61
+
62
+ ```
63
+ /post/1
64
+ /post/99
65
+ ```
66
+
67
+ But this `N` route will not match against a word. For example, a request for `/pots/mypost`
68
+ will return 404 (Not Found). Because the `PostN` declaration will only match _Numeric_ parameters.
69
+
70
+ If you would like to match something other than a number, you should use the `X` suffix:
71
+
72
+ ```ruby
73
+ class PostX
74
+ ```
75
+
76
+ The _X_ tells the controller to match anything, including number and words. For example, it will match:
77
+
78
+ ```
79
+ /post/1
80
+ /post/99
81
+ /post/mypost
82
+ ```
83
+
84
+ But it will NOT match: `/post/mypost/1` (or anything that has "/" in the name). Since slashes signify
85
+ deeper directories, you would need to tell the controller to recognize the deeper directory before using a parameter.
86
+ You can do this using camel case, followed by the "X" or "N":
87
+
88
+ ```ruby
89
+ class PostMypostX
90
+ ```
91
+
92
+ ## Getting parameters from the controller
93
+
94
+ Ok, we have the controller that match parameters; and now what?
95
+
96
+ Say that you want to show the post number N requested in the controller. You'll need the
97
+ number.
98
+
99
+ ```ruby
100
+ class PostN
101
+ def get number
102
+ p "the parameter was: #{number}"
103
+ end
104
+ end
105
+ ```
106
+
107
+ Please, do not try that at home. It's very dirty to use a _view_ inside the controller (more on that soon).
108
+
109
+ The method `get`, for the `/post/N route`, will take a parameter. That number will by
110
+ inside the "number parameter". From now, if you want to route something to your
111
+ post route, you can write a link 100% pragmatically like this:
112
+
113
+ ```ruby
114
+ @post=rand 1..9
115
+ a "See the post number: #{@post}",:href=>R(PostN,@post)
116
+ ```
117
+
118
+ For that example, we just choose a random post and then displayed a link to its path.
119
+
120
+ > but you told me that I shouldn't write that in the controller...
121
+
122
+ Yep...I said that. These things are called "views" because they will
123
+ be in the user's face. Our client will not see the controllers; they will be hidden from them when they visit our site.
124
+ Our client will only see the [views](04_more_about_views.md).
@@ -0,0 +1,118 @@
1
+ # Views
2
+
3
+ The view is the scene for our show. The user is sitting in his chair
4
+ (the browser) and see on screen actors (the view). Enjoy the show
5
+ without think that behind the scenes there is a whole team. The team
6
+ behind the cameras is our controller but the user don't care about
7
+ that.
8
+
9
+ The user only see their browser and our application is just and HTML document.
10
+
11
+
12
+ ## Camping Views
13
+
14
+ Inside the Nut::Views module, we will write methods. That method shall called
15
+ with the render sentence. The views do not use class.
16
+
17
+ ```ruby
18
+ module Nust::Views
19
+
20
+ def post_number
21
+ p "you asked the post number @postn"
22
+ end
23
+
24
+ end
25
+ ```
26
+
27
+ Well, well, that was a views, but now: How we show it to the user? We will call
28
+ the view from the controller. And we pass to the view all the parameters that we
29
+ want to show.
30
+
31
+ ```ruby
32
+ module Nuts::Controller
33
+ class PostN
34
+ def get number
35
+ @postn=number
36
+ render :post_number
37
+ end
38
+ end
39
+ end
40
+ ```
41
+
42
+ We just declared a controller for the route /post/(number here). When the browser
43
+ ask for the route /post/1 the controller will be trigged and the get
44
+ method defined inside the class, will respond to the "get" request in
45
+ the web server.
46
+
47
+ The first instruction in our controller, will by write the number in the @postn
48
+ variable and then "render"
49
+
50
+ But what is `render`? This sentence is not from ruby, this is a camping's
51
+ sentence and mean: -show now the view named (:symbol). It take a symbol
52
+ as parameter, and the symbol's name, shall be one of these methods
53
+ declared in the views. Now we have only a view named post_number.
54
+
55
+ You could "associate" it MENTALLY as a hash like this:
56
+
57
+ ```ruby
58
+ def my_view => render :my_view
59
+ ```
60
+
61
+ But that will happen in your mind. In camping these will be happening in
62
+ the modules, not in a hash, therefore, their are very associated too.
63
+
64
+ Imagine your applications as a big building. The controller as the
65
+ corridors and the views as the offices. Where are the offices and we do
66
+ in each office?
67
+
68
+ ## Views and Controllers
69
+
70
+ Model View and Controller, are joined but not scrambled. The views use
71
+ R(ControllerName) for call the controllers and "move". The controller
72
+ will use "render" for call the view.
73
+
74
+ -And now... what do you think we have behind the curtains?
75
+
76
+ ```ruby
77
+ module Why::Controllers
78
+ class CircusCourtains
79
+ def get
80
+ require 'endertromb'
81
+ @monkey=Endertromb::Animals::StartMonkey.new :frog=>true,:place=>:hand
82
+ render :behind_curtain
83
+ end
84
+ end
85
+ end
86
+ ```
87
+
88
+ -OMG! It's a monkey with a start in the hand!
89
+
90
+ -yes, ladies and gentleman, we have it just here for you
91
+
92
+ ```ruby
93
+ module Views
94
+ def behind_curtain
95
+ p @monkey
96
+ end
97
+ end
98
+ ```
99
+
100
+ No, we don't have it behind the curtains, but the user believe it. There
101
+ is the view, enjoy the show.
102
+
103
+ ## Template engine
104
+
105
+ We spoke about the views, and HTML, but we are not using html's tags for
106
+ our view...
107
+
108
+ How happening this?
109
+
110
+ The rubyist have not necessary to write HTML code. Exists some options
111
+ named template. That the "p" before the `@monkey` in the view. A template
112
+ engine is a kind of "pseudo-language" for handle HTML code. In some
113
+ template engines you will also write HTML in a more easy way. Their also
114
+ handle ruby data inside HTML. Templates engine are the wheels of the
115
+ views.
116
+
117
+ In camping, you will write views using a template engine named
118
+ [Markaby](05_more_about_markaby.md) and you will write HTML pragmatically.
@@ -0,0 +1,173 @@
1
+ ## Where Markaby's come from
2
+
3
+ A great musician, writer and programmer (and a bit crazy) named
4
+ [_why](http://en.wikipedia.org/wiki/Why_the_lucky_stiff) wrote camping. Before
5
+ banish himself to the dimension from where him come (a place named "the
6
+ keyhole"); hi also wanted, that the developers, should have not write pure HTML
7
+ code. Him dream with a world were the programmer write html in their
8
+ programming language.
9
+
10
+ Rails users are very hard guys. Their eat the soup using a fork and generate
11
+ HTML views in a template engine named Erb. Their use a long set of weird tools
12
+ for generate that Embedded Ruby (erb), their call it "scaffolding". The basic
13
+ idea is: "let me rails write html code for you" Many framework have in the
14
+ README a line that say: "support more populars template engines" but normally
15
+ peoples uses the default in the framework.
16
+
17
+ "Mab" is the template engine used by default in camping. _why Wrote the first
18
+ implementation named Markaby and then, judofyr and Jenna, power-up markaby
19
+ writing a more compact version of it.
20
+
21
+ While you are writing with mab, will see ruby code front you are eyes, but your
22
+ mind, will be seen pure HTML without tags. We will be "metaprograming HTML
23
+ code". In order to show a Header-1 tag, we just call a method named h1 and send
24
+ the content as parameter. It will make the dirty work writing all the tags just
25
+ like this:
26
+
27
+ ```ruby
28
+ h1 'This is a header one'
29
+ ```
30
+
31
+ "Write HTML pragmatically" mean: -write html using not html tags.
32
+ Markaby is a way for write Hyper Text Markup Language (HTML) using Ruby.
33
+ That do not mean "html knowledge unneeded"
34
+
35
+ But that is only the beginning, we can do more wild things.
36
+
37
+ ## Writing HTML pragmatically
38
+
39
+ For example: if we want show a table for show users and their real
40
+ names:
41
+
42
+ ```ruby
43
+ # call me using render :users
44
+ # from a get in the controllers
45
+ def users
46
+ table do
47
+ th 'User'
48
+ th 'Realname'
49
+ @users.each do |user,realname|
50
+ tr do
51
+ td user
52
+ td realname
53
+ end # tr
54
+ end # each
55
+ end # table
56
+ end # def
57
+ ```
58
+
59
+ Take a look better [here](https://github.com/camping/mab/blob/master/README.md)
60
+
61
+ ## Markaby and the layout
62
+
63
+ There is a special view named "layout". The layout, is view that will be
64
+ rendered each time any other view are rendered. In fact, the layout will take
65
+ the other views for compose himself. The layout is rendered before anything.
66
+
67
+ Each time you use the "render" sentence, you will be rendering the
68
+ layout and the desired view. Because that, wee need some "special"
69
+ tweaks in the layout. It must have a door with a poster that say:
70
+ "other view will enter using this door"
71
+
72
+ The layout will be rendered, and in some place you will put the other view.
73
+ This will be done with the "yield" sentence. Put the yield sentence whenever
74
+ you want rendering all the other views.
75
+
76
+ This is very useful, for example: We wan to write a footer in ALL the
77
+ pages that we are rendering. You can write the footer in every views
78
+ definition, or just write the footer in the layout.
79
+
80
+ Without a layout, if you render the table's views. Camping will drop out the
81
+ table just like that to the browser's render. It will not draw any body or head
82
+ tag. Writing body and head in every page could be a very bored task. But do not
83
+ worry, the layout is here.
84
+
85
+ Lets write our layout, with all the HTML shape and including a footer
86
+
87
+ ```ruby
88
+ def layout
89
+
90
+ html do
91
+ head do
92
+ title 'My Blog'
93
+ end
94
+
95
+ body do
96
+
97
+ div.wrapper! do
98
+ self << yield
99
+ end
100
+
101
+ p.footer! do
102
+ text 'Powered by Camping'
103
+ end
104
+ end
105
+ end
106
+
107
+ end # layout
108
+ ```
109
+ Well, that was wild. Let's see: First we have everything inside a block, the
110
+ html's block. At the next level, the first block is head, that is rendering
111
+ something like:
112
+
113
+ ```html
114
+ <html>
115
+ <head>
116
+ <title> My Blog </title>
117
+ </head>
118
+ </html>
119
+ ```
120
+
121
+ If you look at the HTML's source of camping, you will see a VERY LOOOONG
122
+ line with every the HTML code, better do not look it.
123
+
124
+ Then, come the more weird thing. A div with a estrange sentence:
125
+
126
+ ```ruby
127
+ self << yield
128
+ ```
129
+ That mean: -put just right here, the other view called.
130
+
131
+ In that place, in the center of the div.wrapper, will be placed all our
132
+ views called using render's sentence.
133
+
134
+ When you call:
135
+
136
+ ```ruby
137
+ render :someview
138
+ ```
139
+
140
+ Camping will rendering before, the layout view, and put all the content
141
+ of "someview" inside div.wrapper! You shall not write a lot of tag like
142
+ head or title.
143
+
144
+ Finally, it will be rendering a "p" named footer. That will be the footer in
145
+ all our pages.
146
+
147
+ ## Tip
148
+
149
+ What would happen? If you do this in the layout:
150
+
151
+ ```ruby
152
+ head do
153
+ title "#{@title}"
154
+ end
155
+ ```
156
+
157
+ Hummm... You could "rewrite" the titles of each pages. In the
158
+ controller, you just need to declare the variable @title, and that will
159
+ be the title for that page.
160
+
161
+ Remember:
162
+
163
+ * Views take @variables from the controller
164
+ * Layout is rendered before any called view.
165
+ * Markaby is ruby code and it can be embedded
166
+ * View's modules use not `class` declarations
167
+
168
+ In the table example, we used a hash named @users. But. Where come from all
169
+ thats data?
170
+
171
+ It come from the controller, but the controller took it from the
172
+ [model](06_more_about_models.md). The M of the MVC, the layer who stare
173
+ the whole bunch of persistent data.
@@ -0,0 +1,58 @@
1
+ ## More about Models
2
+
3
+ Models are used to persist data. That data could be anything. The balance in a bank account, A list of your favorite restaurants, your blog posts, you name it. Camping uses the *ActiveRecord* Gem, an ORM (object-relational mapper), that maps Database tables to objects.
4
+
5
+ We define models by inheriting from a base model named Base:
6
+
7
+ ```ruby
8
+ class User < Base end
9
+ ```
10
+
11
+ Very creative. Base is really just an alias for ActiveRecord, nothing fancy. We put our models into a namespaced module named after our App:
12
+
13
+ ```ruby
14
+ Camping.goes :Nuts
15
+
16
+ module Nuts::Models
17
+ class User < Base end
18
+ end
19
+ ```
20
+
21
+ Remember from earlier that Models need to be defined before our controllers, otherwise we can't use em. So keep them close to the top.
22
+
23
+ The new User model we've defined has a small problem, it's completely empty, it doesn't have any data that can be stored in it. Camping models map Database tables to objects automatically, but this model doesn't have a database table yet. To fix that we'll create a migration:
24
+
25
+ ```ruby
26
+ Camping.goes :Nuts
27
+
28
+ module Nuts::Models
29
+ class User < Base; end
30
+
31
+ # Define a migration to add users
32
+ class AddUser < V 1.2
33
+ def self.up
34
+ create_table User.table_name do |t|
35
+ t.string :username
36
+ t.string :email
37
+ t.timestamps
38
+ end
39
+ end
40
+
41
+ def self.down
42
+ drop_table User.table_name
43
+ end
44
+ end
45
+ end
46
+ ```
47
+
48
+ Databases, like birds, migrate. Migrations move our database from one configuration to another. In our case we're adding users. So cool. User's should be able to log in, sign up, maybe make some pages. We could make the next myspace. To get our database to make a users table we need force our app to create the schema.
49
+
50
+ ```ruby
51
+ def Nuts.create
52
+ Nuts::Models.create_schema
53
+ end
54
+ ```
55
+
56
+ Now that puppy will migrate when we launch our app.
57
+
58
+ Our Users now have greater hope to survive. So great. I love it.
@@ -0,0 +1,143 @@
1
+ # Keep it in one file
2
+
3
+ Generally, the idea is keep your app small and store in a single file. Your app will end up with four sections:
4
+
5
+ 1. Camping setup
6
+
7
+ ```ruby
8
+ do
9
+ require 'rubygems'
10
+ require 'camping'
11
+ Camping.goes :Blog
12
+ end
13
+ ```
14
+
15
+ 2. Models
16
+
17
+ ```ruby
18
+ do
19
+ module Blog::Models
20
+ class User < Base; end
21
+ class Post < Base; belongs_to :user end
22
+ end
23
+ end
24
+ ```
25
+
26
+ 3. Controllers
27
+
28
+ ```ruby
29
+ do
30
+ module Blog::Controllers
31
+ class Index < R '/'
32
+ def get; render :index end
33
+ end
34
+ end
35
+ end
36
+ ```
37
+
38
+ 4. Views
39
+
40
+ ```ruby
41
+ do
42
+ module Blog::Views
43
+ def layout
44
+ html { body { self << yield } }
45
+ end
46
+ def index
47
+ div.page "Welcome!"
48
+ end
49
+ end
50
+ end
51
+ ```
52
+
53
+ # What if things get out of hand?
54
+
55
+ If you’re piling up models and controllers, your file may begin to exceed 200 lines, which means lots of paging up and down. Go ahead and store your models, controllers and views in three separate files. Your directory structure should end up like this:
56
+
57
+ ```
58
+ blog.rb
59
+ blog/
60
+ models.rb
61
+ controllers.rb
62
+ views.rb
63
+ ```
64
+
65
+ (Note, for the development reloading to work, your required files (models.rb etc.) must be in a subdirectory named after your app.)
66
+
67
+ Your blog.rb would still contain the setup (No. 1):
68
+
69
+ ```ruby
70
+ do
71
+ require 'rubygems'
72
+ require 'camping'
73
+ Camping.goes :Blog
74
+ require 'blog/helpers' # if needed
75
+ require 'blog/models'
76
+ require 'blog/views'
77
+ require 'blog/controllers'
78
+ end
79
+ ```
80
+
81
+ # Small apps, many mounts
82
+
83
+ Rather than building huge Camping apps, the idea here is to write small apps which can each be mounted at directories on your web server. One restriction: these apps will share a database. However, this allows applications to access each other’s tables and simplifies setup and configuration.
84
+
85
+ To mount multiple camping apps, you can `require` the app files. When you mount more than one app they won't be mounted according to their parent directory, routing is explicit. If you'd like to give one of your apps a prefix, set the `url_prefix` option in your app:
86
+
87
+ ```ruby
88
+ # camp.rb
89
+ require 'camping'
90
+ Camping.goes :Blog
91
+ require 'blog.rb'
92
+
93
+ Camping.goes :Wiki
94
+ require 'wiki.rb'
95
+ Wiki.set :url_prefix, 'tepee/'
96
+
97
+ Camping.goes :Charty
98
+ require 'charty.rb'
99
+ Charty.set :url_prefix, 'charts/'
100
+
101
+ ```
102
+
103
+ By default Camping will look for a file called `camp.rb` in the root where Camping is executed. You can also supply a ruby filename to load your apps from there.
104
+
105
+ You’ll end up with:
106
+ ```
107
+ http://localhost:3301/blog, a blogging app.
108
+ http://localhost:3301/tepee, a wiki app.
109
+ http://localhost:3301/charts, a charting app.
110
+ ```
111
+
112
+ In your app, if you’re using the R() method to build your links, Camping will make sure the mount is added properly to links.
113
+
114
+ For example, if R(View, 1) is used in the blogging app mounted at /blog, the link will be written as /blog/view/1. If later you mount the blog at /articles instead, Camping will write the link as /articles/view/1.
115
+
116
+ # Give us a create method
117
+
118
+ ```ruby
119
+ do
120
+ def Blog.create
121
+ # Code in here will run when the app starts, or reloads, but not when requests happen.
122
+ # You can use it to create database bits and pieces, files, folders, and so on.
123
+ end
124
+ end
125
+ ```
126
+
127
+ # The camping server
128
+
129
+ The Camping Server is basically a set of rules. At the very least, The Camping Server must:
130
+
131
+ - Load all Camping apps in a directory.
132
+ - Load new apps that appear in that directory.
133
+ - Mount those apps according to their filename. (e.g. blog.rb is mounted at /blog.)
134
+ - Run each app’s create method upon startup.
135
+ - Reload the app if its modification time changes.
136
+ - Reload the app if it requires any files under the same directory and one of their modification times changes.
137
+ - Support the X-Sendfile header.
138
+
139
+ # Bin/camping
140
+
141
+ Camping comes with a very simple version of The Camping Server. bin/camping uses either WEBrick or Mongrel (if you have it installed.)
142
+
143
+ Run it like this: `camping /var/www/camping/*.` It will follow all of the rules above.
@@ -0,0 +1,23 @@
1
+ # Why's origin story
2
+
3
+ The philosophy of Camping is a long and winding tail of origin, met by the ideals for the future of many mad hackers. The story of camping begins in 2006 on a cool winters night in Pittsburgh, where we find a hacker hunched over his computer, typing ruby code with his right hand and playing a laser theremin with his left. To the spooky sounds of his own left hand, he hacked through the night. This night, camping was born.
4
+
5
+ Lets step back though time for a minute though, to the origins of this man. Once an upstanding PHP developer, he grew weary and tired of his day job, writing endless login pages and checkouts. He dreamt of a world free of his C-flavoured prison. Tales of promised lands, where snake powered ponies run wild, dancing around campfires full of rubies glowing red as blood. They worked him to the bone, until one day his bones just up and left. He couldn't do it any longer! He was on a mission to find that fire which fueled his dreams.
6
+
7
+ In seclusion, there isn't much known about this odd man's life. Some say he went crazy. Others say he became a well respected professor. Still others suggest both of these are true. But what we do know, is that it is here, that he developed his love of chunky bacon, foxes, and children shaped like keyholes.
8
+
9
+ And so he went on, crafting his mad writings, scribblings of foxes explaining ruby symbols, and making strange music. Soon this man found himself concerned that children had no good way to make their own eBay competitors. For this reason, he created Camping.
10
+
11
+ The End.
12
+
13
+ # Actual philosophy
14
+
15
+ Why The Lucky Stiff is no longer around, so those of us who contributed early on to Camping have since become its caretakers. We continue to push the framework foward, to be more compact, to be faster, easier, more fun. These are our guiding principals:
16
+
17
+ - Camping is for everyone. It sure is great to turn an idea in to a single ruby file which creates a website. It's also great to organise an app in to several files sometimes. You can plug bits together all in a row, and grow your evil monkey in to an entire army of evil circus animals!
18
+ - Camping isn't for making money. You can make money using camping. Nobody will stop you. But we don't have any buzzwords to offer, we won't make your unit tests easier, nor help you do market research. Our main contributors certainly aren't using camping in large scale deployments, and while camping is blazingly fast, we have no idea how well it would work if you ran it on lots of servers!
19
+ - Camping is really simple. You don't need to know much, to make nifty things with it, and you can really easily add more detailed bits as needed. Your brain will thank you.
20
+ - Camping apps are easy to automatically reload. Because most of them are just one ruby file.
21
+ - Camping encourages experimentation. The whole thing is an experiment.
22
+ - If you're new to ruby, there are heaps of quirky hacks in here which will teach you all sorts of obscure, nifty, and outright strange things about the Ruby language.
23
+ - Camping doesn't take itself too seriously. We're a fun bunch, living on the edge of zany!