camping 1.5.180 → 2.0.rc0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/CHANGELOG +35 -0
  2. data/README +43 -68
  3. data/Rakefile +155 -86
  4. data/bin/camping +64 -246
  5. data/book/01_introduction +19 -0
  6. data/book/02_getting_started +443 -0
  7. data/book/51_upgrading +93 -0
  8. data/doc/api.html +1953 -0
  9. data/doc/book.html +73 -0
  10. data/doc/book/01_introduction.html +57 -0
  11. data/doc/book/02_getting_started.html +573 -0
  12. data/doc/book/51_upgrading.html +146 -0
  13. data/doc/created.rid +1 -0
  14. data/{extras → doc/images}/Camping.gif +0 -0
  15. data/doc/images/loadingAnimation.gif +0 -0
  16. data/{extras → doc/images}/permalink.gif +0 -0
  17. data/doc/index.html +148 -0
  18. data/doc/js/camping.js +79 -0
  19. data/doc/js/jquery.js +32 -0
  20. data/doc/rdoc.css +117 -0
  21. data/examples/blog.rb +280 -181
  22. data/extras/images/badge.gif +0 -0
  23. data/extras/images/boys-life.png +0 -0
  24. data/extras/images/deerputer.png +0 -0
  25. data/extras/images/diagram.png +0 -0
  26. data/extras/images/hill.png +0 -0
  27. data/extras/images/i-wish.png +0 -0
  28. data/extras/images/latl.png +0 -0
  29. data/extras/images/little-wheels.png +0 -0
  30. data/extras/images/square-badge.png +0 -0
  31. data/extras/images/uniform.png +0 -0
  32. data/extras/images/whale-bounce.png +0 -0
  33. data/extras/rdoc/generator/singledarkfish.rb +205 -0
  34. data/extras/rdoc/generator/template/flipbook/images/Camping.gif +0 -0
  35. data/extras/rdoc/generator/template/flipbook/images/loadingAnimation.gif +0 -0
  36. data/extras/rdoc/generator/template/flipbook/images/permalink.gif +0 -0
  37. data/extras/rdoc/generator/template/flipbook/js/camping.js +79 -0
  38. data/extras/rdoc/generator/template/flipbook/js/jquery.js +32 -0
  39. data/extras/rdoc/generator/template/flipbook/page.rhtml +30 -0
  40. data/extras/rdoc/generator/template/flipbook/rdoc.css +117 -0
  41. data/extras/rdoc/generator/template/flipbook/readme.rhtml +31 -0
  42. data/extras/rdoc/generator/template/flipbook/reference.rhtml +71 -0
  43. data/extras/rdoc/generator/template/flipbook/toc.rhtml +43 -0
  44. data/lib/camping-unabridged.rb +420 -481
  45. data/lib/camping.rb +40 -55
  46. data/lib/camping/{db.rb → ar.rb} +5 -8
  47. data/lib/camping/mab.rb +26 -0
  48. data/lib/camping/reloader.rb +175 -147
  49. data/lib/camping/server.rb +178 -0
  50. data/lib/camping/session.rb +34 -121
  51. data/test/apps/env_debug.rb +65 -0
  52. data/test/apps/forms.rb +95 -0
  53. data/test/apps/forward_to_other_controller.rb +60 -0
  54. data/test/apps/migrations.rb +97 -0
  55. data/test/apps/misc.rb +86 -0
  56. data/test/apps/sessions.rb +38 -0
  57. metadata +120 -80
  58. data/doc/camping.1.gz +0 -0
  59. data/examples/campsh.rb +0 -630
  60. data/examples/tepee.rb +0 -242
  61. data/extras/flipbook_rdoc.rb +0 -491
  62. data/lib/camping/fastcgi.rb +0 -244
  63. data/lib/camping/webrick.rb +0 -65
  64. data/test/test_xhtml_trans.rb +0 -55
data/examples/blog.rb CHANGED
@@ -1,171 +1,178 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $:.unshift File.dirname(__FILE__) + "/../../lib"
3
+ $:.unshift File.dirname(__FILE__) + '/../lib'
4
4
  require 'camping'
