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
@@ -0,0 +1,167 @@
1
+ module Comatose
2
+ class BaseController < Comatose::ApplicationController
3
+ unloadable
4
+
5
+ before_filter :set_content_type, :handle_authorization
6
+ after_filter :cache_cms_page
7
+
8
+ # Render a specific page
9
+ def show
10
+ page_name, page_ext = get_page_path
11
+ page = find_page(page_name, request)
12
+ status = nil
13
+ if page.nil?
14
+ status = 404
15
+ page = find_page('404')
16
+ end
17
+ # if it's still nil, well, send a 404 status
18
+ if page.nil?
19
+ render :nothing => true, :status => status
20
+ #raise ActiveRecord::RecordNotFound.new("Comatose page not found ")
21
+ else
22
+ # Make the page access 'safe'
23
+ system_hash = { 'current_user' => @current_user, 'view_context' => view_context }
24
+ @page = Comatose::PageWrapper.new(page, params.stringify_keys, system_hash)
25
+ @current_user = current_user
26
+ # For accurate uri creation, tell the page class which is the active mount point...
27
+ Page.active_mount_info = get_active_mount_point(params[:index])
28
+ rendered_text = page.to_comatose_html({
29
+ 'params' => params.stringify_keys,
30
+ 'system' => system_hash
31
+ })
32
+ render :text => rendered_text, :layout => get_page_layout, :status => status
33
+ end
34
+ end
35
+
36
+ protected
37
+
38
+ protected
39
+
40
+ def handle_authorization
41
+ case Comatose.config.authorization
42
+ when Proc
43
+ instance_eval &Comatose.config.authorization
44
+ when Symbol
45
+ send(Comatose.config.authorization)
46
+ when NilClass
47
+ @_current_user = "placeholder"
48
+ return true
49
+ when Module
50
+ else
51
+ if defined? authorize
52
+ authorize
53
+ else
54
+ @_current_user = "placeholder"
55
+ return true
56
+ end
57
+ end
58
+ end
59
+
60
+ def allow_page_cache?
61
+ # You should have access to the @page being rendered
62
+ true
63
+ end
64
+
65
+ # For use in the #show method... determines the current mount point
66
+ def get_active_mount_point(index)
67
+ #Comatose.logger.debug "active_mount_point: #index: #{index}"
68
+ Comatose.mount_points.each do |path_info|
69
+ if path_info[:index] == index
70
+ return path_info
71
+ end
72
+ end
73
+ {:root=>"", :index=>index}
74
+ end
75
+
76
+
77
+ def get_page_path
78
+ logger.debug "get_page_path: params[:page] class: #{params[:page].class }"
79
+
80
+ case params[:page]
81
+ when String
82
+ page_name = [params[:index], params[:page]].join("/")
83
+ when Array
84
+ page_name = params[:page].join("/")
85
+ when NilClass
86
+ page_name = ''
87
+ else
88
+ logger.debug "get_page_path - params[:page] is an unrecognized type, may cause problems: #{params[:page].class}"
89
+ page_name = params[:page].to_s
90
+ end
91
+
92
+ logger.debug "got page_name: #{page_name}"
93
+
94
+
95
+ page_ext = page_name.split('.')[1] unless page_name.empty?
96
+ # TODO: Automatic support for page RSS feeds... ????
97
+ if page_name.nil? or page_name.empty?
98
+ #Comatose.logger.debug "page_name is blank"
99
+ if params[:index].blank?
100
+ #Comatose.logger.debug "index is blank"
101
+ page_name = ''
102
+ else
103
+ page_name = params[:index]
104
+ params[:cache_path] = "#{request.fullpath}/index"
105
+ #page_name = "#{params[:index]}/#{page_name}"
106
+ Comatose.logger.debug "after index: got page_name: #{page_name}"
107
+ end
108
+ end
109
+ return page_name, page_ext
110
+ end
111
+
112
+ # Returns a path to plugin layout, if it's unspecified, otherwise
113
+ # a path to an application layout...
114
+ def get_page_layout
115
+ [params[:layout], @page.layout, 'comatose/base'].detect{ |shmerp| !shmerp.blank? }
116
+ end
117
+
118
+
119
+ # An after_filter implementing page caching if it's enabled, globally,
120
+ # and is allowed by #allow_page_cache?
121
+ def cache_cms_page
122
+ unless Comatose.config.disable_caching or response.headers['Status'] == '404 Not Found'
123
+ return unless params[:use_cache].to_s == 'true' and allow_page_cache?
124
+ path = params[:cache_path] || request.request_uri
125
+ begin
126
+ # TODO: Don't cache pages rendering '404' content...
127
+ self.class.cache_page( response.body, path )
128
+ rescue
129
+ logger.error "Comatose CMS Page Cache Exception: #{$!}"
130
+ end
131
+ end
132
+ end
133
+
134
+ # An after_filter that sets the HTTP header for Content-Type to
135
+ # what's defined in Comatose.config.content_type. Defaults to utf-8.
136
+ def set_content_type
137
+ response.headers["Content-Type"] = "text/html; charset=#{Comatose.config.content_type}" unless Comatose.config.content_type.nil? or response.headers['Status'] == '404 Not Found'
138
+ end
139
+
140
+ COMATOSE_VIEW_PATH = File.join(Rails.root.to_s, 'vendor', 'plugins', 'comatose', 'views')
141
+ ActionController::Base.append_view_path(COMATOSE_VIEW_PATH) unless ActionController::Base.view_paths.include?(COMATOSE_VIEW_PATH)
142
+
143
+ # Include any, well, includes...
144
+ Comatose.config.includes.each do |mod|
145
+ mod_klass = if mod.is_a? String
146
+ mod.constantize
147
+ elsif mod.is_a? Symbol
148
+ mod.to_s.classify.constantize
149
+ else
150
+ mod
151
+ end
152
+ include mod_klass
153
+ end
154
+
155
+ # Include any helpers...
156
+ Comatose.config.helpers.each do |mod|
157
+ mod_klass = if mod.is_a? String
158
+ mod.constantize
159
+ elsif mod.is_a? Symbol
160
+ mod.to_s.classify.constantize
161
+ else
162
+ mod
163
+ end
164
+ helper mod_klass
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,2 @@
1
+ module ApplicationHelper
2
+ end
@@ -0,0 +1,78 @@
1
+
2
+ module Comatose::AdminHelper
3
+
4
+ # TODO - broken
5
+ def comatose_admin_stylesheets(*names)
6
+ strings = []
7
+ names ||= ['comatose_admin']
8
+ names.each do |name|
9
+ Comatose.logger.debug("[**Comatose**]: stylesheet tag for: #{name}")
10
+ strings << stylesheet_link_tag(name)
11
+ end
12
+ strings.join("\n")
13
+ end
14
+
15
+
16
+ # TODO - broken
17
+ def comatose_admin_javascripts(*names)
18
+ strings = []
19
+ names ||= ['comatose_admin']
20
+ names.each do |name|
21
+ strings << javascript_include_tag(name)
22
+ end
23
+ strings
24
+ end
25
+
26
+
27
+ # Checks the hidden_meta_fields class variable for a specified field name...
28
+ def show_field?(key)
29
+ !Comatose.config.hidden_meta_fields.include? key
30
+ end
31
+
32
+
33
+ def select_from_node(nodes, selected=nil, hide=nil, html_options={})
34
+ html_options[:tabindex] ||= 9
35
+ html_options[:label] ||= "Parent"
36
+ html_options[:name] ||= "page[parent_id]"
37
+ html_options[:id] ||= "page_parent"
38
+ html_options[:blank] ||= false
39
+
40
+ options = options_for_select(collection_from_node_for_select(nodes, hide, html_options[:label], html_options[:blank]), selected)
41
+ select_tag html_options[:name], options, :id => html_options[:id], :tabindex => html_options[:tabindex]
42
+ end
43
+
44
+
45
+ # Used in the Page Form to build an indented drop-down list of pages
46
+ def collection_from_node_for_select(nodes, hide=nil, label="Parent", add_initial=false)
47
+ level = 0
48
+ options = []
49
+
50
+ if add_initial
51
+ options << ["No #{label}", 0]
52
+ end
53
+
54
+ nodes.each do |node|
55
+ collection_from_child_for_select(node, level, hide, options)
56
+ end
57
+ return options
58
+ end
59
+
60
+
61
+ # Called by collection_from_node_for_select
62
+ def collection_from_child_for_select(node, level, hide, options=[])
63
+ padding = " " * level * 4
64
+ padding += '* ' unless level == 0
65
+
66
+ hide_values = Array.new
67
+ hide_values << hide if hide
68
+
69
+ unless hide_values.include?(node.id)
70
+ options << ["#{padding}#{node.title}", node.id]
71
+ node.children.each do |child|
72
+ collection_from_child_for_select(child, level + 1, hide, options)
73
+ end
74
+ end
75
+ return options
76
+ end
77
+
78
+ end
@@ -0,0 +1,2 @@
1
+ module Comatose::ApplicationHelper
2
+ end
@@ -0,0 +1,5 @@
1
+ module Comatose
2
+ module BaseHelper
3
+
4
+ end
5
+ end
@@ -0,0 +1,166 @@
1
+ module Comatose
2
+ # Page attributes
3
+ # - parent_id
4
+ # - title
5
+ # - full_path
6
+ # - slug
7
+ # - keywords
8
+ # - layout
9
+ # - body
10
+ # - author
11
+ # - filter_type
12
+ # - position
13
+ # - version
14
+ # - updated_at
15
+ # - created_at
16
+ class Page < ActiveRecord::Base
17
+
18
+ set_table_name 'comatose_pages'
19
+
20
+ attr_accessor :new_root_page
21
+
22
+ # Only versions the content... Not all of the meta data or position
23
+ acts_as_versioned :table_name=>'comatose_page_versions', :if_changed => [:title, :slug, :keywords, :body]
24
+
25
+ define_option :active_mount_info, {:root=>'', :index=>''}
26
+
27
+ acts_as_tree :order => "position, title"
28
+ acts_as_list :scope => :parent_id
29
+
30
+ #before_create :create_full_path
31
+ before_save :cache_full_path, :create_full_path
32
+ after_save :update_children_full_path
33
+
34
+ # Using before_validation so we can default the slug from the title
35
+ before_validation do |record|
36
+ # Create slug from title
37
+ if record.slug.blank? and !record.title.blank?
38
+ record.slug = record.title.downcase.lstrip.rstrip.gsub( /[^-a-z0-9~\s\.:;+=_]/, '').gsub(/[\s\.:;=_+]+/, '-').gsub(/[\-]{2,}/, '-').to_s
39
+ end
40
+ end
41
+
42
+
43
+ validates_presence_of :title, :on => :save, :message => "must be present"
44
+ validates_uniqueness_of :slug, :on => :save, :scope=>'parent_id', :message => "is already in use"
45
+
46
+ validates :parent_id, :presence => true, :on => :create, :unless => :new_root_page
47
+
48
+
49
+ # Tests ERB/Liquid content...
50
+ validates_each :body, :allow_nil=>true, :allow_blank=>true do |record, attr, value|
51
+ begin
52
+ body_html = record.to_html
53
+ rescue SyntaxError => e
54
+ Comatose.logger.debug e.message
55
+ record.errors.add :body, "syntax error: #{$!.to_s.gsub('<', '&lt;')}"
56
+ rescue => e
57
+ Comatose.logger.debug e.message
58
+ record.errors.add :body, "content error: #{$!.to_s.gsub('<', '&lt;')}"
59
+ end
60
+ end
61
+
62
+
63
+ class <<self
64
+
65
+ def create_root(attrs)
66
+ Page.create(attrs)
67
+ end
68
+
69
+
70
+ def method_added(what)
71
+ Comatose.logger.debug "method added: #{what.to_s}"
72
+ end
73
+
74
+ end
75
+
76
+
77
+ # Returns a pages URI dynamically, based on the active mount point
78
+ def uri
79
+ if full_path == ''
80
+ active_mount_info[:root]
81
+ else
82
+ page_path = (full_path || '').split('/')
83
+ idx_path = active_mount_info[:index].split('/')
84
+ uri_root = active_mount_info[:root].split('/')
85
+ uri_path = ( uri_root + (page_path - idx_path) ).flatten.delete_if {|i| i == "" }
86
+ ['',uri_path].join('/')
87
+ end
88
+ end
89
+
90
+ # Check if a page has a selected keyword... NOT case sensitive.
91
+ # So the keyword McCray is the same as mccray
92
+ def has_keyword?(keyword)
93
+ @key_list ||= (self.keywords || '').downcase.split(',').map {|k| k.strip }
94
+ @key_list.include? keyword.to_s.downcase
95
+ rescue
96
+ false
97
+ end
98
+
99
+ # Returns the page's content, transformed and filtered...
100
+ def to_html(options={})
101
+ #version = options.delete(:version)
102
+ text = self.body
103
+ binding = Comatose::ProcessingContext.new(self, options)
104
+ filter_type = self.filter_type || '[No Filter]'
105
+ transformed_text = TextFilters.transform(text, binding, filter_type, Comatose.config.default_processor)
106
+ #Comatose.logger.debug "transformed_text: #{transformed_text}"
107
+ return transformed_text
108
+ end
109
+ alias :to_comatose_html :to_html
110
+
111
+
112
+ # Returns a Page with a matching path.
113
+ def self.find_by_path(path)
114
+ Comatose.logger.debug "looking for Page with path: #{path}"
115
+ if path.blank?
116
+ Comatose.logger.debug "could not find Page with path: #{path}"
117
+ else
118
+ path = path.split('.')[0] # Will ignore file extension...
119
+ if path.length > 1
120
+ path = path[1..-1] if path.starts_with? "/"
121
+ end
122
+ end
123
+ find( :first, :conditions=>[ 'full_path = ?', path ] )
124
+ end
125
+
126
+
127
+ protected
128
+
129
+ # Creates a URI path based on the Page tree
130
+ def create_full_path
131
+ if parent_node = self.parent
132
+ # Build URI Path
133
+ path = "#{parent_node.full_path}/#{self.slug}"
134
+ # strip leading space, if there is one...
135
+ path = path[1..-1] if path.starts_with? "/"
136
+ self.full_path = path || ""
137
+ else
138
+ # I'm the root -- My path is blank
139
+ self.full_path = ""
140
+ end
141
+ end
142
+
143
+
144
+ def create_full_path!
145
+ create_full_path
146
+ save
147
+ end
148
+
149
+
150
+ # Caches old path (before save) for comparison later
151
+ def cache_full_path
152
+ @old_full_path = self.full_path
153
+ end
154
+
155
+
156
+ # Updates all this content's child URI paths
157
+ def update_children_full_path(should_save=true)
158
+ # OPTIMIZE: Only update all the children if the :slug/:fullpath is different
159
+ for child in self.children
160
+ child.create_full_path! unless child.frozen?
161
+ child.update_children_full_path(should_save)
162
+ end
163
+ end
164
+ end
165
+ end
166
+
@@ -0,0 +1,108 @@
1
+ <%- # TODO error_messages_for :page %>
2
+
3
+ <% form_for @page, :as => :page do |f| %>
4
+ <table class="page-form" cellpadding="0" cellspacing="0">
5
+
6
+ <tr>
7
+ <td class="label"><label for="page_title">Title</label></td>
8
+ <td class="field"><%= f.text_field :title, :tabindex => 1, :maxlength => 255, :size => 50 %> <%= link_to_function "More...", "ComatoseEditForm.toggle_extra_fields(this)", :id => 'more-options' %></td>
9
+ </tr>
10
+
11
+ <tr id="slug_row" class="meta-info">
12
+ <td class="label"><label for="page_slug">Slug</label></td>
13
+ <td class="field"><%= f.text_field :slug, :tabindex => 6, :maxlength => 255, :size => 50, :disabled => @root_pages.include?(@page) %></td>
14
+ </tr>
15
+
16
+ <% if show_field? 'keywords' %>
17
+ <tr id="keywords_row" class="meta-info">
18
+ <td class="label"><label for="page_keywords">Keywords</label></td>
19
+ <td class="field"><%= f.text_field :keywords, :tabindex => 7, :maxlength => 1000, :size => 50 %></td>
20
+ </tr>
21
+ <% end %>
22
+
23
+ <% if show_field? 'layout' %>
24
+ <tr id="layout_row" class="meta-info">
25
+ <td class="label"><label for="page_layout">Layout</label></td>
26
+ <td class="field"><%= f.text_field :layout, :tabindex => 8, :maxlength => 1000, :size => 50 %></td>
27
+ </tr>
28
+ <% end %>
29
+
30
+
31
+ <% if show_field? 'parent' %>
32
+ <tr id="parent_row" class="meta-info">
33
+ <td class="label"><label for="page_parent">Parent</label></td>
34
+ <td class="field">
35
+ <% if mode != :new and @root_pages.include? @page %>
36
+ <select id="page_parent" disabled="true"><option><%= @page.title %> is a root page</option></select>
37
+ <% else %>
38
+ <%= select_from_node(@root_pages, @page.parent_id, @page.id, :tabindex => 9, :label => "Parent") %>
39
+ <% end %>
40
+ </td>
41
+ </tr>
42
+ <% end %>
43
+
44
+ <tr>
45
+ <td class="label body">
46
+ <label for="page_body">Body</label>
47
+ </td>
48
+ <td class="field">
49
+ <%= f.text_area :body, :rows => 20, :tabindex => 2, :wrap => "off", :nowrap => "nowrap", :spellcheck => "false", :indentwidth => 2, :class => 'comatose_editor' %>
50
+ </td>
51
+ </tr>
52
+
53
+ <% if show_field? 'filter' %>
54
+ <tr id="filter_row" class="meta-info">
55
+ <td class="label"><label for="page_filter_type">Filter</label></td>
56
+ <td class="field">
57
+ <%= select_tag 'page[filter_type]', options_for_select(Comatose::TextFilters.all_titles.sort, @page.filter_type || Comatose.config.default_filter), :tabindex => 3, :id => 'page_filter_type' %>
58
+ <span class="field-help">Converts plain text into html</span>
59
+ </td>
60
+ </tr>
61
+ <% end %>
62
+
63
+ <% if show_field? 'created_at' %>
64
+ <tr id="created_row" class="meta-info">
65
+ <td class="label"><label for="page_created_at">Created</label></td>
66
+ <td class="field">
67
+ <%= f.datetime_select :created_at %>
68
+ </td>
69
+ </tr>
70
+ <% end %>
71
+
72
+ </table>
73
+
74
+ <div id="button-group">
75
+ <% unless @page.updated_at.nil? %>
76
+ <div class="last-update">
77
+ <label>
78
+ Updated <%= time_ago_in_words @page.updated_at, true %> ago by
79
+ <%= @page.author %>.
80
+ <%= link_to_if(((@page.versions.length > 0) rescue false), pluralize(@page.versions.length, 'revision', 'revisions'), versions_comatose_page_path(@page, :locale => 'en')) %>
81
+ </label>
82
+ </div>
83
+ <% end %>
84
+ <%= image_tag 'comatose/spinner.gif', :id => 'spinner', :align => 'absmiddle', :style => 'display:none;' %>
85
+ <%- #= button_to_function('Preview', "ComatoseEditForm.preview_content('#{preview_comatose_page_path(@page, :locale => 'en')}')", :tabindex => 3, :id => 'preview-btn' ) if show_field? 'preview' %>
86
+ <%= submit_tag ((mode == :edit) ? 'Save Changes' : 'Create Page'), :tabindex => 10 %>
87
+ <% if @page.versions.length > 0 %>
88
+ <%= link_to "Revert", :action => 'versions', :id => @page %>
89
+ <% end %>
90
+ or
91
+ <a href="<%= comatose_pages_path %>" onlick="ComatoseEditForm.cancel(this.href); return false;" tabindex="5">Cancel</a>
92
+ </div>
93
+ <% end %>
94
+
95
+ <div id="preview-area">
96
+ <fieldset>
97
+ <legend>Page Preview</legend>
98
+ <div class="preview-body">
99
+ <div id="preview-panel"><span style='color:blue;'>Loading Preview...</span></div>
100
+ <div style="clear:both"></div>
101
+ </div>
102
+ </fieldset>
103
+ <div class="commands">
104
+ <a href="#" onclick="$('preview-area').hide();">Close Preview</a> or <a href="#">Back to top</a>
105
+ </div>
106
+ </div>
107
+
108
+ <%= javascript_tag "ComatoseEditForm.init('#{mode.to_s}');" %>
@@ -0,0 +1,62 @@
1
+ <%# Params:
2
+ # - page (Page Node)
3
+ # - level (integer indicating current tree depth)
4
+ # Called From:
5
+ # - index
6
+ # Description:
7
+ # This partial is used recursively. Render it with the root node, and it will recurse
8
+ # down all of the child nodes to build a list with proper indentation to indicate
9
+ # tree depth.
10
+ %>
11
+
12
+ <% collapse_children = (level >= Comatose.config.default_tree_level) %>
13
+
14
+
15
+ <li id="page_<%= page.id %>">
16
+ <table cellpadding="0" cellspacing="0">
17
+ <tr>
18
+ <td rowspan="2" valign="center">
19
+ <% if !page.children.empty? %>
20
+ <%= image_tag( ((collapse_children) ? 'comatose/collapsed.gif' : 'comatose/expanded.gif'), :title=>'Expand/Collapse', :onclick=>"ComatoseList.toggle_tree_nodes(this,#{page.id});", :class=>'tree-controller', :size=>'12x12', :id=>"page_controller_#{page.id}" ) %>
21
+ <% else %>
22
+ <%= image_tag 'comatose/no-children.gif', :size=>'12x12', :class=>'tree-controller' %>
23
+ <% end %>
24
+ </td>
25
+ <td rowspan="2" valign="center">
26
+ <%= image_tag 'comatose/page.gif', :size=>'25x31', :align=>"absmiddle" %>
27
+ <span class="handle">DRAG</span>
28
+ </td>
29
+ <td>
30
+ <%- # TODO %>
31
+ <%= link_to page.title, edit_comatose_page_path(page, :locale => 'en'), :class => 'page' %>
32
+ </td>
33
+ </tr>
34
+ <tr>
35
+ <td class="commands">
36
+ Updated
37
+ <span title="Created on <%= page.created_at %>">
38
+ <%= time_ago_in_words page.updated_at, true %> ago
39
+ </span>
40
+ <%= " by #{page.author}" unless page.author.blank? %>,
41
+ <%= link_to_if(((page.versions.length > 0) rescue false), pluralize(page.versions.length, 'revision', 'revisions'), versions_comatose_page_path(page, :locale => 'en')) %>
42
+ <%= link_to 'add child page', new_comatose_page_path(:parent => page, :title => "Add a child to '#{page.title}'", :locale => 'en'), :class => 'add-page' %>
43
+ <% if !page.children.empty? and page.children.length > 1 %>
44
+ <%= link_to_function 'reorder children', "ComatoseList.toggle_reorder('page_list_#{page.id}',this,#{page.id})", :title=>"Reorder children of '#{page.title}'", :class=>'reorder-children', :href=>url_for(:action=>'reorder', :id=>page) %>
45
+ <% end %>
46
+ <%= link_to_unless @root_pages.include?(page), 'delete', comatose_page_path(page, :locale => 'en', :method => :destroy), :confirm=>'This will delete this page, and any children. Are you sure?', :title=>"Delete page '#{page.title}' and all it's children", :class=>'delete-page', :method=>'post', :onmouseover=>"ComatoseList.item_hover('page_#{page.id}', 'over', true)", :onmouseout=>"ComatoseList.item_hover('page_#{page.id}', 'out', true)" %>
47
+ </td>
48
+ </tr>
49
+ </table>
50
+
51
+ <ul id="page_list_<%= page.id %>" old="lvl-<%= page.id %>" class="page-list <%= 'collapsed' if collapse_children %>" >
52
+ <% for child in page.children %>
53
+ <%= render :partial=>'page_list_item', :locals=>{ :page=>child, :level=>level+1 } %>
54
+ <% end %>
55
+ </ul>
56
+
57
+ <%= sortable_element( "page_list_#{page.id}",
58
+ :complete => visual_effect(:highlight, "page_list_#{page.id}"),
59
+ :handle=>'handle',
60
+ :update=>'flash-content',
61
+ :url => { :action => "reorder", :id=>page } ) if !page.children.empty? and page.children.length > 1 %>
62
+ </li>
@@ -0,0 +1,18 @@
1
+ <h1>
2
+ Page Delete Confirmation
3
+ </h1>
4
+
5
+ <blockquote>
6
+ <p>Are you sure you want to delete the page titled "<b><%= @page.title %></b>"?</p>
7
+ <% unless @page.children.empty? %>
8
+ <p>It has <b><%= @page.children.length %></b> child pages that will also be deleted...</p>
9
+ <% end %>
10
+ </blockquote>
11
+
12
+ <%= start_form_tag %>
13
+ <div id="button-group">
14
+ <%= submit_tag "Yes, Delete The Page" %>
15
+ or
16
+ <%= link_to "Cancel", :action=>'index' %>
17
+ </div>
18
+ <%= end_form_tag %>
@@ -0,0 +1,5 @@
1
+ <h1>
2
+ Edit Page
3
+ </h1>
4
+
5
+ <%= render :partial=>'form', :locals=>{:mode=>:edit} %>
@@ -0,0 +1,34 @@
1
+ <div class="action">
2
+ <%= link_to 'Clear Page Cache', expire_comatose_pages_path %>
3
+ <% if Comatose.config.allow_import_export %>
4
+ <%= link_to 'Import', '#', :id => 'import_link2', :onclick => "$('import_form').setStyle({display: 'inline'}); return false;" %>
5
+ <%= link_to 'Export', export_comatose_pages_path %>
6
+ <div id="import_form" style="display: none;">
7
+ <% form_tag(import_comatose_pages_path, :multipart => true) do %>
8
+ <%= file_field_tag 'import_file' %>
9
+ <%= submit_tag 'Upload and Import' %>
10
+ <a href="#" onclick="$('import_form').hide(); return false;">Cancel</a>
11
+ <% end %>
12
+ </div>
13
+ <% end %>
14
+ </div>
15
+
16
+ <div class="action">
17
+ <%= link_to 'New Page', new_comatose_page_path %>
18
+ </div>
19
+
20
+ <h1>
21
+ Page List
22
+ <%= image_tag 'comatose/spinner.gif', :id=>'spinner', :align=>'absmiddle', :style=>'display:none;' %>
23
+ </h1>
24
+
25
+
26
+ <ul class="page-list root">
27
+ <% @root_pages.each do |page| %>
28
+ <%= render :partial => 'page_list_item', :locals => { :page => page, :level => 1 } %>
29
+ <% end %>
30
+ </ul>
31
+
32
+ <div id="status"></div>
33
+
34
+ <%= javascript_tag "ComatoseList.init()" %>
@@ -0,0 +1,5 @@
1
+ <h1>
2
+ New Page
3
+ </h1>
4
+
5
+ <%= render :partial=>'form', :locals=>{:mode=>:new} %>