spontaneous 0.2.0.beta4 → 0.2.0.beta5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (205) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +39 -0
  3. data/Gemfile +11 -6
  4. data/Readme.markdown +136 -69
  5. data/application/css/core.css.scss +27 -7
  6. data/application/css/editing.css.scss +4 -26
  7. data/application/css/schema_error.css.scss +22 -0
  8. data/application/js/content.js +11 -3
  9. data/application/js/edit_panel.js +1 -4
  10. data/application/js/field/file.js +17 -0
  11. data/application/js/field/image.js +30 -21
  12. data/application/js/field/string.js +4 -1
  13. data/application/js/field_preview.js +21 -16
  14. data/application/js/publish.js +6 -6
  15. data/application/js/types.js +5 -13
  16. data/application/js/views.js +2 -2
  17. data/application/js/views/box_view.js +3 -2
  18. data/application/js/views/page_piece_view.js +1 -1
  19. data/application/js/views/piece_view.js +1 -1
  20. data/application/views/schema_modification_error.html.erb +13 -3
  21. data/db/migrations/20131104101935_site_must_publish_all.rb +14 -0
  22. data/lib/spontaneous.rb +0 -1
  23. data/lib/spontaneous/box_style.rb +15 -9
  24. data/lib/spontaneous/capistrano/deploy.rb +13 -1
  25. data/lib/spontaneous/change.rb +11 -13
  26. data/lib/spontaneous/cli.rb +5 -2
  27. data/lib/spontaneous/cli/assets.rb +7 -1
  28. data/lib/spontaneous/cli/console.rb +7 -1
  29. data/lib/spontaneous/cli/content.rb +35 -0
  30. data/lib/spontaneous/cli/fields.rb +3 -2
  31. data/lib/spontaneous/cli/generate.rb +5 -2
  32. data/lib/spontaneous/cli/server.rb +12 -8
  33. data/lib/spontaneous/cli/site.rb +12 -12
  34. data/lib/spontaneous/cli/user.rb +28 -14
  35. data/lib/spontaneous/collections/box_set.rb +4 -4
  36. data/lib/spontaneous/collections/field_set.rb +4 -4
  37. data/lib/spontaneous/collections/prototype_set.rb +12 -4
  38. data/lib/spontaneous/data_mapper.rb +11 -7
  39. data/lib/spontaneous/data_mapper/content_model.rb +8 -0
  40. data/lib/spontaneous/data_mapper/content_model/associations.rb +1 -1
  41. data/lib/spontaneous/data_mapper/dataset.rb +14 -2
  42. data/lib/spontaneous/data_mapper/scope.rb +33 -13
  43. data/lib/spontaneous/facet.rb +4 -0
  44. data/lib/spontaneous/field.rb +12 -12
  45. data/lib/spontaneous/field/base.rb +27 -22
  46. data/lib/spontaneous/field/boolean.rb +4 -4
  47. data/lib/spontaneous/field/date.rb +2 -2
  48. data/lib/spontaneous/field/file.rb +24 -18
  49. data/lib/spontaneous/field/html.rb +1 -1
  50. data/lib/spontaneous/field/image.rb +6 -19
  51. data/lib/spontaneous/field/location.rb +1 -1
  52. data/lib/spontaneous/field/long_string.rb +3 -3
  53. data/lib/spontaneous/field/markdown.rb +3 -3
  54. data/lib/spontaneous/field/select.rb +2 -2
  55. data/lib/spontaneous/field/string.rb +2 -2
  56. data/lib/spontaneous/field/tags.rb +2 -2
  57. data/lib/spontaneous/field/update.rb +21 -20
  58. data/lib/spontaneous/field/webvideo.rb +6 -6
  59. data/lib/spontaneous/field/webvideo/fallback.rb +2 -2
  60. data/lib/spontaneous/field/webvideo/vimeo.rb +7 -7
  61. data/lib/spontaneous/generators/site.rb +2 -2
  62. data/lib/spontaneous/generators/site/Gemfile.tt +5 -1
  63. data/lib/spontaneous/layout.rb +2 -2
  64. data/lib/spontaneous/media.rb +1 -0
  65. data/lib/spontaneous/media/file.rb +6 -5
  66. data/lib/spontaneous/media/image/attributes.rb +4 -0
  67. data/lib/spontaneous/media/image/renderable.rb +4 -4
  68. data/lib/spontaneous/media/store.rb +22 -0
  69. data/lib/spontaneous/{storage → media/store}/backend.rb +1 -1
  70. data/lib/spontaneous/{storage → media/store}/cloud.rb +1 -1
  71. data/lib/spontaneous/{storage → media/store}/local.rb +1 -1
  72. data/lib/spontaneous/media/temp_file.rb +1 -1
  73. data/lib/spontaneous/model.rb +10 -7
  74. data/lib/spontaneous/model/action.rb +7 -0
  75. data/lib/spontaneous/model/action/clean.rb +87 -0
  76. data/lib/spontaneous/model/box/allowed_types.rb +15 -1
  77. data/lib/spontaneous/model/core.rb +10 -0
  78. data/lib/spontaneous/model/core/aliases.rb +1 -1
  79. data/lib/spontaneous/model/core/content_groups.rb +1 -1
  80. data/lib/spontaneous/model/core/fields.rb +1 -1
  81. data/lib/spontaneous/model/core/modifications.rb +2 -2
  82. data/lib/spontaneous/model/core/page_search.rb +4 -0
  83. data/lib/spontaneous/model/core/publishing.rb +4 -17
  84. data/lib/spontaneous/model/core/render.rb +4 -4
  85. data/lib/spontaneous/model/core/styles.rb +2 -2
  86. data/lib/spontaneous/model/core/visibility.rb +6 -2
  87. data/lib/spontaneous/model/page.rb +6 -2
  88. data/lib/spontaneous/model/page/controllers.rb +55 -17
  89. data/lib/spontaneous/model/page/formats.rb +12 -7
  90. data/lib/spontaneous/model/page/layouts.rb +2 -2
  91. data/lib/spontaneous/model/page/locks.rb +4 -1
  92. data/lib/spontaneous/model/page/page_tree.rb +40 -6
  93. data/lib/spontaneous/output.rb +14 -52
  94. data/lib/spontaneous/output/context.rb +11 -39
  95. data/lib/spontaneous/output/context/navigation.rb +31 -0
  96. data/lib/spontaneous/output/format.rb +15 -19
  97. data/lib/spontaneous/output/renderable.rb +99 -0
  98. data/lib/spontaneous/output/store.rb +24 -0
  99. data/lib/spontaneous/output/store/backend.rb +52 -0
  100. data/lib/spontaneous/output/store/file.rb +77 -0
  101. data/lib/spontaneous/output/store/moneta.rb +117 -0
  102. data/lib/spontaneous/output/store/revision.rb +34 -0
  103. data/lib/spontaneous/output/store/store.rb +15 -0
  104. data/lib/spontaneous/output/store/transaction.rb +44 -0
  105. data/lib/spontaneous/output/template/engine.rb +17 -7
  106. data/lib/spontaneous/output/template/renderer.rb +66 -40
  107. data/lib/spontaneous/page_lock.rb +5 -7
  108. data/lib/spontaneous/page_piece.rb +2 -2
  109. data/lib/spontaneous/permissions/user.rb +14 -7
  110. data/lib/spontaneous/plugins/application/features.rb +8 -4
  111. data/lib/spontaneous/plugins/application/state.rb +12 -6
  112. data/lib/spontaneous/prototypes/box_prototype.rb +9 -10
  113. data/lib/spontaneous/prototypes/field_prototype.rb +66 -15
  114. data/lib/spontaneous/publishing/immediate.rb +30 -26
  115. data/lib/spontaneous/rack.rb +12 -7
  116. data/lib/spontaneous/rack/back.rb +43 -37
  117. data/lib/spontaneous/rack/back/base.rb +4 -4
  118. data/lib/spontaneous/rack/back/changes.rb +2 -2
  119. data/lib/spontaneous/rack/back/file.rb +16 -24
  120. data/lib/spontaneous/rack/back/map.rb +5 -5
  121. data/lib/spontaneous/rack/back/preview.rb +3 -4
  122. data/lib/spontaneous/rack/back/schema.rb +1 -1
  123. data/lib/spontaneous/rack/back/site.rb +6 -7
  124. data/lib/spontaneous/rack/front.rb +19 -16
  125. data/lib/spontaneous/rack/middleware/authenticate.rb +3 -3
  126. data/lib/spontaneous/rack/middleware/reloader.rb +3 -2
  127. data/lib/spontaneous/rack/middleware/scope.rb +25 -19
  128. data/lib/spontaneous/rack/page_controller.rb +164 -13
  129. data/lib/spontaneous/rack/public.rb +23 -62
  130. data/lib/spontaneous/rack/static.rb +2 -3
  131. data/lib/spontaneous/schema.rb +27 -8
  132. data/lib/spontaneous/schema/schema_modification.rb +9 -1
  133. data/lib/spontaneous/schema/uid.rb +2 -2
  134. data/lib/spontaneous/schema/uid_map.rb +3 -2
  135. data/lib/spontaneous/search/database.rb +2 -2
  136. data/lib/spontaneous/search/field.rb +5 -3
  137. data/lib/spontaneous/search/index.rb +12 -7
  138. data/lib/spontaneous/search/results.rb +5 -3
  139. data/lib/spontaneous/server.rb +2 -2
  140. data/lib/spontaneous/site.rb +10 -3
  141. data/lib/spontaneous/site/features.rb +26 -6
  142. data/lib/spontaneous/site/helpers.rb +9 -12
  143. data/lib/spontaneous/site/level.rb +7 -9
  144. data/lib/spontaneous/site/map.rb +9 -11
  145. data/lib/spontaneous/site/paths.rb +5 -5
  146. data/lib/spontaneous/site/publishing.rb +83 -80
  147. data/lib/spontaneous/site/schema.rb +1 -7
  148. data/lib/spontaneous/site/search.rb +8 -18
  149. data/lib/spontaneous/site/selectors.rb +60 -54
  150. data/lib/spontaneous/site/state.rb +36 -30
  151. data/lib/spontaneous/site/storage.rb +10 -16
  152. data/lib/spontaneous/state.rb +8 -0
  153. data/lib/spontaneous/style.rb +32 -33
  154. data/lib/spontaneous/version.rb +1 -1
  155. data/spontaneous.gemspec +22 -21
  156. data/test/fixtures/public/templates/layouts/default.html.cut +1 -1
  157. data/test/fixtures/public/templates/layouts/default.pdf.cut +1 -1
  158. data/test/fixtures/public/templates/layouts/default.rss.cut +1 -1
  159. data/test/fixtures/search/config/indexes.rb +1 -1
  160. data/test/fixtures/serialisation/class_hash.yaml.erb +13 -1
  161. data/test/fixtures/serialisation/root_hash.yaml.erb +10 -0
  162. data/test/functional/test_application.rb +20 -24
  163. data/test/functional/test_back.rb +26 -27
  164. data/test/functional/test_cli.rb +146 -0
  165. data/test/functional/test_front.rb +287 -216
  166. data/test/functional/test_user_manager.rb +1 -1
  167. data/test/test_helper.rb +15 -11
  168. data/test/unit/test_alias.rb +32 -25
  169. data/test/unit/test_asset_bundler.rb +1 -1
  170. data/test/unit/test_assets.rb +34 -33
  171. data/test/unit/test_authentication.rb +1 -1
  172. data/test/unit/test_boxes.rb +16 -2
  173. data/test/unit/test_changesets.rb +23 -11
  174. data/test/unit/test_content.rb +15 -0
  175. data/test/unit/test_context.rb +139 -0
  176. data/test/unit/test_controllers.rb +374 -0
  177. data/test/{experimental → unit}/test_crypt.rb +0 -0
  178. data/test/unit/test_datamapper.rb +260 -237
  179. data/test/unit/test_datamapper_content.rb +42 -12
  180. data/test/{experimental → unit}/test_features.rb +85 -3
  181. data/test/unit/test_fields.rb +117 -42
  182. data/test/unit/test_formats.rb +11 -1
  183. data/test/unit/test_generators.rb +2 -2
  184. data/test/unit/test_helpers.rb +7 -8
  185. data/test/unit/test_images.rb +39 -2
  186. data/test/unit/test_layouts.rb +14 -12
  187. data/test/unit/test_media.rb +32 -23
  188. data/test/unit/test_output_store.rb +342 -0
  189. data/test/unit/test_page.rb +8 -1
  190. data/test/unit/test_permissions.rb +11 -7
  191. data/test/unit/test_plugins.rb +3 -3
  192. data/test/unit/test_prototype_set.rb +8 -1
  193. data/test/unit/test_publishing.rb +67 -54
  194. data/test/unit/test_render.rb +91 -38
  195. data/test/unit/test_revisions.rb +4 -4
  196. data/test/unit/test_schema.rb +109 -84
  197. data/test/unit/test_search.rb +42 -42
  198. data/test/unit/test_serialisation.rb +3 -2
  199. data/test/unit/test_site.rb +39 -27
  200. data/test/unit/test_storage.rb +9 -6
  201. data/test/unit/test_styles.rb +25 -32
  202. data/test/unit/test_templates.rb +8 -4
  203. metadata +89 -54
  204. data/lib/spontaneous/model/page/request.rb +0 -105
  205. data/lib/spontaneous/storage.rb +0 -22