5
+ require 'camping/ar'
5
6
  require 'camping/session'
6
-
7
+ require 'redcloth'
8
+
7
9
  Camping.goes :Blog
8
10
 
9
11
  module Blog
10
- include Camping::Session
11
- end
12
+ include Camping::Session
12
13
 
13
- module Blog::Models
14
- class Post < Base; belongs_to :user; end
14
+ module Models
15
+ class Post < Base
16
+ belongs_to :user
17
+
18
+ before_save do |record|
19
+ cloth = RedCloth.new(record.body)
20
+ cloth.hard_breaks = false
21
+ record.html_body = cloth.to_html
22
+ end
23
+ end
24
+
15
25
  class Comment < Base; belongs_to :user; end
16
26
  class User < Base; end
17
27
 
18
- class CreateTheBasics < V 1.0
28
+ class BasicFields < V 1.1
19
29
  def self.up
20
30
  create_table :blog_posts, :force => true do |t|
21
- t.column :id, :integer, :null => false
22
- t.column :user_id, :integer, :null => false
23
- t.column :title, :string, :limit => 255
24
- t.column :body, :text
31
+ t.integer :user_id, :null => false
32
+ t.string :title, :limit => 255
33
+ t.text :body, :html_body
34
+ t.timestamps
25
35
  end
26
36
  create_table :blog_users, :force => true do |t|
27
- t.column :id, :integer, :null => false
28
- t.column :username, :string
29
- t.column :password, :string
37
+ t.string :username, :password
30
38
  end
31
39
  create_table :blog_comments, :force => true do |t|
32
- t.column :id, :integer, :null => false
33
- t.column :post_id, :integer, :null => false
34
- t.column :username, :string
35
- t.column :body, :text
40
+ t.integer :post_id, :null => false
41
+ t.string :username
42
+ t.text :body, :html_body
43
+ t.timestamps
36
44
  end
37
45
  User.create :username => 'admin', :password => 'camping'
38
46
  end
47
+
39
48
  def self.down
40
49
  drop_table :blog_posts
41
50
  drop_table :blog_users
42
51
  drop_table :blog_comments
43
52
  end
44
53
  end
45
- end
54
+ end
46
55
 
47
- module Blog::Controllers
48
- class Index < R '/'
49
- def get
50
- @posts = Post.find :all
51
- render :index
52
- end
53
- end
54
-
55
- class Add
56
- def get
57
- unless @state.user_id.blank?
58
- @user = User.find @state.user_id
59
- @post = Post.new
60
- end
61
- render :add
62
- end
63
- def post
64
- unless @state.user_id.blank?
65
- post = Post.create :title => input.post_title, :body => input.post_body,
66
- :user_id => @state.user_id
67
- redirect View, post
68
- end
69
- end
56
+ module Controllers
57
+ class Index
58
+ def get
59
+ @posts = Post.all(:order => 'updated_at DESC')
60
+ render :index
61
+ end
70
62
  end
71
63
 
72
- class Info < R '/info/(\d+)', '/info/(\w+)/(\d+)', '/info', '/info/(\d+)/(\d+)/(\d+)/([\w-]+)'
73
- def get(*args)
74
- div do
75
- code args.inspect; br; br
76
- code @env.inspect; br
77
- code "Link: #{R(Info, 1, 2)}"
78
- end
79
- end
64
+ class PostNew
65
+ def get
66
+ require_login!
67
+ @post = Post.new
68
+ render :add
69
+ end
70
+
71
+ def post
72
+ require_login!
73
+ post = Post.create(:title => input.post_title, :body => input.post_body,
74
+ :user_id => @state.user_id)
75
+ redirect PostN, post
76
+ end
80
77
  end
81
78
 
