comatose-rubyisbeautiful 3.0.0

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.
Files changed (192) hide show
  1. data/CHANGELOG +198 -0
  2. data/Gemfile +29 -0
  3. data/Gemfile.lock +130 -0
  4. data/INSTALL +14 -0
  5. data/LICENSE +20 -0
  6. data/Manifest +188 -0
  7. data/README +0 -0
  8. data/README.markdown +113 -0
  9. data/Rakefile +5 -0
  10. data/SPECS +61 -0
  11. data/app/controllers/application_controller.rb +3 -0
  12. data/app/controllers/comatose/admin_controller.rb +425 -0
  13. data/app/controllers/comatose/application_controller.rb +30 -0
  14. data/app/controllers/comatose/base_controller.rb +167 -0
  15. data/app/helpers/application_helper.rb +2 -0
  16. data/app/helpers/comatose/admin_helper.rb +78 -0
  17. data/app/helpers/comatose/application_helper.rb +2 -0
  18. data/app/helpers/comatose/base_helper.rb +5 -0
  19. data/app/models/comatose/page.rb +166 -0
  20. data/app/views/comatose/admin/_form.html.erb +108 -0
  21. data/app/views/comatose/admin/_page_list_item.html.erb +62 -0
  22. data/app/views/comatose/admin/delete.html.erb +18 -0
  23. data/app/views/comatose/admin/edit.html.erb +5 -0
  24. data/app/views/comatose/admin/index.html.erb +34 -0
  25. data/app/views/comatose/admin/new.html.erb +5 -0
  26. data/app/views/comatose/admin/reorder.html.erb +30 -0
  27. data/app/views/comatose/admin/versions.html.erb +40 -0
  28. data/app/views/layouts/application.html.erb +14 -0
  29. data/app/views/layouts/comatose/admin.html.erb +44 -0
  30. data/app/views/layouts/comatose/base.html.erb +14 -0
  31. data/comatose-rubyisbeautiful.gemspec +65 -0
  32. data/config/environment.rb +5 -0
  33. data/config/environments/development.rb +26 -0
  34. data/config/environments/production.rb +49 -0
  35. data/config/environments/test.rb +35 -0
  36. data/config/locales/en.yml +5 -0
  37. data/config.ru +4 -0
  38. data/db/seeds.rb +11 -0
  39. data/lib/comatose/configuration.rb +87 -0
  40. data/lib/comatose/drop.rb +45 -0
  41. data/lib/comatose/engine.rb +28 -0
  42. data/lib/comatose/filters/inline_filter.rb +15 -0
  43. data/lib/comatose/filters/timeago_filter.rb +14 -0
  44. data/lib/comatose/filters/translation_filter.rb +11 -0
  45. data/lib/comatose/locale_constraint.rb +15 -0
  46. data/lib/comatose/logger.rb +10 -0
  47. data/lib/comatose/page_wrapper.rb +147 -0
  48. data/lib/comatose/processing_context.rb +103 -0
  49. data/lib/comatose/routes.rb +70 -0
  50. data/lib/comatose/tasks/admin.rb +57 -0
  51. data/lib/comatose/tasks/data.rb +79 -0
  52. data/lib/comatose/tasks/setup.rb +118 -0
  53. data/lib/comatose/text_filters.rb +148 -0
  54. data/lib/comatose/version.rb +9 -0
  55. data/lib/comatose.rb +88 -0
  56. data/lib/generators/comatose/USAGE +7 -0
  57. data/lib/generators/comatose/comatose_generator.rb +37 -0
  58. data/lib/generators/comatose/templates/comatose.rb +33 -0
  59. data/lib/generators/comatose/templates/migration.erb +32 -0
  60. data/lib/generators/comatose/templates/seeds.erb +2 -0
  61. data/lib/support/class_options.rb +36 -0
  62. data/lib/support/inline_rendering.rb +48 -0
  63. data/lib/support/route_mapper.rb +51 -0
  64. data/lib/tasks/comatose.rake +9 -0
  65. data/lib/text_filters/markdown.rb +14 -0
  66. data/lib/text_filters/markdown_smartypants.rb +15 -0
  67. data/lib/text_filters/none.rb +8 -0
  68. data/lib/text_filters/rdoc.rb +13 -0
  69. data/lib/text_filters/simple.rb +8 -0
  70. data/lib/text_filters/textile.rb +15 -0
  71. data/public/404.html +26 -0
  72. data/public/422.html +26 -0
  73. data/public/500.html +26 -0
  74. data/public/favicon.ico +0 -0
  75. data/public/images/comatose/collapsed.gif +0 -0
  76. data/public/images/comatose/expanded.gif +0 -0
  77. data/public/images/comatose/no-children.gif +0 -0
  78. data/public/images/comatose/page.gif +0 -0
  79. data/public/images/comatose/rails.png +0 -0
  80. data/public/images/comatose/spinner.gif +0 -0
  81. data/public/images/comatose/title-hover-bg.gif +0 -0
  82. data/public/javascripts/comatose/admin.js +406 -0
  83. data/public/javascripts/comatose/application.js +2 -0
  84. data/public/javascripts/comatose/dragdrop.js +974 -0
  85. data/public/javascripts/editor.js +452 -0
  86. data/public/javascripts/jquery/GPL-LICENSE.txt +278 -0
  87. data/public/javascripts/jquery/MIT-LICENSE.txt +20 -0
  88. data/public/javascripts/jquery/README +67 -0
  89. data/public/javascripts/jquery/jquery.js +11 -0
  90. data/public/javascripts/jquery/jquery.ui.draggable.js +1 -0
  91. data/public/javascripts/jquery/jquery.ui.js +1 -0
  92. data/public/javascripts/jquery/jquery.ui.resizable.js +1 -0
  93. data/public/javascripts/jquery/jquery.ui.sortable.js +1 -0
  94. data/public/javascripts/wymeditor/iframe/default/lbl-blockquote.png +0 -0
  95. data/public/javascripts/wymeditor/iframe/default/lbl-h1.png +0 -0
  96. data/public/javascripts/wymeditor/iframe/default/lbl-h2.png +0 -0
  97. data/public/javascripts/wymeditor/iframe/default/lbl-h3.png +0 -0
  98. data/public/javascripts/wymeditor/iframe/default/lbl-h4.png +0 -0
  99. data/public/javascripts/wymeditor/iframe/default/lbl-h5.png +0 -0
  100. data/public/javascripts/wymeditor/iframe/default/lbl-h6.png +0 -0
  101. data/public/javascripts/wymeditor/iframe/default/lbl-p.png +0 -0
  102. data/public/javascripts/wymeditor/iframe/default/lbl-pre.png +0 -0
  103. data/public/javascripts/wymeditor/iframe/default/wymiframe.css +90 -0
  104. data/public/javascripts/wymeditor/iframe/default/wymiframe.html +26 -0
  105. data/public/javascripts/wymeditor/jquery.wymeditor.js +4688 -0
  106. data/public/javascripts/wymeditor/jquery.wymeditor.min.js +1 -0
  107. data/public/javascripts/wymeditor/jquery.wymeditor.pack.js +1 -0
  108. data/public/javascripts/wymeditor/lang/bg.js +45 -0
  109. data/public/javascripts/wymeditor/lang/ca.js +45 -0
  110. data/public/javascripts/wymeditor/lang/cs.js +45 -0
  111. data/public/javascripts/wymeditor/lang/cy.js +45 -0
  112. data/public/javascripts/wymeditor/lang/de.js +45 -0
  113. data/public/javascripts/wymeditor/lang/en.js +45 -0
  114. data/public/javascripts/wymeditor/lang/es.js +45 -0
  115. data/public/javascripts/wymeditor/lang/fa.js +46 -0
  116. data/public/javascripts/wymeditor/lang/fi.js +44 -0
  117. data/public/javascripts/wymeditor/lang/fr.js +45 -0
  118. data/public/javascripts/wymeditor/lang/gl.js +45 -0
  119. data/public/javascripts/wymeditor/lang/he.js +45 -0
  120. data/public/javascripts/wymeditor/lang/hr.js +45 -0
  121. data/public/javascripts/wymeditor/lang/hu.js +45 -0
  122. data/public/javascripts/wymeditor/lang/it.js +45 -0
  123. data/public/javascripts/wymeditor/lang/nb.js +45 -0
  124. data/public/javascripts/wymeditor/lang/nl.js +45 -0
  125. data/public/javascripts/wymeditor/lang/nn.js +45 -0
  126. data/public/javascripts/wymeditor/lang/pl.js +45 -0
  127. data/public/javascripts/wymeditor/lang/pt-br.js +45 -0
  128. data/public/javascripts/wymeditor/lang/pt.js +45 -0
  129. data/public/javascripts/wymeditor/lang/ru.js +45 -0
  130. data/public/javascripts/wymeditor/lang/sv.js +45 -0
  131. data/public/javascripts/wymeditor/lang/tr.js +45 -0
  132. data/public/javascripts/wymeditor/lang/zh_cn.js +47 -0
  133. data/public/javascripts/wymeditor/plugins/embed/jquery.wymeditor.embed.js +52 -0
  134. data/public/javascripts/wymeditor/plugins/fullscreen/icon_fullscreen.gif +0 -0
  135. data/public/javascripts/wymeditor/plugins/fullscreen/jquery.wymeditor.fullscreen.js +127 -0
  136. data/public/javascripts/wymeditor/plugins/hovertools/jquery.wymeditor.hovertools.js +57 -0
  137. data/public/javascripts/wymeditor/plugins/resizable/jquery.wymeditor.resizable.js +91 -0
  138. data/public/javascripts/wymeditor/plugins/resizable/readme.txt +124 -0
  139. data/public/javascripts/wymeditor/plugins/tidy/README +19 -0
  140. data/public/javascripts/wymeditor/plugins/tidy/jquery.wymeditor.tidy.js +82 -0
  141. data/public/javascripts/wymeditor/plugins/tidy/tidy.php +36 -0
  142. data/public/javascripts/wymeditor/plugins/tidy/wand.png +0 -0
  143. data/public/javascripts/wymeditor/skins/compact/icons.png +0 -0
  144. data/public/javascripts/wymeditor/skins/compact/skin.css +134 -0
  145. data/public/javascripts/wymeditor/skins/compact/skin.js +35 -0
  146. data/public/javascripts/wymeditor/skins/default/icons.png +0 -0
  147. data/public/javascripts/wymeditor/skins/default/skin.css +133 -0
  148. data/public/javascripts/wymeditor/skins/default/skin.js +40 -0
  149. data/public/javascripts/wymeditor/skins/minimal/images/bg.header.gif +0 -0
  150. data/public/javascripts/wymeditor/skins/minimal/images/bg.selector.silver.gif +0 -0
  151. data/public/javascripts/wymeditor/skins/minimal/images/bg.wymeditor.png +0 -0
  152. data/public/javascripts/wymeditor/skins/minimal/images/icons.silver.gif +0 -0
  153. data/public/javascripts/wymeditor/skins/minimal/skin.css +131 -0
  154. data/public/javascripts/wymeditor/skins/minimal/skin.js +30 -0
  155. data/public/javascripts/wymeditor/skins/silver/COPYING +674 -0
  156. data/public/javascripts/wymeditor/skins/silver/README +27 -0
  157. data/public/javascripts/wymeditor/skins/silver/images/bg.header.gif +0 -0
  158. data/public/javascripts/wymeditor/skins/silver/images/bg.selector.silver.gif +0 -0
  159. data/public/javascripts/wymeditor/skins/silver/images/bg.wymeditor.png +0 -0
  160. data/public/javascripts/wymeditor/skins/silver/images/icons.silver.gif +0 -0
  161. data/public/javascripts/wymeditor/skins/silver/skin.css +297 -0
  162. data/public/javascripts/wymeditor/skins/silver/skin.js +61 -0
  163. data/public/javascripts/wymeditor/skins/twopanels/icons.png +0 -0
  164. data/public/javascripts/wymeditor/skins/twopanels/skin.css +134 -0
  165. data/public/javascripts/wymeditor/skins/twopanels/skin.js +39 -0
  166. data/public/javascripts/wymeditor/skins/wymeditor_icon.png +0 -0
  167. data/public/javascripts/wymeditor.tar +0 -0
  168. data/public/robots.txt +5 -0
  169. data/public/stylesheets/comatose/admin.css +488 -0
  170. data/public/stylesheets/comatose/base.css +9 -0
  171. data/spec/controllers/comatose/base_controller_spec.rb +14 -0
  172. data/spec/controllers/foos_controller_spec.rb +5 -0
  173. data/spec/helpers/foos_helper_spec.rb +15 -0
  174. data/spec/routing/base_routing_spec.rb +12 -0
  175. data/spec/spec_helper.rb +27 -0
  176. data/test/behaviors.rb +106 -0
  177. data/test/fixtures/comatose_pages.yml +96 -0
  178. data/test/functional/comatose_admin_controller_test.rb +114 -0
  179. data/test/functional/comatose_controller_test.rb +45 -0
  180. data/test/integration/comatose_routing_test.rb +17 -0
  181. data/test/javascripts/test.html +26 -0
  182. data/test/javascripts/test_runner.js +307 -0
  183. data/test/old_test_helper.rb +43 -0
  184. data/test/performance/browsing_test.rb +9 -0
  185. data/test/test_helper.rb +13 -0
  186. data/test/unit/class_options_test.rb +52 -0
  187. data/test/unit/comatose_page_test.rb +128 -0
  188. data/test/unit/processing_context_test.rb +108 -0
  189. data/test/unit/text_filters_test.rb +52 -0
  190. data.tar.gz.sig +1 -0
  191. metadata +379 -0
  192. metadata.gz.sig +0 -0