@@ -84,7 +84,7 @@ module Spontaneous::Model::Core
84
84
  end
85
85
 
86
86
  def field_versions(field)
87
- Spontaneous::Field::FieldVersion.filter(:content_id => self.id, :field_sid => field.schema_id.to_s).order(:created_at.desc)
87
+ Spontaneous::Field::FieldVersion.filter(:content_id => self.id, :field_sid => field.schema_id.to_s).order(Sequel.desc(:created_at))
88
88
  end
89
89
 
90
90
  def save_field_versions
@@ -26,7 +26,7 @@ module Spontaneous::Model::Core
26
26
  end
27
27
 
28
28
  def dataset
29
- path_like = :ancestor_path.like("#{owner[:ancestor_path]}.#{owner.id}%")
29
+ path_like = Sequel.like(:ancestor_path, "#{owner[:ancestor_path]}.#{owner.id}%")
30
30
  owner.content_model.filter(path_like)
31
31
  end
32
32
 
@@ -76,7 +76,7 @@ module Spontaneous::Model::Core
76
76
  end
77
77
 
78
78
  def dataset
79
- path_like = :visibility_path.like("#{owner[:visibility_path]}.#{owner.id}%")
79
+ path_like = Sequel.like(:visibility_path, "#{owner[:visibility_path]}.#{owner.id}%")
80
80
  owner.content_model::Page.filter(path_like)