82
- class View < R '/view/(\d+)'
83
- def get post_id
84
- @post = Post.find post_id
85
- @comments = Models::Comment.find :all, :conditions => ['post_id = ?', post_id]
86
- render :view
87
- end
88
- end
89
-
90
- class Edit < R '/edit/(\d+)', '/edit'
91
- def get post_id
92
- unless @state.user_id.blank?
93
- @user = User.find @state.user_id
94
- end
95
- @post = Post.find post_id
96
- render :edit
97
- end
98
-
99
- def post
100
- unless @state.user_id.blank?
101
- @post = Post.find input.post_id
102
- @post.update_attributes :title => input.post_title, :body => input.post_body
103
- redirect View, @post
104
- end
105
- end
79
+ class PostN
80
+ def get(post_id)
81
+ @post = Post.find(post_id)
82
+ render :view
83
+ end
106
84
  end
107
-
108
- class Comment
109
- def post
110
- Models::Comment.create(:username => input.post_username,
111
- :body => input.post_body, :post_id => input.post_id)
112
- redirect View, input.post_id
113
- end
85
+
86
+ class Edit < R '/post/(\d+)/edit'
87
+ def get(post_id)
88
+ require_login!
89
+ @post = Post.find(post_id)
90
+ render :edit
91
+ end
92
+
93
+ def post(post_id)
94
+ require_login!
95
+ @post = Post.find(post_id)
96
+ @post.update_attributes :title => input.post_title, :body => input.post_body
97
+ redirect PostN, @post
98
+ end
114
99
  end
115
-
100
+
116
101
  class Login
117
- def post
118
- @user = User.find :first, :conditions => ['username = ? AND password = ?', input.username, input.password]
119
-
120
- if @user
121
- @login = 'login success !'
122
- @state.user_id = @user.id
123
- else
124
- @login = 'wrong user name or password'
125
- end
126
- render :login
102
+ def get
103
+ render :login
104
+ end
105
+
106
+ def post
107
+ @user = User.find_by_username_and_password(input.username, input.password)
108
+
109
+ if @user
110
+ @state.user_id = @user.id
111
+ redirect R(Index)
112
+ else
113
+ @info = 'Wrong username or password.'
127
114
  end
115
+
116
+ render :login
117
+ end
128
118
  end
129
-
119
+
130
120
  class Logout
131
- def get
132
- @state.user_id = nil
133
- render :logout
134
- end
135
- end
136
-
137
- class Style < R '/styles.css'
138
- def get
139
- @headers["Content-Type"] = "text/css; charset=utf-8"
140
- @body = %{
141
- body {
142
- font-family: Utopia, Georga, serif;
143
- }
144
- h1.header {
145
- background-color: #fef;
146
- margin: 0; padding: 10px;
147
- }
148
- div.content {
149
- padding: 10px;
150
- }
151
- }
152
- end
121
+ def get
122
+ @state.user_id = nil
123
+ redirect Index
124
+ end
153
125
  end
154
- end
155
126
 
156
- module Blog::Views
127
+ class Style < R '/styles\.css'
128
+ STYLE = File.read(__FILE__).gsub(/.*__END__/m, '')
129
+
130
+ def get
131
+ @headers['Content-Type'] = 'text/css; charset=utf-8'
132
+ STYLE
133
+ end
134
+ end
135
+ end
136
+
137
+ module Helpers
138
+ def logged_in?
139
+ !!@state.user_id
140
+ end
141
+
142
+ def require_login!
143
+ unless logged_in?
144
+ redirect Controllers::Login
145
+ throw :halt
146
+ end
147
+ end
148
+ end
157
149
 
150
+ module Views
158
151
  def layout
159
152
  html do
160
153
  head do
161
- title 'blog'
154
+ title 'My Blog'
162
155
  link :rel => 'stylesheet', :type => 'text/css',
163
- :href => '/styles.css', :media => 'screen'
156
+ :href => '/styles.css', :media => 'screen'
164
157
  end
165
158
  body do
166
- h1.header { a 'blog', :href => R(Index) }
167
- div.content do
168
- self << yield
159
+ h1 { a 'My Blog', :href => R(Index) }
160
+
161
+ div.wrapper! do
162
+ text yield
163
+ end
164
+
165
+ hr
166
+
167
+ p.footer! do
168
+ if logged_in?
169
+ _admin_menu
170
+ else
171
+ a 'Login', :href => R(Login)
172
+ text ' to the adminpanel'
173
+ end
174
+ text ' &ndash; Powered by '
175
+ a 'Camping', :href => 'http://camping.rubyforge.org/'
169
176
  end