data/README.markdown ADDED
@@ -0,0 +1,113 @@
1
+ # Comatose
2
+
3
+ * Version: 3.0.0 (beta)
4
+ * Author: Bryan Taylor (originally written by Matt McCray)
5
+ * Website: github.com/rubyisbeautiful/comatose
6
+ * Email: artofobjects at gmail dot com
7
+
8
+
9
+ *Comatose* is a micro CMS designed for being embedded into existing Rails
10
+ applications.
11
+
12
+ It's intended for simple CMS support. Comatose supports
13
+
14
+ * Nested pages
15
+ * Versioning
16
+ * Page markup in Textile, Markdown, RDoc, or easily add your own
17
+ * Page processing through Liquid or ERb
18
+ * Generators for easy installation/migration
19
+ * Self-contained gem containing a Rails::Engine
20
+ * Code Editor for mark, designed by scienco.de (http://blog.scienceco.de/2011/06/19/einfacher-javascript-code-editor/)
21
+
22
+ It's meant to be lean, mean, easily embedded, and easy to re-skin for
23
+ existing applications. If you need something more, I would recommend
24
+ looking into Radiant, Mephisto, Refinery, BrowserCMS, or Locomotive.
25
+
26
+ For more information, see the [Getting Started][] guide.
27
+
28
+ ### Requirements
29
+
30
+ * Rails 3.0.x (3.0.9)
31
+ * `acts_as_list-rails3`, `acts_as_tree_rails3`, and `liquid` gems are required (at the moment)
32
+
33
+
34
+ ### Development Notes
35
+
36
+ *NOTE*: This is a port of Comatose, which was last maintained in 2008. This
37
+ branch of Comatose is built specifically for Rails 3.
38
+ There is no legacy support.
39
+
40
+ * Make comatose fully self-contained, which means removing `acts_as_(tree|list)`
41
+ * Improve `ComatoseAdminController` to reduce number of DB calls for building the page tree
42
+ * `Comatose.configure` needs to be an initializer (update docs)
43
+ * Give access to all the default rails helpers to Comatose Pages by default?
44
+ * UI refresh (nothing major, just some cleanup).
45
+ * RESTful goodness.
46
+ * Support XML/JSON responses from `ComatoseController` and `ComatoseAdminController`.
47
+ * Support for static rendering (for generating sites like this blog).
48
+
49
+ ### Installation
50
+
51
+ *Note*: See the 'Upgrading' section if you already have an older version of
52
+ the comatose plugin installed.
53
+
54
+ $ gem install comatose
55
+ $ rails generate comatose
56
+ $ rake db:migrate
57
+ $ rails server
58
+
59
+ Open your `routes.rb` and add the following:
60
+
61
+ routes_for_comatose
62
+
63
+ That's it, you're ready to go! You should be able to browse to
64
+ http://127.0.0.1:3000/en/comatose and start adding pages to your CMS.
65
+ Browsing to http://127.0.0.1:3000/en will render your comatose pages if
66
+ routing doesn't match any of your controllers.
67
+
68
+
69
+ ### Configuration
70
+
71
+ You configure Comatose in your `config/intializers/comatose.rb` file. Here is an example
72
+ configuration block:
73
+
74
+ Comatose.configure do |config|
75
+ # Sets the text in the Admin UI's title area
76
+ config.admin_title = "Site Content"
77
+ config.admin_sub_title = "Content for the rest of us..."
78
+ end
79
+
80
+
81
+ ### Extra Credit
82
+
83
+ This gem is based on the work of Matt McCray, and other original Comatose contributers,
84
+ as well as the following individuals, to whom Matt gave credit in the original README.markdown.
85
+ Following are the specific libraries that are distributed with Comatose. If I've
86
+ missed someone/something please let me know.
87
+
88
+ * [Liquid][] by [Tobias Luetke][]
89
+ * [RedCloth][] by [_why][]
90
+ * [Acts as Versioned][] by [Rick Olsen][]
91
+ * [Behaviors][] by Atomic Object LLC -- very nice BDD-like testing library
92
+
93
+ ### Feedback
94
+
95
+ I’ve released Comatose under the MIT license. Which basically means you
96
+ can use it however you want.
97
+
98
+ Don't forget to read the [Getting Started][] guide located on the RubyForge
99
+ project site.
100
+
101
+ If you like it, hate it, or have some ideas for new features, let me know!
102
+
103
+ artofobjects at gmail dot com
104
+
105
+
106
+ [Getting Started]: http://github.com/rubyisbeautiful/comatose
107
+ [Liquid]: http://home.leetsoft.com/liquid
108
+ [Tobias Luetke]: http://blog.leetsoft.com
109
+ [RedCloth]: http://whytheluckystiff.net/ruby/redcloth
110
+ [_why]: http://whytheluckystiff.net
111
+ [Acts as Versioned]: http://ar-versioned.rubyforge.org
112
+ [Rick Olsen]: http://weblog.techno-weenie.net
113
+ [Behaviors]: http://behaviors.rubyforge.org
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ require 'rake'
2
+ require 'rails/all'
3
+ require File.expand_path('../lib/comatose/engine.rb', __FILE__)
4
+
5
+ Comatose::Engine.load_tasks
data/SPECS ADDED
@@ -0,0 +1,61 @@
1
+ Comatose Admin Controller should:
2
+ - show the index action
3
+ - show the new action
4
+ - successfully create pages
5
+ - create a page with an empty body
6
+ - not create a page with a missing title
7
+ - not create a page associated to an invalid parent
8
+ - contain all the correct options for filter_type
9
+ - show the edit action
10
+ - update pages with valid data
11
+ - not update pages with invalid data
12
+ - delete a page
13
+ - reorder pages
14
+ - set runtime mode
15
+
16
+ Comatose Controller should:
17
+ - show pages based on path_info
18
+
19
+ Class Options should:
20
+ - allow nil as a default
21
+ - allow boolean defaults
22
+ - allow string defaults
23
+ - allow numeric defaults
24
+ - allow symbolic defaults
25
+ - allow array literals as defaults
26
+ - allow hash literals as defaults
27
+
28
+ Comatose Page should:
29
+ - create page
30
+ - create a new version of an updated page
31
+ - render content through textile and liquid processors
32
+ - not allow creation of page when missing a title
33
+ - have good fixtures for this to work out
34
+ - generate slugs correctly
35
+ - generate page paths correctly
36
+ - update page paths when pages are moved
37
+ - set an AR error with processor syntax error info
38
+ - render body text accurately
39
+ - render data from parameterized calls too
40
+ - render data from a Drop
41
+
42
+ Processing Context should:
43
+ - process liquid tags with no filters correctly
44
+ - process erb tags correctly
45
+ - support text translation and processing with ERB
46
+ - support text translation and processing with Liquid
47
+ - allow access to safe properties and methods when processing with ERB
48
+ - prevent access to protected properties and methods when processing with ERB
49
+ - allow access to safe properties and methods when processing with Liquid
50
+ - prevent access to protected properties and methods when processing with Liquid
51
+ - allow referenceing of defined ComatoseDrops
52
+ - let ComatoseDrop errors bubble upward
53
+
54
+ Text Filters should:
55
+ - not alter output when using filter :none
56
+ - convert newlines into <br/>s when using :simple filter
57
+ - support Textile, if it's available, using :textile or 'Textile' as a key
58
+ - support Markdown, if it's available, using :markdown or 'Markdown' as a key
59
+ - support RDoc, if it's available, using :rdoc or 'RDoc' as a key
60
+ - support transformation of parameters via ERB
61
+ - support transformation of parameters via Liquid
@@ -0,0 +1,3 @@
1
+ class ApplicationController < ActionController::Base
2
+ protect_from_forgery
3
+ end
@@ -0,0 +1,425 @@
1
+ module Comatose
2
+ class AdminController < Comatose::ApplicationController
3
+ unloadable
4
+
5
+ define_option :original_template_root, nil
6
+ define_option :plugin_layout_path, File.join( '..', '..', '..', 'vendor', 'plugins', 'comatose', 'views', 'layouts' )
7
+
8
+ before_filter :handle_authorization
9
+ before_filter :set_content_type
10
+ layout 'comatose/admin'
11
+
12
+ # Shows the page tree
13
+ def index
14
+ @root_pages = [fetch_root_page].flatten
15
+ Comatose.logger.debug "current_user: #{current_user}"
16
+ end
17
+
18
+ # Edit a specific page
19
+ def edit
20
+ # Clear the page cache for this page... ?
21
+ @page = Page.find params[:id]
22
+ @root_pages = [fetch_root_page].flatten
23
+ end
24
+
25
+
26
+ def update
27
+ @page = Page.find params[:id]
28
+ @root_pages = [fetch_root_page].flatten
29
+
30
+ @page.update_attributes(params[:page].merge(:author => fetch_author_name))
31
+ Comatose.logger.debug "Saved #{@page}"
32
+ expire_cms_page @page
33
+ expire_cms_fragment @page
34
+ flash[:notice] = "Saved changes to '#{@page.title}'"
35
+ redirect_to comatose_pages_path and return false
36
+ rescue => e
37
+ Comatose.logger.info e.message
38
+ Comatose.logger.debug e.backtrace
39
+ end
40
+
41
+ # Create a new page (posts back)
42
+ def new
43
+ @root_pages = [fetch_root_page].flatten
44
+ @page = Page.new :title=>'New Page', :parent_id => params[:parent]
45
+ end
46
+
47
+
48
+ def create
49
+ @root_pages = [fetch_root_page].flatten
50
+ @page = Page.new params[:page]
51
+ @page.author = fetch_author_name
52
+ if @page.save
53
+ flash[:notice] = "Created page '#{@page.title}'"
54
+ redirect_to comatose_pages_path
55
+ end
56
+ end
57
+
58
+ # Saves position of child pages
59
+ def reorder
60
+ # If it's AJAX, do our thing and move on...
61
+ if request.xhr?
62
+ params["page_list_#{params[:id]}"].each_with_index { |id,idx| Page.update(id, :position => idx) }
63
+ expire_cms_page Page.find(params[:id])
64
+ render :text=>'Updated sort order', :layout=>false
65
+ else
66
+ @page = Page.find params[:id]
67
+ if params.has_key? :cmd
68
+ @target = Page.find params[:page]
69
+ case params[:cmd]
70
+ when 'up' then @target.move_higher
71
+ when 'down' then @target.move_lower
72
+ end
73
+ redirect_to :action=>'reorder', :id=>@page
74
+ end
75
+ end
76
+ end
77
+
78
+ # Allows comparing between two versions of a page's content
79
+ def versions
80
+ @page = Page.find params[:id]
81
+ @version_num = (params[:version] || @page.versions.length).to_i
82
+ @version = @page.find_version(@version_num)
83
+ end
84
+
85
+ # Reverts a page to a specific version...
86
+ def set_version
87
+ if request.post?
88
+ @page = Page.find params[:id]
89
+ @version_num = params[:version]
90
+ @page.revert_to!(@version_num)
91
+ end
92
+ redirect_to :controller=>self.controller_name, :action=>'index'
93
+ end
94
+
95
+ # Deletes the specified page
96
+ def delete
97
+ @page = Page.find params[:id]
98
+ if request.post?
99
+ expire_cms_pages_from_bottom @page
100
+ expire_cms_fragments_from_bottom @page
101
+ @page.destroy
102
+ flash[:notice] = "Deleted page '#{@page.title}'"
103
+ redirect_to :controller=>self.controller_name, :action=>'index'
104
+ end
105
+ end
106
+
107
+ # Returns a preview of the page content...
108
+ def preview
109
+ begin
110
+ page = Page.new(params[:page])
111
+ page.author = fetch_author_name
112
+ if params.has_key? :version
113
+ content = page.to_html( {'params'=>params.stringify_keys, 'version'=>params[:version]} )
114
+ else
115
+ content = page.to_html( {'params'=>params.stringify_keys} )
116
+ end
117
+ rescue SyntaxError
118
+ content = "<p>There was an error generating the preview.</p><p><pre>#{$!.to_s.gsub(/\</, '&lt;')}</pre></p>"
119
+ rescue
120
+ content = "<p>There was an error generating the preview.</p><p><pre>#{$!.to_s.gsub(/\</, '&lt;')}</pre></p>"
121
+ end
122
+ render :text=>content, :layout => false
123
+ end
124
+
125
+ # Expires the entire page cache
126
+ def expire_page_cache
127
+ expire_cms_pages_from_bottom( fetch_root_page )
128
+ expire_cms_fragments_from_bottom( fetch_root_page )
129
+ flash[:notice] = "Page cache has been flushed"
130
+ redirect_to :controller=>self.controller_name, :action=>'index'
131
+ end
132
+
133
+ # Walks the page tree and generates HTML files in your /public
134
+ # folder... It will skip pages that have a 'nocache' keyword
135
+ # TODO: Make page cache generation work when in :plugin mode
136
+ def generate_page_cache
137
+ if runtime_mode == :plugin
138
+ @errors = ["Page cache cannot be generated in plugin mode"]
139
+ else
140
+ @errors = generate_all_pages_html(params)
141
+ end
142
+ if @errors.length == 0
143
+ flash[:notice] = "Pages Cached Successfully"
144
+ else
145
+ flash[:notice] = "Pages Cache Error(s): #{@errors.join(', ')}"
146
+ flash[:cache_errors] = @errors
147
+ end
148
+ redirect_to :controller=>self.controller_name, :action=>'index'
149
+ end
150
+
151
+ def export
152
+ if Comatose.config.allow_import_export
153
+ send_data(page_to_hash(Page.root).to_yaml, :disposition => 'attachment', :type => 'text/yaml', :filename => "comatose-pages.yml")
154
+ else
155
+ flash[:notice] = "Export is not allowed"
156
+ redirect_to :controller=>self.controller_name, :action=>'index'
157
+ end
158
+ end
159
+
160
+ def import
161
+ if Comatose.config.allow_import_export
162
+ data = YAML::load(params[:import_file])
163
+ hash_to_page_tree(data, Page.root)
164
+ flash[:notice] = "Pages Imported Successfully"
165
+ else
166
+ flash[:notice] = "Import isn't allowed"
167
+ end
168
+ redirect_to :controller=>self.controller_name, :action=>'index'
169
+ end
170
+
171
+ protected
172
+
173
+ def handle_authorization
174
+ Comatose.logger.debug Comatose.config.admin_authorization.to_s
175
+ case Comatose.config.admin_authorization
176
+ when Proc
177
+ instance_eval &Comatose.config.admin_authorization
178
+ when Symbol
179
+ send(Comatose.config.admin_authorization)
180
+ when NilClass
181
+ @_current_user = "placeholder"
182
+ return true
183
+ when Module
184
+ else
185
+ if defined? authorize
186
+ authorize
187
+ else
188
+ @_current_user = "placeholder"
189
+ return true
190
+ end
191
+ end
192
+ end
193
+
194
+
195
+ def fetch_author_name
196
+ if Comatose.config.admin_get_author.is_a? Proc
197
+ instance_eval &Comatose.config.admin_get_author
198
+ elsif Comatose.config.admin_get_author.is_a? Symbol
199
+ send(Comatose.config.admin_get_author)
200
+ elsif defined? get_author
201
+ get_author
202
+ end
203
+ end
204
+
205
+
206
+ # Can be overridden -- return your root comtase page
207
+ def fetch_root_page
208
+ if Comatose.config.admin_get_root_page.is_a? Proc
209
+ instance_eval &Comatose.config.admin_get_root_page
210
+ elsif Comatose.config.admin_get_root_page.is_a? Symbol
211
+ send(Comatose.config.admin_get_root_page)
212
+ elsif defined? get_root_page
213
+ get_root_page
214
+ end
215
+ end
216
+
217
+ def get_root_page
218
+ Page.find(:first, :conditions => { :parent_id => nil })
219
+ end
220
+
221
+ # Sets the HTTP content-type header based on what's configured
222
+ # in Comatose.config.content_type
223
+ def set_content_type
224
+ response.headers["Content-Type"] = "text/html; charset=#{Comatose.config.content_type}" unless Comatose.config.content_type.nil?
225
+ end
226
+
227
+ # Calls generate_page_html for each mount point..
228
+ def generate_all_pages_html(params={})
229
+ @errors = []
230
+ @been_cached = []
231
+ Comatose.mount_points.each do |root_info|
232
+ Page.active_mount_info = root_info
233
+ generate_page_html(Page.find_by_path( root_info[:index] ), root_info, params)
234
+ end
235
+ @errors
236
+ end
237
+
238
+ # Accepts a Comatose Page and a root_info object to generate
239
+ # the page as a static HTML page -- using the layout that was
240
+ # defined on the mount point
241
+ def generate_page_html(page, root_info, params={})
242
+ @been_cached ||= []
243
+ unless page.has_keyword? :nocache or @been_cached.include? page.id
244
+ uri = page.uri
245
+ uri = "#{uri}/index".split('/').flatten.join('/') if page.full_path == root_info[:index]
246
+ @page = Comatose::PageWrapper.new(page)
247
+ begin
248
+ page_layout = get_page_layout(root_info)
249
+ #puts "mode = #{runtime_mode}, layout = #{page_layout}, template_root = #{template_root}, original_template_root = #{original_template_root}"
250
+ html = render_to_string( :text=>page.to_html({'params'=>params.stringify_keys}), :layout=>page_layout )
251
+ cache_page( html, uri )
252
+ rescue
253
+ logger.error "Comatose CMS Page Cache Exception: #{$!}"
254
+ @errors << "(#{page}/#{page.slug}) - #{$!}"
255
+ end
256
+ @been_cached << page.id
257
+ # recurse...
258
+ page.children.each do |child|
259
+ generate_page_html(child, root_info)
260
+ end
261
+ end
262
+ end
263
+
264
+ # Calls the class methods of the same name...
265
+ def expire_cms_page(page)
266
+ self.class.expire_cms_page(page)
267
+ end
268
+ def expire_cms_pages_from_bottom(page)
269
+ self.class.expire_cms_pages_from_bottom(page)
270
+ end
271
+
272
+
273
+ # expire the page from the fragment cache
274
+ def expire_cms_fragment(page)
275
+ key = page.full_path.gsub(/\//, '+')
276
+ expire_fragment(key)
277
+ end
278
+
279
+ # expire pages starting at a specific node
280
+ def expire_cms_fragments_from_bottom(page)
281
+ pages = page.is_a?(Array) ? page : [page]
282
+ pages.each do |page|
283
+ page.children.each {|c| expire_cms_fragments_from_bottom( c ) } if !page.children.empty?
284
+ expire_cms_fragment( page )
285
+ end
286
+ end
287
+
288
+ # Class Methods...
289
+ class << self
290
+
291
+
292
+ # Walks all the way down, and back up the tree -- the allows the expire_cms_page
293
+ # to delete empty directories better
294
+ def expire_cms_pages_from_bottom(page)
295
+ pages = page.is_a?(Array) ? page : [page]
296
+ pages.each do |page|
297
+ page.children.each {|c| expire_cms_pages_from_bottom( c ) } if !page.children.empty?
298
+ expire_cms_page( page )
299
+ end
300
+ end
301
+
302
+ # Expire the page from all the mount points...
303
+ def expire_cms_page(page)
304
+ Comatose.mount_points.each do |path_info|
305
+ Page.active_mount_info = path_info
306
+ expire_page(page.uri)
307
+ # If the page is the index page for the root, expire it too
308
+ if path_info[:root] == page.uri
309
+ expire_page("#{path_info[:root]}/index")
310
+ end
311
+ begin # I'm not sure this matters too much -- but it keeps things clean
312
+ dir_path = File.join(Rails.root, 'public', page.uri[1..-1])
313
+ Dir.delete( dir_path ) if FileTest.directory?( dir_path ) and !page.parent.nil?
314
+ rescue
315
+ # It probably isn't empty -- just as well we leave it be
316
+ #STDERR.puts " - Couldn't delete dir #{dir_path} -> #{$!}"
317
+ end
318
+ end
319
+ end
320
+
321
+ # Returns a path to plugin layout, if it's unspecified, otherwise
322
+ # a path to an application layout...
323
+ def get_page_layout(params)
324
+ if params[:layout] == 'comatose_content'
325
+ File.join(plugin_layout_path, params[:layout])
326
+ else
327
+ params[:layout]
328
+ end
329
+ end
330
+
331
+ def configure_template_root
332
+ if self.runtime_mode == :unknown
333
+ if FileTest.exist? File.join(Rails.root, 'public', 'javascripts', 'admin.js')
334
+ self.runtime_mode = :application
335
+ else
336
+ self.runtime_mode = :plugin
337
+ end
338
+ end
339
+ end
340
+
341
+ def runtime_mode
342
+ @@runtime_mode ||= :unknown
343
+ end
344
+
345
+ def runtime_mode=(mode)
346
+ admin_view_path = File.expand_path(File.join( File.dirname(__FILE__), '..', 'views'))
347
+ if self.respond_to?(:template_root)
348
+ case mode
349
+ when :plugin
350
+ self.original_template_root = self.template_root
351
+ self.template_root = admin_view_path
352
+ when :application
353
+ self.template_root = self.original_template_root if self.original_template_root
354
+ end
355
+ else
356
+ ActionController::Base.append_view_path(admin_view_path) unless ActionController::Base.view_paths.include?(admin_view_path)
357
+ end
358
+ @@runtime_mode = mode
359
+ end
360
+
361
+ end
362
+
363
+ # Check to see if we are in 'embedded' mode, or are being 'customized'
364
+ # embedded = runtime_mode of :plugin
365
+ # customized = runtime_mode of :application
366
+ configure_template_root
367
+
368
+ #
369
+ # Include any modules...
370
+ Comatose.config.admin_includes.each do |mod|
371
+ if mod.is_a? String
372
+ include mod.constantize
373
+ elsif mod.is_a? Symbol
374
+ include mod.to_s.classify.constantize
375
+ else
376
+ include mod
377
+ end
378
+ end
379
+
380
+ # Include any helpers...
381
+ Comatose.config.admin_helpers.each do |mod|
382
+ if mod.is_a? String
383
+ helper mod.constantize
384
+ elsif mod.is_a? Symbol
385
+ helper mod.to_s.classify.constantize
386
+ else
387
+ helper mod
388
+ end
389
+ end
390
+
391
+ private
392
+
393
+ def page_to_hash(page)
394
+ data = page.attributes.clone
395
+ # Pull out the specific, or unnecessary fields
396
+ %w(id parent_id updated_at author position version created_at full_path).each {|key| data.delete(key)}
397
+ if !page.children.empty?
398
+ data['children'] = []
399
+ page.children.each do |child|
400
+ data['children'] << page_to_hash(child)
401
+ end
402
+ end
403
+ data
404
+ end
405
+
406
+ def hash_to_page_tree(hsh, page=nil)
407
+ child_ary = hsh.delete 'children'
408
+
409
+ if page.blank?
410
+ page = Comatose::Page.create_root(hsh)
411
+ else
412
+ page.update_attributes(hsh)
413
+ end
414
+
415
+ child_ary.each do |child_hsh|
416
+ if child_pg = page.children.find_by_slug( child_hsh['slug'] )
417
+ hash_to_page_tree( child_hsh, child_pg )
418
+ else
419
+ hash_to_page_tree( child_hsh, page.children.create )
420
+ end
421
+ end if child_ary
422
+ end
423
+
424
+ end
425
+ end
@@ -0,0 +1,30 @@
1
+ module Comatose
2
+ class ApplicationController < ActionController::Base
3
+
4
+ before_filter :set_locale
5
+
6
+
7
+ def comatose_current_user
8
+ @_current_user
9
+ end
10
+
11
+
12
+ def set_locale
13
+ locale_language, locale_country = params[:locale].to_s.split('-')
14
+ locale_language ||= 'en'
15
+ locale_country ||= 'US'
16
+ locale_language.downcase.to_sym
17
+ locale_country.upcase!
18
+ I18n.locale = locale_language
19
+ logger.debug "Locale set to #{locale_language} from param #{params[:locale]}"
20
+ end
21
+
22
+
23
+ def find_page(*args)
24
+ Comatose::Page.send(Comatose.config.page_finder, *args)
25
+ end
26
+
27
+
28
+
29
+ end
30
+ end