81
81
  end
82
82
  end
@@ -14,6 +14,10 @@ module Spontaneous::Model::Core
14
14
  path(Spontaneous::SLASH)
15
15
  end
16
16
 
17
+ def id(id)
18
+ first_visible("id:#{id}", :id => id)
19
+ end
20
+
17
21
  def uid(uid)
18
22
  first_visible("uid:#{uid}", :uid => uid)
19
23
  end
@@ -7,19 +7,6 @@ module Spontaneous::Model::Core
7
7
 
8
8
  module ClassMethods
9
9
 
10
- # def current_revision_table
11
- # revision_table(revision)
12
- # end
13
-
14
- # def base_table
15
- # mapper.base_table
16
- # end
17
-
18
- # make sure that the table name is always the correct revision
19
- # def simple_table
20
- # current_revision_table
21
- # end
22
-
23
10
  def revision_table(revision=nil)
24
11
  mapper.revision_table(revision)
25
12
  end
@@ -66,12 +53,12 @@ module Spontaneous::Model::Core
66
53
  mapper.editable!(&block)
67
54
  end
68
55
 
69
- def with_published(&block)
70
- scope(Spontaneous::Site.published_revision, true, &block)
56
+ def with_published(site, &block)
57
+ scope(site.published_revision, true, &block)
71
58
  end