170
177
  end
171
178
  end
@@ -173,99 +180,191 @@ module Blog::Views
173
180
 
174
181
  def index
175
182
  if @posts.empty?
176
- p 'No posts found.'
177
- p { a 'Add', :href => R(Add) }
183
+ h2 'No posts'
184
+ p do
185
+ text 'Could not find any posts. Feel free to '
186
+ a 'add one', :href => R(PostNew)
187
+ text ' yourself. '
188
+ end
178
189
  else
179
- for post in @posts
190
+ @posts.each do |post|
180
191
  _post(post)
181
192
  end
182
193
  end
183
194
  end
184
195
 
185
196
  def login
186
- p { b @login }
187
- p { a 'Continue', :href => R(Add) }
188
- end
197
+ h2 'Login'
198
+ p.info @info if @info
199
+
200
+ form :action => R(Login), :method => 'post' do
201
+ input :name => 'to', :type => 'hidden', :value => @to if @to
202
+
203
+ label 'Username', :for => 'username'
204
+ input :name => 'username', :id => 'username', :type => 'text'
189
205
 
190
- def logout
191
- p "You have been logged out."
192
- p { a 'Continue', :href => R(Index) }
206
+ label 'Password', :for => 'password'
207
+ input :name => 'password', :id => 'password', :type => 'password'
208
+
209
+ input :type => 'submit', :class => 'submit', :value => 'Login'
210
+ end
193
211
  end
194
212
 
195
213
  def add
196
- if @user
197
- _form(@post, :action => R(Add))
198
- else
199
- _login
200
- end
214
+ _form(@post, :action => R(PostNew))
201
215
  end
202
216
 
203
217
  def edit
204
- if @user
205
- _form(@post, :action => R(Edit))
206
- else
207
- _login
208
- end
218
+ _form(@post, :action => R(Edit, @post))
209
219
  end
210
220
 
211
221
  def view
212
- _post(@post)
213
-
214
- p "Comment for this post:"
215
- for c in @comments
216
- h1 c.username
217
- p c.body
218
- end
219
-
220
- form :action => R(Comment), :method => 'post' do
221
- label 'Name', :for => 'post_username'; br
222
- input :name => 'post_username', :type => 'text'; br
223
- label 'Comment', :for => 'post_body'; br
224
- textarea :name => 'post_body' do; end; br
225
- input :type => 'hidden', :name => 'post_id', :value => @post.id
226
- input :type => 'submit'
227
- end
222
+ _post(@post)
228
223
  end
229
224
 
230
225
  # partials
231
- def _login
232
- form :action => R(Login), :method => 'post' do
233
- label 'Username', :for => 'username'; br
234
- input :name => 'username', :type => 'text'; br
235
-
236
- label 'Password', :for => 'password'; br
237
- input :name => 'password', :type => 'text'; br
238
-
239
- input :type => 'submit', :name => 'login', :value => 'Login'
240
- end
226
+ def _admin_menu
227
+ text [['Log out', R(Logout)], ['New', R(PostNew)]].map { |name, to|
228
+ capture { a name, :href => to}
229
+ }.join(' &ndash; ')
241
230
  end
242
231
 
243
232
  def _post(post)
244
- h1 post.title
245
- p post.body
246
- p do
247
- [a("Edit", :href => R(Edit, post)), a("View", :href => R(View, post))].join " | "
233
+ h2 { a post.title, :href => R(PostN, post) }
234
+ p.info do
235
+ text "Written by <strong>#{post.user.username}</strong> "
236
+ text post.updated_at.strftime('%B %M, %Y @ %H:%M ')
237
+ _post_menu(post)
238
+ end
239
+ text post.html_body
240
+ end
241
+
242
+ def _post_menu(post)
243
+ if logged_in?
244
+ a '(edit)', :href => R(Edit, post)
248
245
  end
249
246
  end
250
247
 
251
248
  def _form(post, opts)
