camping 1.5.180 → 2.0.rc0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +35 -0
- data/README +43 -68
- data/Rakefile +155 -86
- data/bin/camping +64 -246
- data/book/01_introduction +19 -0
- data/book/02_getting_started +443 -0
- data/book/51_upgrading +93 -0
- data/doc/api.html +1953 -0
- data/doc/book.html +73 -0
- data/doc/book/01_introduction.html +57 -0
- data/doc/book/02_getting_started.html +573 -0
- data/doc/book/51_upgrading.html +146 -0
- data/doc/created.rid +1 -0
- data/{extras → doc/images}/Camping.gif +0 -0
- data/doc/images/loadingAnimation.gif +0 -0
- data/{extras → doc/images}/permalink.gif +0 -0
- data/doc/index.html +148 -0
- data/doc/js/camping.js +79 -0
- data/doc/js/jquery.js +32 -0
- data/doc/rdoc.css +117 -0
- data/examples/blog.rb +280 -181
- data/extras/images/badge.gif +0 -0
- data/extras/images/boys-life.png +0 -0
- data/extras/images/deerputer.png +0 -0
- data/extras/images/diagram.png +0 -0
- data/extras/images/hill.png +0 -0
- data/extras/images/i-wish.png +0 -0
- data/extras/images/latl.png +0 -0
- data/extras/images/little-wheels.png +0 -0
- data/extras/images/square-badge.png +0 -0
- data/extras/images/uniform.png +0 -0
- data/extras/images/whale-bounce.png +0 -0
- data/extras/rdoc/generator/singledarkfish.rb +205 -0
- data/extras/rdoc/generator/template/flipbook/images/Camping.gif +0 -0
- data/extras/rdoc/generator/template/flipbook/images/loadingAnimation.gif +0 -0
- data/extras/rdoc/generator/template/flipbook/images/permalink.gif +0 -0
- data/extras/rdoc/generator/template/flipbook/js/camping.js +79 -0
- data/extras/rdoc/generator/template/flipbook/js/jquery.js +32 -0
- data/extras/rdoc/generator/template/flipbook/page.rhtml +30 -0
- data/extras/rdoc/generator/template/flipbook/rdoc.css +117 -0
- data/extras/rdoc/generator/template/flipbook/readme.rhtml +31 -0
- data/extras/rdoc/generator/template/flipbook/reference.rhtml +71 -0
- data/extras/rdoc/generator/template/flipbook/toc.rhtml +43 -0
- data/lib/camping-unabridged.rb +420 -481
- data/lib/camping.rb +40 -55
- data/lib/camping/{db.rb → ar.rb} +5 -8
- data/lib/camping/mab.rb +26 -0
- data/lib/camping/reloader.rb +175 -147
- data/lib/camping/server.rb +178 -0
- data/lib/camping/session.rb +34 -121
- data/test/apps/env_debug.rb +65 -0
- data/test/apps/forms.rb +95 -0
- data/test/apps/forward_to_other_controller.rb +60 -0
- data/test/apps/migrations.rb +97 -0
- data/test/apps/misc.rb +86 -0
- data/test/apps/sessions.rb +38 -0
- metadata +120 -80
- data/doc/camping.1.gz +0 -0
- data/examples/campsh.rb +0 -630
- data/examples/tepee.rb +0 -242
- data/extras/flipbook_rdoc.rb +0 -491
- data/lib/camping/fastcgi.rb +0 -244
- data/lib/camping/webrick.rb +0 -65
- 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__) +
|
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
|
-
|
11
|
-
end
|
12
|
+
include Camping::Session
|
12
13
|
|
13
|
-
module
|
14
|
-
class Post < Base
|
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
|
28
|
+
class BasicFields < V 1.1
|
19
29
|
def self.up
|
20
30
|
create_table :blog_posts, :force => true do |t|
|
21
|
-
t.
|
22
|
-
t.
|
23
|
-
t.
|
24
|
-
t.
|
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.
|
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.
|
33
|
-
t.
|
34
|
-
t.
|
35
|
-
t.
|
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
|
48
|
-
class Index
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
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
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
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
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
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
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
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
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
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
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
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
|
-
|
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 '
|
154
|
+
title 'My Blog'
|
162
155
|
link :rel => 'stylesheet', :type => 'text/css',
|
163
|
-
|
156
|
+
:href => '/styles.css', :media => 'screen'
|
164
157
|
end
|
165
158
|
body do
|
166
|
-
h1
|
167
|
-
|
168
|
-
|
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 ' – 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
|
-
|
177
|
-
p
|
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
|
-
|
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
|
-
|
187
|
-
p
|
188
|
-
|
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
|
-
|
191
|
-
|
192
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
232
|
-
|
233
|
-
|
234
|
-
|
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(' – ')
|
241
230
|
end
|
242
231
|
|
243
232
|
def _post(post)
|
244
|
-
|
245
|
-
p
|
246
|
-
|
247
|
-
|
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'
|
255
|
-
input :name => 'post_title', :type => 'text',
|
256
|
-
:value => post.title
|
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'
|
259
|
-
textarea post.body, :name => 'post_body'
|
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
|
-
|
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
|
+
|