72
59
 
73
- def with_published!(&block)
74
- scope!(Spontaneous::Site.published_revision, true, &block)
60
+ def with_published!(site, &block)
61
+ scope!(site.published_revision, true, &block)
75
62
  end
76
63
 
77
64
  def database
@@ -9,13 +9,13 @@ module Spontaneous::Model::Core
9
9
  raise "Cannot render content without enclosing page"
10
10
  end
11
11
 
12
- def render(format = :html, params = {}, *args)
12
+ def render(format = :html, params = {}, parent_context = nil)
13
13
  params, format = format, :html if format.is_a?(Hash)
14
- output(format).render(params, *args)
14
+ output(format).render(params, parent_context)
15
15
  end
16
16
 
17
- def render_using(renderer, format = :html, params = {}, *args)
18
- output(format).render_using(renderer, params, *args)
17
+ def render_using(renderer, format = :html, params = {}, parent_context = nil)
18
+ output(format).render_using(renderer, params, parent_context)
19
19
  end
20
20
  end
21
21
  end
@@ -108,8 +108,8 @@ module Spontaneous::Model::Core
108
108
  self.class.styles
109
109
  end
110
110
 
111
- def template(format = :html)
112
- style.template(format)
111
+ def template(format = :html, renderer = Spontaneous::Output.default_renderer)
112
+ style.template(format, renderer)
113
113
  end