252
- p { "You are logged in as #{@user.username} | #{a 'Logout', :href => R(Logout)}" }
253
249
  form({:method => 'post'}.merge(opts)) do
254
- label 'Title', :for => 'post_title'; br
255
- input :name => 'post_title', :type => 'text',
256
- :value => post.title; br
250
+ label 'Title', :for => 'post_title'
251
+ input :name => 'post_title', :id => 'post_title', :type => 'text',
252
+ :value => post.title
257
253
 
258
- label 'Body', :for => 'post_body'; br
259
- textarea post.body, :name => 'post_body'; br
254
+ label 'Body', :for => 'post_body'
255
+ textarea post.body, :name => 'post_body', :id => 'post_body'
260
256
 
261
257
  input :type => 'hidden', :name => 'post_id', :value => post.id
262
- input :type => 'submit'
258
+ input :type => 'submit', :class => 'submit', :value => 'Submit'
263
259
  end
264
260
  end
261
+ end
265
262
  end
266
-
263
+
267
264
  def Blog.create
268
- Camping::Models::Session.create_schema
269
- Blog::Models.create_schema :assume => (Blog::Models::Post.table_exists? ? 1.0 : 0.0)
265
+ Blog::Models.create_schema :assume => (Blog::Models::Post.table_exists? ? 1.0 : 0.0)
270
266
  end
271
267
 
268
+ __END__
269
+ * {
270
+ margin: 0;
271
+ padding: 0;
272
+ }
273
+
274
+ body {
275
+ font: normal 14px Arial, 'Bitstream Vera Sans', Helvetica, sans-serif;
276
+ line-height: 1.5;
277
+ }
278
+
279
+ h1, h2, h3, h4 {
280
+ font-family: Georgia, serif;
281
+ font-weight: normal;
282
+ }
283
+
284
+ h1 {
285
+ background-color: #EEE;
286
+ border-bottom: 5px solid #6F812D;
287
+ outline: 5px solid #9CB441;
288
+ font-weight: normal;
289
+ font-size: 3em;
290
+ padding: 0.5em 0;
291
+ text-align: center;
292
+ }
293
+
294
+ h2 {
295
+ margin-top: 1em;
296
+ font-size: 2em;
297
+ }
298
+
299
+ h1 a { color: #143D55; text-decoration: none }
300
+ h1 a:hover { color: #143D55; text-decoration: underline }
301
+ h2 a { color: #287AA9; text-decoration: none }
302
+ h2 a:hover { color: #287AA9; text-decoration: underline }
303
+
304
+ #wrapper {
305
+ margin: 3em auto;
306
+ width: 700px;
307
+ }
308
+
309
+ p {
310
+ margin-bottom: 1em;
311
+ }
312
+
313
+ p.info, p#footer {
314
+ color: #999;
315
+ margin-left: 1em;
316
+ }
317
+
318
+ p.info a, p#footer a {
319
+ color: #999;
320
+ }
321
+
322
+ p.info a:hover, p#footer a:hover {
323
+ text-decoration: none;
324
+ }
325
+
326
+ a {
327
+ color: #6F812D;
328
+ }
329
+
330
+ a:hover {
331
+ color: #9CB441;
332
+ }
333
+
334
+ hr {
335
+ border-width: 5px 0;
336
+ border-style: solid;
337
+ border-color: #9CB441;
338
+ border-bottom-color: #6F812D;
339
+ height: 0;
340
+ }
341
+
342
+ p#footer {
343
+ font-size: 0.9em;
344
+ margin: 0;
345
+ padding: 1em;
346
+ text-align: center;
347
+ }
348
+
349
+ label {
350
+ display: block;
351
+ width: 100%;
352
+ }
353
+
354
+ input, textarea {
355
+ padding: 5px;
356
+ margin-bottom: 1em;
357
+ margin-right: 490px;
358
+ width: 200px;
359
+ }
360
+
361
+ input.submit {
362
+ width: auto;
363
+ }
364
+
365
+ textarea {
366
+ font: normal 14px Arial, 'Bitstream Vera Sans', Helvetica, sans-serif;
367
+ height: 300px;
368
+ width: 400px;
369
+ }
370
+