cms_controller.rb
11.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
class CmsController < MyProfileController
define_option :page_class, Article
protect 'post_content', :profile, :only => [:edit, :new, :reorder, :delete]
protected
def profile
Profile.find_by_identifier(params[:profile])
end
def user
current_user.person
end
public
#############################################################
# everything below was copied from comatose
#############################################################
define_option :original_template_root, nil
define_option :plugin_layout_path, File.join( '..', '..', '..', 'vendor', 'plugins', 'comatose', 'views', 'layouts' )
before_filter :handle_authorization
before_filter :set_content_type
# Shows the page tree
def index
@root_pages = [fetch_root_page].flatten
end
# Edit a specfic page (posts back)
def edit
# Clear the page cache for this page... ?
@page = page_class.find params[:id]
@root_pages = [fetch_root_page].flatten
if request.post?
@page.update_attributes(params[:page])
@page.updated_on = Time.now
@page.author = fetch_author_name
if @page.save
expire_cms_page @page
expire_cms_fragment @page
flash[:notice] = "Saved changes to '#{@page.title}'"
redirect_to :controller=>self.controller_name, :action=>'index'
end
end
end
# Create a new page (posts back)
def new
@root_pages = [fetch_root_page].flatten
if request.post?
@page = page_class.new params[:page]
@page.author = fetch_author_name
if @page.save
flash[:notice] = "Created page '#{@page.title}'"
redirect_to :controller=>self.controller_name, :action=>'index'
end
else
@page = page_class.new(:parent_id=>(params[:parent] || nil))
end
end
# Saves position of child pages
def reorder
# If it's AJAX, do our thing and move on...
if request.xhr?
params["page_list_#{params[:id]}"].each_with_index { |id,idx| page_class.update(id, :position => idx) }
expire_cms_page page_class.find(params[:id])
render :text=>'Updated sort order', :layout=>false
else
@page = page_class.find params[:id]
if params.has_key? :cmd
@target = page_class.find params[:page]
case params[:cmd]
when 'up' then @target.move_higher
when 'down' then @target.move_lower
end
redirect_to :action=>'reorder', :id=>@page
end
end
end
# Allows comparing between two versions of a page's content
def versions
@page = page_class.find params[:id]
@version_num = (params[:version] || @page.versions.length).to_i
@version = @page.find_version(@version_num)
end
# Reverts a page to a specific version...
def set_version
if request.post?
@page = page_class.find params[:id]
@version_num = params[:version]
@page.revert_to!(@version_num)
end
redirect_to :controller=>self.controller_name, :action=>'index'
end
# Deletes the specified page
def delete
@page = page_class.find params[:id]
if request.post?
expire_cms_pages_from_bottom @page
expire_cms_fragments_from_bottom @page
@page.destroy
flash[:notice] = "Deleted page '#{@page.title}'"
redirect_to :controller=>self.controller_name, :action=>'index'
end
end
# Returns a preview of the page content...
def preview
begin
page = page_class.new(params[:page])
page.author = fetch_author_name
if params.has_key? :version
content = page.to_html( {'params'=>params.stringify_keys, 'version'=>params[:version]} )
else
content = page.to_html( {'params'=>params.stringify_keys} )
end
rescue SyntaxError
content = "<p>There was an error generating the preview.</p><p><pre>#{$!.to_s.gsub(/\</, '<')}</pre></p>"
rescue
content = "<p>There was an error generating the preview.</p><p><pre>#{$!.to_s.gsub(/\</, '<')}</pre></p>"
end
render :text=>content, :layout => false
end
# Expires the entire page cache
def expire_page_cache
expire_cms_pages_from_bottom( fetch_root_page )
expire_cms_fragments_from_bottom( fetch_root_page )
flash[:notice] = "Page cache has been flushed"
redirect_to :controller=>self.controller_name, :action=>'index'
end
# Walks the page tree and generates HTML files in your /public
# folder... It will skip pages that have a 'nocache' keyword
# TODO: Make page cache generation work when in :plugin mode
def generate_page_cache
if runtime_mode == :plugin
@errors = ["Page cache cannot be generated in plugin mode"]
else
@errors = generate_all_pages_html(params)
end
if @errors.length == 0
flash[:notice] = "Pages Cached Successfully"
else
flash[:notice] = "Pages Cache Error(s): #{@errors.join(', ')}"
flash[:cache_errors] = @errors
end
redirect_to :controller=>self.controller_name, :action=>'index'
end
protected
def handle_authorization
if Comatose.config.admin_authorization.is_a? Proc
instance_eval &Comatose.config.admin_authorization
elsif Comatose.config.admin_authorization.is_a? Symbol
send(Comatose.config.admin_authorization)
elsif defined? authorize
authorize
else
true
end
end
def fetch_author_name
if Comatose.config.admin_get_author.is_a? Proc
instance_eval &Comatose.config.admin_get_author
elsif Comatose.config.admin_get_author.is_a? Symbol
send(Comatose.config.admin_get_author)
elsif defined? get_author
get_author
end
end
# Can be overridden -- return your root comtase page
def fetch_root_page
if Comatose.config.admin_get_root_page.is_a? Proc
instance_eval &Comatose.config.admin_get_root_page
elsif Comatose.config.admin_get_root_page.is_a? Symbol
send(Comatose.config.admin_get_root_page)
elsif defined? get_root_page
get_root_page
end
end
# Sets the HTTP content-type header based on what's configured
# in Comatose.config.content_type
def set_content_type
response.headers["Content-Type"] = "text/html; charset=#{Comatose.config.content_type}" unless Comatose.config.content_type.nil?
end
# Calls generate_page_html for each mount point..
def generate_all_pages_html(params={})
@errors = []
@been_cached = []
Comatose.mount_points.each do |root_info|
page_class.active_mount_info = root_info
generate_page_html(page_class.find_by_path( root_info[:index] ), root_info, params)
end
@errors
end
# Accepts a Comatose Page and a root_info object to generate
# the page as a static HTML page -- using the layout that was
# defined on the mount point
def generate_page_html(page, root_info, params={})
@been_cached ||= []
unless page.has_keyword? :nocache or @been_cached.include? page.id
uri = page.uri
uri = "#{uri}/index".split('/').flatten.join('/') if page.full_path == root_info[:index]
@page = Comatose::PageWrapper.new(page)
begin
page_layout = get_page_layout(root_info)
#puts "mode = #{runtime_mode}, layout = #{page_layout}, template_root = #{template_root}, original_template_root = #{original_template_root}"
html = render_to_string( :text=>page.to_html({'params'=>params.stringify_keys}), :layout=>page_layout )
cache_page( html, uri )
rescue
logger.error "Comatose CMS Page Cache Exception: #{$!}"
@errors << "(#{page}/#{page.slug}) - #{$!}"
end
@been_cached << page.id
# recurse...
page.children.each do |child|
generate_page_html(child, root_info)
end
end
end
# Calls the class methods of the same name...
def expire_cms_page(page)
self.class.expire_cms_page(page)
end
def expire_cms_pages_from_bottom(page)
self.class.expire_cms_pages_from_bottom(page)
end
# expire the page from the fragment cache
def expire_cms_fragment(page)
key = page.full_path.gsub(/\//, '+')
expire_fragment(key)
end
# expire pages starting at a specific node
def expire_cms_fragments_from_bottom(page)
pages = page.is_a?(Array) ? page : [page]
pages.each do |page|
page.children.each {|c| expire_cms_fragments_from_bottom( c ) } if !page.children.empty?
expire_cms_fragment( page )
end
end
# Class Methods...
class << self
# Walks all the way down, and back up the tree -- the allows the expire_cms_page
# to delete empty directories better
def expire_cms_pages_from_bottom(page)
pages = page.is_a?(Array) ? page : [page]
pages.each do |page|
page.children.each {|c| expire_cms_pages_from_bottom( c ) } if !page.children.empty?
expire_cms_page( page )
end
end
# Expire the page from all the mount points...
def expire_cms_page(page)
Comatose.mount_points.each do |path_info|
page_class.active_mount_info = path_info
expire_page(page.uri)
# If the page is the index page for the root, expire it too
if path_info[:root] == page.uri
expire_page("#{path_info[:root]}/index")
end
begin # I'm not sure this matters too much -- but it keeps things clean
dir_path = File.join(RAILS_ROOT, 'public', page.uri[1..-1])
Dir.delete( dir_path ) if FileTest.directory?( dir_path ) and !page.parent.nil?
rescue
# It probably isn't empty -- just as well we leave it be
#STDERR.puts " - Couldn't delete dir #{dir_path} -> #{$!}"
end
end
end
# Returns a path to plugin layout, if it's unspecified, otherwise
# a path to an application layout...
def get_page_layout(params)
if params[:layout] == 'comatose_content'
File.join(plugin_layout_path, params[:layout])
else
params[:layout]
end
end
def configure_template_root
if self.runtime_mode == :unknown
if FileTest.exist? File.join(RAILS_ROOT, 'public', 'javascripts', 'comatose_admin.js')
self.runtime_mode = :application
else
self.runtime_mode = :plugin
end
end
end
def runtime_mode
@@runtime_mode ||= :unknown
end
def runtime_mode=(mode)
case mode
when :plugin
self.original_template_root = self.template_root
self.template_root = File.join( File.dirname(__FILE__), '..', '..', 'views')
when :application
self.template_root = self.original_template_root if self.original_template_root
end
@@runtime_mode = mode
end
end
# Check to see if we are in 'embedded' mode, or are being 'customized'
# embedded = runtime_mode of :plugin
# customized = runtime_mode of :application
configure_template_root
#
# Include any modules...
Comatose.config.admin_includes.each do |mod|
if mod.is_a? String
include mod.constantize
elsif mod.is_a? Symbol
include mod.to_s.classify.constantize
else
include mod
end
end
# Include any helpers...
Comatose.config.admin_helpers.each do |mod|
if mod.is_a? String
helper mod.constantize
elsif mod.is_a? Symbol
helper mod.to_s.classify.constantize
else
helper mod
end
end
end