114
114
  end
115
115
  end
@@ -104,7 +104,7 @@ module Spontaneous::Model::Core
104
104
  end
105
105
 
106
106
  def hide_descendents(visible)
107
- path_like = :visibility_path.like("#{self[:visibility_path]}.#{self.id}%")
107
+ path_like = Sequel.like(:visibility_path, "#{self[:visibility_path]}.#{self.id}%")
108
108
  origin = visible ? nil : self.id
109
109
  dataset = content_model.filter(path_like).filter(:hidden => visible)
110
110
  # if a child item has been made invisible *before* its parent then it exists
@@ -127,8 +127,12 @@ module Spontaneous::Model::Core
127
127
  end
128
128
 
129
129
  def visibility_ancestors
130
+ visibility_ancestor_ids.map { |id| content_model[id] }
131
+ end
132
+
133
+ def visibility_ancestor_ids
130
134
  return [] if visibility_path.blank?
131
- visibility_path.split(Spontaneous::VISIBILITY_PATH_SEP).map { |id| content_model[id] }
135
+ visibility_path.split(Spontaneous::VISIBILITY_PATH_SEP).map(&:to_i)
132
136
  end
133
137
 
134
138
  def recalculated_hidden
@@ -6,7 +6,6 @@ require "spontaneous/model/page/layouts"
6
6
  require "spontaneous/model/page/locks"
7
7
  require "spontaneous/model/page/page_tree"
8
8
  require "spontaneous/model/page/paths"
9
- require "spontaneous/model/page/request"
10
9
  require "spontaneous/model/page/site_map"
11
10
  require "spontaneous/model/page/site_timestamps"
12
11
 
@@ -20,7 +19,6 @@ module Spontaneous::Model
20
19
  include Layouts
21
20
  include PageTree
22
21
  include Paths
23
- include Request
24
22
  include SiteMap
25
23
  include SiteTimestamps
26
24
  include Locks
@@ -147,5 +145,11 @@ module Spontaneous::Model
147
145
  def inspecttion_values
148
146
  { :id => id, :uid => uid, :path => path }.merge(inspection_fields)
149
147
  end
148
+
149
+ # PagePieces are == to their target but we must enforce the reverse,
150
+ # that Pages are == to a PagePiece that encloses them
151
+ def eql?(obj)
152
+ super || (Spontaneous::PagePiece === obj && obj.target.eql?(self))
153
+ end
150
154
  end
151
155
  end
@@ -11,36 +11,74 @@ module Spontaneous::Model::Page
11
11
  @controllers ||= Spontaneous::Collections::PrototypeSet.new(supertype, :controllers)
12
12
  end
13
13
 
14
- def controller_base_class
15
- return ::PageController if defined?(::PageController)
16
- default_controller_base_class
17
- end
18
-
19
14
  def default_controller_base_class
20
15
  Spontaneous::Rack::PageController
21
16
  end
22
17
 
