cortex-reaver 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +25 -0
- data/README +48 -0
- data/bin/console +11 -0
- data/bin/cortex_reaver +110 -0
- data/bin/import.rb +78 -0
- data/lib/cortex_reaver.rb +114 -0
- data/lib/cortex_reaver/config.rb +21 -0
- data/lib/cortex_reaver/controller/comment.rb +113 -0
- data/lib/cortex_reaver/controller/config.rb +14 -0
- data/lib/cortex_reaver/controller/journal.rb +40 -0
- data/lib/cortex_reaver/controller/main.rb +56 -0
- data/lib/cortex_reaver/controller/page.rb +34 -0
- data/lib/cortex_reaver/controller/photograph.rb +45 -0
- data/lib/cortex_reaver/controller/project.rb +40 -0
- data/lib/cortex_reaver/controller/tag.rb +67 -0
- data/lib/cortex_reaver/controller/user.rb +71 -0
- data/lib/cortex_reaver/helper/activity.rb +9 -0
- data/lib/cortex_reaver/helper/attachments.rb +139 -0
- data/lib/cortex_reaver/helper/auth.rb +45 -0
- data/lib/cortex_reaver/helper/canonical.rb +55 -0
- data/lib/cortex_reaver/helper/crud.rb +317 -0
- data/lib/cortex_reaver/helper/date.rb +29 -0
- data/lib/cortex_reaver/helper/error.rb +14 -0
- data/lib/cortex_reaver/helper/feeds.rb +88 -0
- data/lib/cortex_reaver/helper/form.rb +114 -0
- data/lib/cortex_reaver/helper/navigation.rb +142 -0
- data/lib/cortex_reaver/helper/photographs.rb +25 -0
- data/lib/cortex_reaver/helper/tags.rb +47 -0
- data/lib/cortex_reaver/helper/workflow.rb +27 -0
- data/lib/cortex_reaver/migrations/001_users.rb +24 -0
- data/lib/cortex_reaver/migrations/002_pages.rb +29 -0
- data/lib/cortex_reaver/migrations/003_journals.rb +26 -0
- data/lib/cortex_reaver/migrations/004_photographs.rb +24 -0
- data/lib/cortex_reaver/migrations/005_projects.rb +27 -0
- data/lib/cortex_reaver/migrations/006_tags.rb +64 -0
- data/lib/cortex_reaver/migrations/007_comments.rb +40 -0
- data/lib/cortex_reaver/migrations/008_config.rb +23 -0
- data/lib/cortex_reaver/model/comment.rb +109 -0
- data/lib/cortex_reaver/model/journal.rb +53 -0
- data/lib/cortex_reaver/model/page.rb +87 -0
- data/lib/cortex_reaver/model/photograph.rb +133 -0
- data/lib/cortex_reaver/model/project.rb +49 -0
- data/lib/cortex_reaver/model/tag.rb +72 -0
- data/lib/cortex_reaver/model/user.rb +147 -0
- data/lib/cortex_reaver/public/css/admin.css +45 -0
- data/lib/cortex_reaver/public/css/custom.css +0 -0
- data/lib/cortex_reaver/public/css/form.css +51 -0
- data/lib/cortex_reaver/public/css/main.css +325 -0
- data/lib/cortex_reaver/public/css/photo.css +113 -0
- data/lib/cortex_reaver/public/css/ramaze_error.css +90 -0
- data/lib/cortex_reaver/public/css/text.css +25 -0
- data/lib/cortex_reaver/public/dispatch.fcgi +11 -0
- data/lib/cortex_reaver/public/images/CortexReaver.gif +0 -0
- data/lib/cortex_reaver/public/images/atom-xml-icon.png +0 -0
- data/lib/cortex_reaver/public/images/body.png +0 -0
- data/lib/cortex_reaver/public/images/border_bottom.png +0 -0
- data/lib/cortex_reaver/public/images/border_bottom_left.png +0 -0
- data/lib/cortex_reaver/public/images/border_bottom_right.png +0 -0
- data/lib/cortex_reaver/public/images/border_left.png +0 -0
- data/lib/cortex_reaver/public/images/border_right.png +0 -0
- data/lib/cortex_reaver/public/images/border_top.png +0 -0
- data/lib/cortex_reaver/public/images/border_top_left.png +0 -0
- data/lib/cortex_reaver/public/images/border_top_right.png +0 -0
- data/lib/cortex_reaver/public/images/comment.gif +0 -0
- data/lib/cortex_reaver/public/images/dark_trans.png +0 -0
- data/lib/cortex_reaver/public/images/delete.gif +0 -0
- data/lib/cortex_reaver/public/images/edit.gif +0 -0
- data/lib/cortex_reaver/public/images/header.png +0 -0
- data/lib/cortex_reaver/public/images/header.xcf +0 -0
- data/lib/cortex_reaver/public/images/header_background.png +0 -0
- data/lib/cortex_reaver/public/images/parent.gif +0 -0
- data/lib/cortex_reaver/public/images/rss-xml-icon.png +0 -0
- data/lib/cortex_reaver/public/images/sections.png +0 -0
- data/lib/cortex_reaver/public/images/sections_highlight.png +0 -0
- data/lib/cortex_reaver/public/js/admin.js +36 -0
- data/lib/cortex_reaver/public/js/cookie.js +27 -0
- data/lib/cortex_reaver/public/js/jquery.js +32 -0
- data/lib/cortex_reaver/public/js/photo.js +33 -0
- data/lib/cortex_reaver/snippets/array.rb +7 -0
- data/lib/cortex_reaver/snippets/ramaze/dispatcher/file.rb +37 -0
- data/lib/cortex_reaver/support/attachments.rb +235 -0
- data/lib/cortex_reaver/support/cached_rendering.rb +79 -0
- data/lib/cortex_reaver/support/canonical.rb +107 -0
- data/lib/cortex_reaver/support/comments.rb +69 -0
- data/lib/cortex_reaver/support/pagination.rb +38 -0
- data/lib/cortex_reaver/support/renderer.rb +196 -0
- data/lib/cortex_reaver/support/sequenceable.rb +248 -0
- data/lib/cortex_reaver/support/tags.rb +108 -0
- data/lib/cortex_reaver/support/timestamps.rb +33 -0
- data/lib/cortex_reaver/version.rb +8 -0
- data/lib/cortex_reaver/view/adminbox.rhtml +56 -0
- data/lib/cortex_reaver/view/blank_layout.rhtml +46 -0
- data/lib/cortex_reaver/view/comments/comment.rhtml +34 -0
- data/lib/cortex_reaver/view/comments/form.rhtml +25 -0
- data/lib/cortex_reaver/view/comments/list.rhtml +5 -0
- data/lib/cortex_reaver/view/comments/post_form.rhtml +36 -0
- data/lib/cortex_reaver/view/config/form.rhtml +10 -0
- data/lib/cortex_reaver/view/error.rhtml +72 -0
- data/lib/cortex_reaver/view/journals/form.rhtml +12 -0
- data/lib/cortex_reaver/view/journals/journal.rhtml +39 -0
- data/lib/cortex_reaver/view/journals/list.rhtml +33 -0
- data/lib/cortex_reaver/view/journals/short.rhtml +3 -0
- data/lib/cortex_reaver/view/journals/show.rhtml +5 -0
- data/lib/cortex_reaver/view/pages/form.rhtml +12 -0
- data/lib/cortex_reaver/view/pages/list.rhtml +26 -0
- data/lib/cortex_reaver/view/pages/show.rhtml +12 -0
- data/lib/cortex_reaver/view/photographs/atom_fragment.rhtml +82 -0
- data/lib/cortex_reaver/view/photographs/form.rhtml +19 -0
- data/lib/cortex_reaver/view/photographs/grid.rhtml +36 -0
- data/lib/cortex_reaver/view/photographs/list.rhtml +9 -0
- data/lib/cortex_reaver/view/photographs/short.rhtml +3 -0
- data/lib/cortex_reaver/view/photographs/show.rhtml +114 -0
- data/lib/cortex_reaver/view/photographs/sidebar.rhtml +7 -0
- data/lib/cortex_reaver/view/projects/form.rhtml +13 -0
- data/lib/cortex_reaver/view/projects/list.rhtml +27 -0
- data/lib/cortex_reaver/view/projects/show.rhtml +38 -0
- data/lib/cortex_reaver/view/tags/form.rhtml +9 -0
- data/lib/cortex_reaver/view/tags/list.rhtml +28 -0
- data/lib/cortex_reaver/view/tags/show.rhtml +51 -0
- data/lib/cortex_reaver/view/text_layout.rhtml +78 -0
- data/lib/cortex_reaver/view/users/form.rhtml +16 -0
- data/lib/cortex_reaver/view/users/list.rhtml +38 -0
- data/lib/cortex_reaver/view/users/login.rhtml +13 -0
- data/lib/cortex_reaver/view/users/register.rhtml +13 -0
- data/lib/cortex_reaver/view/users/show.rhtml +37 -0
- data/lib/cortex_reaver/view/users/user.rhtml +35 -0
- data/lib/proto/cortex_reaver.yaml +28 -0
- metadata +285 -0
@@ -0,0 +1,45 @@
|
|
1
|
+
module Ramaze
|
2
|
+
module Helper
|
3
|
+
# Provides authentication services
|
4
|
+
module Auth
|
5
|
+
# Is the current user an admin?
|
6
|
+
def admin?
|
7
|
+
u = session[:user] and u.admin?
|
8
|
+
end
|
9
|
+
|
10
|
+
# Tries to log in a user by login and password. If successful, sets
|
11
|
+
# session[:user] to the user and returns that user. Otherwise returns
|
12
|
+
# false.
|
13
|
+
def do_login(login, password)
|
14
|
+
if user = CortexReaver::User.authenticate(login, password)
|
15
|
+
# Successful login
|
16
|
+
session[:user] = user
|
17
|
+
else
|
18
|
+
false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Log out the current user, and returns the user object.
|
23
|
+
def do_logout
|
24
|
+
session.delete :user
|
25
|
+
end
|
26
|
+
|
27
|
+
def require_admin
|
28
|
+
if session[:user] and session[:user].admin?
|
29
|
+
true
|
30
|
+
elsif session[:user]
|
31
|
+
flash[:error] = "You must have administrative privileges to do this."
|
32
|
+
redirect :/
|
33
|
+
else
|
34
|
+
flash[:notice] = "Please log in first."
|
35
|
+
session[:target_uri] = request.request_uri
|
36
|
+
redirect R('/users', :login)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def error_403
|
41
|
+
respond 'Forbidden', 403
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Ramaze
|
2
|
+
module Helper
|
3
|
+
module Canonical
|
4
|
+
Helper::LOOKUP << self
|
5
|
+
|
6
|
+
# Returns the canonical name for this model, given a candidate new name.
|
7
|
+
def canonicalize
|
8
|
+
respond self.class.const_get('MODEL').canonicalize(
|
9
|
+
request[:new],
|
10
|
+
request[:id]
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
# Adds an AJAX-ified name field for a model.
|
17
|
+
def live_name_field(model, opts={:name => 'name', :watch => 'title'})
|
18
|
+
name = opts[:name]
|
19
|
+
watch = opts[:watch]
|
20
|
+
title = opts[:title] || name.to_s.titleize
|
21
|
+
|
22
|
+
s = "<p><label for=\"#{name}\">#{title}</label>"
|
23
|
+
s << "<input name=\"#{name}\" id=\"#{name}\" type=\"text\" value=\"#{attr_h(model.send(opts[:name]))}\" /></p>"
|
24
|
+
|
25
|
+
s << <<EOF
|
26
|
+
<script type="text/javascript">
|
27
|
+
/* <![CDATA[ */
|
28
|
+
|
29
|
+
// Updates the "name" field as the watched field changes.
|
30
|
+
$('##{watch}').change(function () {
|
31
|
+
$.get('#{Rs('canonicalize')}', {
|
32
|
+
new: $('##{watch}').val(),
|
33
|
+
id: '#{model.id}'
|
34
|
+
}, function(response) {
|
35
|
+
$('##{name}').val(response);
|
36
|
+
})
|
37
|
+
});
|
38
|
+
|
39
|
+
// Canonicalizes the name when we're done, just to make sure.
|
40
|
+
$('##{name}').blur(function() {
|
41
|
+
$.get('#{Rs('canonicalize')}', {
|
42
|
+
new: $('##{name}').val(),
|
43
|
+
id: '#{model.id}'
|
44
|
+
}, function(response) {
|
45
|
+
$('##{name}').val(response);
|
46
|
+
})
|
47
|
+
});
|
48
|
+
|
49
|
+
/* ]]> */
|
50
|
+
</script>
|
51
|
+
EOF
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,317 @@
|
|
1
|
+
module Ramaze
|
2
|
+
module Helper
|
3
|
+
# Provides list, create, read, update, and delete functionality for Cortex
|
4
|
+
# Reaver. Centralizes the lookup and database logic for re-use across
|
5
|
+
# several models.
|
6
|
+
#
|
7
|
+
# Requires pagination, auth, workflow, and feeds
|
8
|
+
module Crud
|
9
|
+
require 'builder'
|
10
|
+
|
11
|
+
Helper::LOOKUP << self
|
12
|
+
|
13
|
+
def self.included(base)
|
14
|
+
base.instance_eval do
|
15
|
+
# Provides on_save, on_create, on_update callbacks for controllers,
|
16
|
+
# which defines how the controller CRUD sets attributes on the
|
17
|
+
# primary model.
|
18
|
+
|
19
|
+
# This block is called when a new model is being created. The model
|
20
|
+
# and request are passed to the block. The resulting model is stored
|
21
|
+
# in the database. Example:
|
22
|
+
#
|
23
|
+
# JournalController.on_save do |journal, request|
|
24
|
+
# journal.title = request[:title]
|
25
|
+
# journal.body = request[:body].downcase
|
26
|
+
# end
|
27
|
+
|
28
|
+
def self.on_create(&block)
|
29
|
+
unless block_given? and block.arity == 2
|
30
|
+
raise ArgumentError.new("needs a block with two arguments")
|
31
|
+
end
|
32
|
+
@on_create = block
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.on_update(&block)
|
36
|
+
unless block_given? and block.arity == 2
|
37
|
+
raise ArgumentError.new("needs a block with two arguments")
|
38
|
+
end
|
39
|
+
@on_update = block
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.on_save(&block)
|
43
|
+
unless block_given? and block.arity == 2
|
44
|
+
raise ArgumentError.new("needs a block with two arguments")
|
45
|
+
end
|
46
|
+
@on_save = block
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.on_second_save(&block)
|
50
|
+
unless block_given? and block.arity == 2
|
51
|
+
raise ArgumentError.new("needs a block with two arguments")
|
52
|
+
end
|
53
|
+
@on_second_save = block
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.on_create_block
|
57
|
+
@on_create
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.on_save_block
|
61
|
+
@on_save
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.on_second_save_block
|
65
|
+
@on_second_save
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.on_update_block
|
69
|
+
@on_update
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
base.class_eval do
|
74
|
+
# Check that MODEL is defined, so we know what we're working with.
|
75
|
+
unless const_defined?('MODEL')
|
76
|
+
raise RuntimeError.new("can't use CRUD helper unless MODEL is set.")
|
77
|
+
end
|
78
|
+
|
79
|
+
# Set the singular and plural instance vars for MODEL.
|
80
|
+
unless const_defined?('SINGULAR_MODEL_VAR')
|
81
|
+
const_set('SINGULAR_MODEL_VAR', '@' + const_get('MODEL').to_s.demodulize.underscore)
|
82
|
+
end
|
83
|
+
unless const_defined?('PLURAL_MODEL_VAR')
|
84
|
+
const_set('PLURAL_MODEL_VAR', const_get('SINGULAR_MODEL_VAR').pluralize)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Prevent conflicts with our 0-ary action methods. Not needed if
|
88
|
+
# we're using controller/show/name instead of controller/name
|
89
|
+
#
|
90
|
+
#begin
|
91
|
+
# const_get('MODEL').reserved_canonical_names += ['index', 'new']
|
92
|
+
#rescue
|
93
|
+
#end
|
94
|
+
|
95
|
+
# This action can't be in the normal module body, or it breaks things.
|
96
|
+
def new
|
97
|
+
require_admin
|
98
|
+
|
99
|
+
@title = "New #{h model_class.to_s.demodulize.titleize}"
|
100
|
+
@form_action = :new
|
101
|
+
|
102
|
+
if request.post?
|
103
|
+
begin
|
104
|
+
# Create model
|
105
|
+
CortexReaver.db.transaction do
|
106
|
+
@model = model_class.new
|
107
|
+
|
108
|
+
# Initial callbacks
|
109
|
+
if block = self.class.on_save_block
|
110
|
+
block.call(@model, request)
|
111
|
+
end
|
112
|
+
if block = self.class.on_create_block
|
113
|
+
block.call(@model, request)
|
114
|
+
end
|
115
|
+
|
116
|
+
# Save for the first time
|
117
|
+
raise unless @model.save
|
118
|
+
|
119
|
+
# Second save callback, if applicable
|
120
|
+
if block = self.class.on_second_save_block
|
121
|
+
block.call(@model, request)
|
122
|
+
raise unless @model.save
|
123
|
+
end
|
124
|
+
|
125
|
+
flash[:notice] = "Created #{model_class.to_s.demodulize.downcase} #{h @model.to_s}."
|
126
|
+
redirect @model.url
|
127
|
+
end
|
128
|
+
rescue => e
|
129
|
+
# An error occurred
|
130
|
+
Ramaze::Log.error e.inspect + e.backtrace.join("\n")
|
131
|
+
flash[:error] = "Couldn't create #{model_class.to_s.demodulize.downcase} #{h request[:title]}: #{h e}."
|
132
|
+
set_singular_model_var @model
|
133
|
+
end
|
134
|
+
else
|
135
|
+
set_singular_model_var model_class.new
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
private
|
142
|
+
|
143
|
+
# Returns the model class for this controller, e.g., 'Journal'
|
144
|
+
def model_class
|
145
|
+
self.class.const_get('MODEL')
|
146
|
+
end
|
147
|
+
|
148
|
+
# Set the singular instance var for this controller, e.g. '@journal'.
|
149
|
+
def set_singular_model_var(value)
|
150
|
+
instance_variable_set(self.class.const_get('SINGULAR_MODEL_VAR'), value)
|
151
|
+
end
|
152
|
+
|
153
|
+
# Set the plural instance var for this controller, e.g. '@journals'
|
154
|
+
def set_plural_model_var(value)
|
155
|
+
instance_variable_set(self.class.const_get('PLURAL_MODEL_VAR'), value)
|
156
|
+
end
|
157
|
+
|
158
|
+
public
|
159
|
+
|
160
|
+
# Normal actions start here.
|
161
|
+
|
162
|
+
def index(id = nil)
|
163
|
+
if id
|
164
|
+
# Redirect to show
|
165
|
+
#
|
166
|
+
# This way, you can (assuming your name doesn't conflict with an existing
|
167
|
+
# action) tell people to visit /journals/my-cool-event, and it will go to
|
168
|
+
# /journals/show/my-cool-event.
|
169
|
+
raw_redirect Rs(:show, id), :status => 301
|
170
|
+
else
|
171
|
+
# Display index
|
172
|
+
page :last
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def delete(id)
|
177
|
+
require_admin
|
178
|
+
|
179
|
+
if @model = model_class.get(id)
|
180
|
+
if @model.destroy
|
181
|
+
flash[:notice] = "#{model_class.to_s.demodulize.downcase} #{h @model.to_s} deleted."
|
182
|
+
redirect Rs()
|
183
|
+
else
|
184
|
+
flash[:notice] = "Couldn't delete #{model_class.to_s.demodulize.downcase} #{h @model.to_s}."
|
185
|
+
redirect @model.url
|
186
|
+
end
|
187
|
+
else
|
188
|
+
flash[:error] = "No such #{model_class.to_s.demodulize.downcase} (#{h id}) exists."
|
189
|
+
redirect Rs()
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def edit(id = nil)
|
194
|
+
require_admin
|
195
|
+
|
196
|
+
if @model = model_class.get(id)
|
197
|
+
@title = "Edit #{model_class.to_s.demodulize.downcase} #{h @model.to_s}"
|
198
|
+
if @model.class.respond_to? :canonical_name_attr
|
199
|
+
@form_action = "edit/#{@model.send(@model.class.canonical_name_attr)}"
|
200
|
+
else
|
201
|
+
@form_action = "edit/#{@model.id}"
|
202
|
+
end
|
203
|
+
|
204
|
+
set_singular_model_var @model
|
205
|
+
|
206
|
+
if request.post?
|
207
|
+
begin
|
208
|
+
# Update model
|
209
|
+
CortexReaver.db.transaction do
|
210
|
+
# Initial callbacks
|
211
|
+
if block = self.class.on_save_block
|
212
|
+
block.call(@model, request)
|
213
|
+
end
|
214
|
+
if block = self.class.on_update_block
|
215
|
+
block.call(@model, request)
|
216
|
+
end
|
217
|
+
|
218
|
+
# Save
|
219
|
+
raise unless @model.save
|
220
|
+
|
221
|
+
# Second callbacks and save if applicable
|
222
|
+
if block = self.class.on_second_save_block
|
223
|
+
block.call(@model, request)
|
224
|
+
raise unless @model.save
|
225
|
+
end
|
226
|
+
|
227
|
+
flash[:notice] = "Updated #{model_class.to_s.demodulize.downcase} #{h @model.to_s}."
|
228
|
+
redirect @model.url
|
229
|
+
end
|
230
|
+
rescue => e
|
231
|
+
# An error occurred
|
232
|
+
Ramaze::Log.error e.inspect + e.backtrace.join("\n")
|
233
|
+
flash[:error] = "Couldn't update #{model_class.to_s.demodulize.downcase} #{h @model.to_s}: #{h e}."
|
234
|
+
end
|
235
|
+
end
|
236
|
+
else
|
237
|
+
flash[:error] = "No such #{model_class.to_s.demodulize.downcase} (#{id}) exists."
|
238
|
+
redirect Rs()
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
def page(page)
|
243
|
+
|
244
|
+
page = case page
|
245
|
+
when Symbol
|
246
|
+
page
|
247
|
+
when 'first'
|
248
|
+
:first
|
249
|
+
when 'last'
|
250
|
+
:last
|
251
|
+
when nil
|
252
|
+
error_404
|
253
|
+
else
|
254
|
+
page.to_i
|
255
|
+
end
|
256
|
+
|
257
|
+
@title = "#{model_class.to_s.demodulize.pluralize.titleize}"
|
258
|
+
if self.class.private_method_defined? :feed and model_class.respond_to? :atom_url
|
259
|
+
feed @title, model_class.atom_url
|
260
|
+
end
|
261
|
+
@models = model_class.window(page)
|
262
|
+
@page = page
|
263
|
+
|
264
|
+
if model_class.count.zero?
|
265
|
+
# There are NO models
|
266
|
+
elsif @models.empty?
|
267
|
+
# Empty page
|
268
|
+
error_404
|
269
|
+
end
|
270
|
+
|
271
|
+
set_plural_model_var @models
|
272
|
+
|
273
|
+
workflow "New #{model_class.to_s.demodulize}", Rs(:new)
|
274
|
+
|
275
|
+
render_template :list
|
276
|
+
end
|
277
|
+
|
278
|
+
def show(id)
|
279
|
+
if id and @model = model_class.get(id)
|
280
|
+
# Found that model
|
281
|
+
# Redirect IDs to names
|
282
|
+
raw_redirect(@model.url, :status => 301) if id =~ /^\d+$/
|
283
|
+
|
284
|
+
@title = h @model.to_s
|
285
|
+
set_singular_model_var @model
|
286
|
+
|
287
|
+
# Retrieve pending comment from session, if applicable.
|
288
|
+
if comment = session[:pending_comment] and comment.parent == @model
|
289
|
+
@new_comment = session.delete :pending_comment
|
290
|
+
else
|
291
|
+
# Create a comment to be posted
|
292
|
+
@new_comment = CortexReaver::Comment.new
|
293
|
+
@new_comment.send("#{model_class.to_s.demodulize.underscore.downcase}=", @model)
|
294
|
+
end
|
295
|
+
|
296
|
+
if session[:user]
|
297
|
+
@new_comment.user = session[:user]
|
298
|
+
end
|
299
|
+
|
300
|
+
# ID component of edit/delete links
|
301
|
+
if @model.class.respond_to? :canonical_name_attr
|
302
|
+
id = @model.send(@model.class.canonical_name_attr)
|
303
|
+
else
|
304
|
+
id = @model.id
|
305
|
+
end
|
306
|
+
|
307
|
+
workflow "Edit this #{model_class.to_s.demodulize}", Rs(:edit, id)
|
308
|
+
workflow "Delete this #{model_class.to_s.demodulize}", Rs(:delete, id)
|
309
|
+
render_template :show
|
310
|
+
elsif id
|
311
|
+
# Didn't find that model
|
312
|
+
error_404
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Ramaze
|
2
|
+
module Helper
|
3
|
+
# Provides assistance methods for displaying dates of objects.
|
4
|
+
module Date
|
5
|
+
# Puts out a line describing the creation (and modification) date of a
|
6
|
+
# model. If times are within identical_tolerance seconds (for example,
|
7
|
+
# because you forgot something on the form, hit back, and updated the
|
8
|
+
# record), the update time isn't displayed.
|
9
|
+
def date_line(model, identical_tolerance = 3600)
|
10
|
+
c = model.created_on
|
11
|
+
u = model.updated_on
|
12
|
+
date = '<span class="date">' + c.strftime('%A, %e %B %Y, %H:%M') + "</span>"
|
13
|
+
|
14
|
+
if (u - c) > identical_tolerance
|
15
|
+
# A significant modification time.
|
16
|
+
if u.year != c.year
|
17
|
+
date << " (updated <span class=\"date\">#{u.strftime('%A, %e %B %Y, %H:%M')}</span>)"
|
18
|
+
elsif u.day != c.day
|
19
|
+
date << " (updated <span class=\"date\">#{u.strftime('%A, %e %B, %H:%M')})</span>"
|
20
|
+
else
|
21
|
+
date << " (updated <span class=\"date\">#{u.strftime('%H:%M')}</span>)"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
date
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|