23
- def controller(namespace, base_class = controller_base_class, &block)
24
- controller_class_name = "#{namespace.to_s.camelize}Controller"
25
- controller_class = Class.new(base_class)
18
+ # Searches through the type heirarchy for the first defined controller
19
+ # if there isn't one for the given namespace it tries on the 'default'
20
+ # namespace
21
+ def controller_superclass(namespace, base_class)
22
+ return base_class unless base_class.nil?
23
+ return ::PageController if defined?(::PageController)
24
+ search = ancestors.select { |klass| klass.respond_to?(:controllers) }
25
+ controller_superclass = [namespace, :__nil__].uniq.flat_map { |n|
26
+ search.map { |type| type.controllers[n] }
27
+ }.compact.first
28
+ controller_superclass ||= default_controller_base_class
29
+ end
30
+
31
+ def controller(namespace = :__nil__, base_class = nil, &block)
32
+ namespace_name = (namespace == :__nil__ ? "Root" : namespace.to_s.camelize)
33
+ controller_class = Class.new(controller_superclass(namespace, base_class))
34
+ const_set("#{namespace_name}Controller", controller_class)# unless self.const_defined?(controller_class_name)
26
35
  controller_class.class_eval(&block) if block_given?
27
- self.const_set(controller_class_name, controller_class) unless self.const_defined?(controller_class_name)
28
- controllers[namespace.to_sym] = controller_class
36
+ controllers[namespace] = controller_class
37
+ end
38
+
39
+ METHOD_MAP = Hash[%w(GET PUT POST DELETE HEAD OPTIONS PATCH LINK UNLINK).map { |m| [m, m.downcase.to_sym] }].freeze
40
+
41
+ def normalize_method(method)
42
+ return method if method.is_a?(Symbol)
43
+ METHOD_MAP[method]
44
+ end
45
+
46
+ # Tests for existance of a request handler for a method
47
+ # Used by the publishing mechanism to determine which template bucket a
48
+ # published page should be placed in.
49
+ def dynamic?(method = :get)
50
+ method = normalize_method(method)
51
+ return true unless method == :get
52
+ controller = controllers[:__nil__]
53
+ controller and controller.dynamic?(method)
29
54
  end
30
55
  end # ClassMethods
31
56
 
32
57
  # InstanceMethods
33
58
 
59
+ def dynamic?(method = :get)
60
+ self.class.dynamic?(method)
61
+ end
62
+
34
63
  # resolve and call the relevant action handler and return the results to the controller
35
- def process_action(action_path, env, format)
36
- env = env.dup
37
- namespace, *p = action_path.split(S::Constants::SLASH)
38
- path = [S::Constants::EMPTY].concat(p).join(S::Constants::SLASH)
64
+ def process_action(site, action_path, env, format)
65
+ namespace, *parts = action_path.split(S::Constants::SLASH)
66
+ path = "/" << parts.join(S::Constants::SLASH)
39
67
  env[S::Constants::PATH_INFO] = path
68
+ run_controller(site, namespace, env, format)
69
+ end
70
+
71
+ def process_root_action(site, env, format)
72
+ env[S::Constants::PATH_INFO] = S::Constants::SLASH
73
+ run_controller(site, :__nil__, env, format)
74
+ end
75
+
76
+ def run_controller(site, namespace, env, format)
40
77
  controller_class = self.class.controllers[namespace.to_sym]
41
- return 404 unless controller_class
42
- app = controller_class.new(self, format)
43
- app.call(env)
78
+ return 404 if controller_class.nil?
79
+ app = controller_class.new(site, self, format)
80
+ status, headers, body = app.call(env)
81
+ [status, headers, body]
44
82
  end
45
83
 
46
84
  # generate an action URL of the form
@@ -55,10 +55,15 @@ module Spontaneous::Model::Page
55
55
  output_list.first
56
56
  end
57
57
 
58
- def provides_format?(format)
58
+ def provides_format?(format, instance = nil)
59
59
  return true if format.blank?
60
- format = format.to_s
61
- outputs.any? { |output| (output == format) or (output.name.to_s == format) }
60
+ format_name = format.to_s
61
+ case format
62
+ when Spontaneous::Output::Format
63
+ (instance.nil? || (format.page == instance)) && outputs.any? { |output| (output.to_sym == format.to_sym) }
64
+ else
65
+ outputs.any? { |output| output.name.to_s == format_name }
66
+ end
62
67
  end
63
68
 
64
69
  alias_method :provides_output?, :provides_format?
@@ -92,7 +97,7 @@ module Spontaneous::Model::Page
92
97
  end
93
98
 
94
99
  def provides_output?(format)
95
- self.class.provides_output?(format)
100
+ self.class.provides_output?(format, self)
96
101
  end
97
102
 
98
103
  def output(format, content = nil)
@@ -105,10 +110,10 @@ module Spontaneous::Model::Page
105
110
  self.class.mime_type(format)
106
111
  end
107
112
 
108
- def render(format=:html, params={}, *args)
109
- params, format = format, :html if format.is_a?(Hash)
113
+ def render(format = :html, locals = {}, parent_context = nil)
114
+ locals, format = format, :html if format.is_a?(Hash)
110
115
  output = output(format)
111
- output.render(params, *args)
116
+ output.render(locals, parent_context)
112
117
  end
113
118
  end # Formats
114
119
  end # Spontaneous::Plugins::Page
@@ -86,8 +86,8 @@ module Spontaneous::Model::Page
86
86
  self.class.find_named_layout(layout_name)
87
87
  end
88
88
 
89
- def template(format = :html)
90
- layout.template(format)
89
+ def template(format = :html, renderer = Spontaneous::Output::default_renderer)
90
+ layout.template(format, renderer)
91
91
  end
92
92
  end # Layouts
93
93
  end # Spontaneous::Plugins
@@ -5,7 +5,10 @@ module Spontaneous::Model::Page
5
5
  extend Spontaneous::Concern
6
6
 
7
7
  included do
8
- one_to_many :update_locks, :class => Spontaneous::PageLock, :key => :page_id
8
+ one_to_many :update_locks, class: Spontaneous::PageLock, key: :page_id
9
+
10
+ Spontaneous::PageLock.many_to_one :page, class: model, key: :page_id
11
+ Spontaneous::PageLock.many_to_one :content, class: model, key: :content_id
9
12
  end
10
13
 
11
14
  def locked_for_update?
@@ -15,18 +15,52 @@ module Spontaneous::Model::Page
15
15
  end
16
16
 
17
17
  # Returns a list of all the pages at a certain depth in the page tree for any page
18
- def at_depth(depth)
18
+ def at_depth(depth, opts = {})
19
19
  return root_at_depth(depth) if is_root?
20
20
  parent_depth = [0, depth - 1].max
21
- parent = ancestor(parent_depth)
22
- unordered_pages = parent.children
21
+ parent = ancestor(parent_depth)
23
22
  # This is made more complex because the #children method is unordered
24
23
  # whereas the actual page order must come from the boxes
25
- return unordered_pages if parent.boxes.empty?
26
- ordered_pages = []
24
+ return parent.children if parent.boxes.empty?
25
+
27
26
  # Iterate through the list of boxes and pull out of the
28
27
  # unordered page list each page that belongs to the current box
29
- parent.boxes.each do |box|
28
+ boxes = parent.boxes
29
+
30
+ filter_proc = filter_list = nil
31
+
32
+ if (filter_list = (opts.delete(:only) || opts.delete(:box) || opts.delete(:boxes)))
33
+ filter_proc = proc { |box| filter_list.include?(box._name) }
34
+ elsif (filter_list = opts.delete(:except))
35
+ filter_proc = proc { |box| !filter_list.include?(box._name) }
36
+ end
37
+
38
+ if filter_list && filter_proc
39
+ filter_list = Array(filter_list).map(&:to_sym)
40
+ boxes = boxes.select(&filter_proc)
41
+ end
42
+
43
+ ordered_pages = parent.ordered_pages(boxes)
44
+
45
+ filter_proc = filter_list = nil
46
+
47
+ if (filter_list = opts.delete(:include))
48
+ filter_proc = proc { |p| filter_list.include?(p.class) }
49
+ elsif (filter_list = opts.delete(:exclude))
50
+ filter_proc = proc { |p| !filter_list.include?(p.class) }
51
+ end
52
+
53
+ if filter_list && filter_proc
54
+ filter_list = Array(filter_list).map { |s| Class === s ? s : s.to_s.constantize }
55
+ ordered_pages = ordered_pages.select(&filter_proc)
56
+ end
57
+ ordered_pages
58
+ end
59
+
60
+ def ordered_pages(boxes)
61
+ unordered_pages = self.children
62
+ ordered_pages = []
63
+ boxes.each do |box|
30
64
  box_id = box.schema_id.to_s
31
65
  in_box, unordered_pages = unordered_pages.partition { |p| p.box_sid == box_id }
32
66
  ordered_pages.concat in_box.sort { |a, b| a.position <=> b.position }
@@ -52,37 +52,6 @@ module Spontaneous
52
52
  end
53
53
  end
54
54
 
55
- def self.output_path(revision, output, template_dynamic = false, request_method = "GET")
56
- output_path_with_root(revision_root(revision), revision, output, template_dynamic, request_method)
57
- end
58
-
59
- def self.output_path_with_root(root, revision, output, template_dynamic = false, request_method = "GET")
60
- segment = case
61
- when template_dynamic || output.dynamic?
62
- "dynamic"
63
- when output.page.dynamic?(request_method)
64
- "protected"
65
- else
66
- "static"
67
- end
68
- path = output.page.path
69
- dir = root / segment / path
70
- ext = output.extension(template_dynamic)
71
-
72
- file = "#{dir}#{ext}"
73
- file = dir / "/index#{ext}" if path == "/" # root is a special case, as always
74
- file
75
- end
76
-
77
- # TODO: Is this ever used? Delete it & see what breaks
78
- def self.revision_dir(revision=nil, root = nil)
79
- Spontaneous::Site.instance.revision_dir(revision, root)
80
- end
81
-
82
- def self.revision_root(revision)
83
- Spontaneous::Site.instance.revision_dir(revision)
84
- end
85
-
86
55
  def self.context_class
87
56
  Cutaneous::Context
88
57
  end
@@ -120,28 +89,19 @@ module Spontaneous
120
89
  Cutaneous::Engine
121
90
  end
122
91
 
123
- def self.renderer
124
- @renderer ||= default_renderer
125
- end
126
-
127
- def self.renderer=(renderer)
128
- @renderer = renderer
129
- end
130
-
131
- def self.default_renderer
132
- Template::Renderer.new
133
- end
134
-
135
- def self.published_renderer(revision = Spontaneous::State.published_revision)
136
- Template::PublishedRenderer.new(revision)
92
+ # Used in the console or any other place where we want to render
93
+ # content outside of the Rack applications or publishing
94
+ # system
95
+ def self.default_renderer(site = Spontaneous::Site.instance)
96
+ Template::Renderer.new(site)
137
97
  end
138
98
 
139
- def self.preview_renderer
140
- Template::PreviewRenderer.new
99
+ def self.published_renderer(site, revision = Spontaneous::State.published_revision)
100
+ Template::PublishedRenderer.new(site, revision)
141
101
  end
142
102
 
143
- def self.template_exists?(root, template, format)
144
- renderer.template_exists?(root, template, format)
103
+ def self.preview_renderer(site)
104
+ Template::PreviewRenderer.new(site)
145
105
  end
146
106
 
147
107
  def self.asset_url(file = nil)
@@ -152,9 +112,11 @@ module Spontaneous
152
112
  Spontaneous.revision_dir(revision) / asset_url
153
113
  end
154
114
 
155
- autoload :Template, "spontaneous/output/template"
156
- autoload :Context, "spontaneous/output/context"
157
- autoload :Helpers, "spontaneous/output/helpers"
115
+ autoload :Template, "spontaneous/output/template"
116
+ autoload :Context, "spontaneous/output/context"
117
+ autoload :Helpers, "spontaneous/output/helpers"
118
+ autoload :Renderable, "spontaneous/output/renderable"
119
+ autoload :Store, "spontaneous/output/store"
158
120
  end
159
121
  end
160
122