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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +39 -0
- data/Gemfile +11 -6
- data/Readme.markdown +136 -69
- data/application/css/core.css.scss +27 -7
- data/application/css/editing.css.scss +4 -26
- data/application/css/schema_error.css.scss +22 -0
- data/application/js/content.js +11 -3
- data/application/js/edit_panel.js +1 -4
- data/application/js/field/file.js +17 -0
- data/application/js/field/image.js +30 -21
- data/application/js/field/string.js +4 -1
- data/application/js/field_preview.js +21 -16
- data/application/js/publish.js +6 -6
- data/application/js/types.js +5 -13
- data/application/js/views.js +2 -2
- data/application/js/views/box_view.js +3 -2
- data/application/js/views/page_piece_view.js +1 -1
- data/application/js/views/piece_view.js +1 -1
- data/application/views/schema_modification_error.html.erb +13 -3
- data/db/migrations/20131104101935_site_must_publish_all.rb +14 -0
- data/lib/spontaneous.rb +0 -1
- data/lib/spontaneous/box_style.rb +15 -9
- data/lib/spontaneous/capistrano/deploy.rb +13 -1
- data/lib/spontaneous/change.rb +11 -13
- data/lib/spontaneous/cli.rb +5 -2
- data/lib/spontaneous/cli/assets.rb +7 -1
- data/lib/spontaneous/cli/console.rb +7 -1
- data/lib/spontaneous/cli/content.rb +35 -0
- data/lib/spontaneous/cli/fields.rb +3 -2
- data/lib/spontaneous/cli/generate.rb +5 -2
- data/lib/spontaneous/cli/server.rb +12 -8
- data/lib/spontaneous/cli/site.rb +12 -12
- data/lib/spontaneous/cli/user.rb +28 -14
- data/lib/spontaneous/collections/box_set.rb +4 -4
- data/lib/spontaneous/collections/field_set.rb +4 -4
- data/lib/spontaneous/collections/prototype_set.rb +12 -4
- data/lib/spontaneous/data_mapper.rb +11 -7
- data/lib/spontaneous/data_mapper/content_model.rb +8 -0
- data/lib/spontaneous/data_mapper/content_model/associations.rb +1 -1
- data/lib/spontaneous/data_mapper/dataset.rb +14 -2
- data/lib/spontaneous/data_mapper/scope.rb +33 -13
- data/lib/spontaneous/facet.rb +4 -0
- data/lib/spontaneous/field.rb +12 -12
- data/lib/spontaneous/field/base.rb +27 -22
- data/lib/spontaneous/field/boolean.rb +4 -4
- data/lib/spontaneous/field/date.rb +2 -2
- data/lib/spontaneous/field/file.rb +24 -18
- data/lib/spontaneous/field/html.rb +1 -1
- data/lib/spontaneous/field/image.rb +6 -19
- data/lib/spontaneous/field/location.rb +1 -1
- data/lib/spontaneous/field/long_string.rb +3 -3
- data/lib/spontaneous/field/markdown.rb +3 -3
- data/lib/spontaneous/field/select.rb +2 -2
- data/lib/spontaneous/field/string.rb +2 -2
- data/lib/spontaneous/field/tags.rb +2 -2
- data/lib/spontaneous/field/update.rb +21 -20
- data/lib/spontaneous/field/webvideo.rb +6 -6
- data/lib/spontaneous/field/webvideo/fallback.rb +2 -2
- data/lib/spontaneous/field/webvideo/vimeo.rb +7 -7
- data/lib/spontaneous/generators/site.rb +2 -2
- data/lib/spontaneous/generators/site/Gemfile.tt +5 -1
- data/lib/spontaneous/layout.rb +2 -2
- data/lib/spontaneous/media.rb +1 -0
- data/lib/spontaneous/media/file.rb +6 -5
- data/lib/spontaneous/media/image/attributes.rb +4 -0
- data/lib/spontaneous/media/image/renderable.rb +4 -4
- data/lib/spontaneous/media/store.rb +22 -0
- data/lib/spontaneous/{storage → media/store}/backend.rb +1 -1
- data/lib/spontaneous/{storage → media/store}/cloud.rb +1 -1
- data/lib/spontaneous/{storage → media/store}/local.rb +1 -1
- data/lib/spontaneous/media/temp_file.rb +1 -1
- data/lib/spontaneous/model.rb +10 -7
- data/lib/spontaneous/model/action.rb +7 -0
- data/lib/spontaneous/model/action/clean.rb +87 -0
- data/lib/spontaneous/model/box/allowed_types.rb +15 -1
- data/lib/spontaneous/model/core.rb +10 -0
- data/lib/spontaneous/model/core/aliases.rb +1 -1
- data/lib/spontaneous/model/core/content_groups.rb +1 -1
- data/lib/spontaneous/model/core/fields.rb +1 -1
- data/lib/spontaneous/model/core/modifications.rb +2 -2
- data/lib/spontaneous/model/core/page_search.rb +4 -0
- data/lib/spontaneous/model/core/publishing.rb +4 -17
- data/lib/spontaneous/model/core/render.rb +4 -4
- data/lib/spontaneous/model/core/styles.rb +2 -2
- data/lib/spontaneous/model/core/visibility.rb +6 -2
- data/lib/spontaneous/model/page.rb +6 -2
- data/lib/spontaneous/model/page/controllers.rb +55 -17
- data/lib/spontaneous/model/page/formats.rb +12 -7
- data/lib/spontaneous/model/page/layouts.rb +2 -2
- data/lib/spontaneous/model/page/locks.rb +4 -1
- data/lib/spontaneous/model/page/page_tree.rb +40 -6
- data/lib/spontaneous/output.rb +14 -52
- data/lib/spontaneous/output/context.rb +11 -39
- data/lib/spontaneous/output/context/navigation.rb +31 -0
- data/lib/spontaneous/output/format.rb +15 -19
- data/lib/spontaneous/output/renderable.rb +99 -0
- data/lib/spontaneous/output/store.rb +24 -0
- data/lib/spontaneous/output/store/backend.rb +52 -0
- data/lib/spontaneous/output/store/file.rb +77 -0
- data/lib/spontaneous/output/store/moneta.rb +117 -0
- data/lib/spontaneous/output/store/revision.rb +34 -0
- data/lib/spontaneous/output/store/store.rb +15 -0
- data/lib/spontaneous/output/store/transaction.rb +44 -0
- data/lib/spontaneous/output/template/engine.rb +17 -7
- data/lib/spontaneous/output/template/renderer.rb +66 -40
- data/lib/spontaneous/page_lock.rb +5 -7
- data/lib/spontaneous/page_piece.rb +2 -2
- data/lib/spontaneous/permissions/user.rb +14 -7
- data/lib/spontaneous/plugins/application/features.rb +8 -4
- data/lib/spontaneous/plugins/application/state.rb +12 -6
- data/lib/spontaneous/prototypes/box_prototype.rb +9 -10
- data/lib/spontaneous/prototypes/field_prototype.rb +66 -15
- data/lib/spontaneous/publishing/immediate.rb +30 -26
- data/lib/spontaneous/rack.rb +12 -7
- data/lib/spontaneous/rack/back.rb +43 -37
- data/lib/spontaneous/rack/back/base.rb +4 -4
- data/lib/spontaneous/rack/back/changes.rb +2 -2
- data/lib/spontaneous/rack/back/file.rb +16 -24
- data/lib/spontaneous/rack/back/map.rb +5 -5
- data/lib/spontaneous/rack/back/preview.rb +3 -4
- data/lib/spontaneous/rack/back/schema.rb +1 -1
- data/lib/spontaneous/rack/back/site.rb +6 -7
- data/lib/spontaneous/rack/front.rb +19 -16
- data/lib/spontaneous/rack/middleware/authenticate.rb +3 -3
- data/lib/spontaneous/rack/middleware/reloader.rb +3 -2
- data/lib/spontaneous/rack/middleware/scope.rb +25 -19
- data/lib/spontaneous/rack/page_controller.rb +164 -13
- data/lib/spontaneous/rack/public.rb +23 -62
- data/lib/spontaneous/rack/static.rb +2 -3
- data/lib/spontaneous/schema.rb +27 -8
- data/lib/spontaneous/schema/schema_modification.rb +9 -1
- data/lib/spontaneous/schema/uid.rb +2 -2
- data/lib/spontaneous/schema/uid_map.rb +3 -2
- data/lib/spontaneous/search/database.rb +2 -2
- data/lib/spontaneous/search/field.rb +5 -3
- data/lib/spontaneous/search/index.rb +12 -7
- data/lib/spontaneous/search/results.rb +5 -3
- data/lib/spontaneous/server.rb +2 -2
- data/lib/spontaneous/site.rb +10 -3
- data/lib/spontaneous/site/features.rb +26 -6
- data/lib/spontaneous/site/helpers.rb +9 -12
- data/lib/spontaneous/site/level.rb +7 -9
- data/lib/spontaneous/site/map.rb +9 -11
- data/lib/spontaneous/site/paths.rb +5 -5
- data/lib/spontaneous/site/publishing.rb +83 -80
- data/lib/spontaneous/site/schema.rb +1 -7
- data/lib/spontaneous/site/search.rb +8 -18
- data/lib/spontaneous/site/selectors.rb +60 -54
- data/lib/spontaneous/site/state.rb +36 -30
- data/lib/spontaneous/site/storage.rb +10 -16
- data/lib/spontaneous/state.rb +8 -0
- data/lib/spontaneous/style.rb +32 -33
- data/lib/spontaneous/version.rb +1 -1
- data/spontaneous.gemspec +22 -21
- data/test/fixtures/public/templates/layouts/default.html.cut +1 -1
- data/test/fixtures/public/templates/layouts/default.pdf.cut +1 -1
- data/test/fixtures/public/templates/layouts/default.rss.cut +1 -1
- data/test/fixtures/search/config/indexes.rb +1 -1
- data/test/fixtures/serialisation/class_hash.yaml.erb +13 -1
- data/test/fixtures/serialisation/root_hash.yaml.erb +10 -0
- data/test/functional/test_application.rb +20 -24
- data/test/functional/test_back.rb +26 -27
- data/test/functional/test_cli.rb +146 -0
- data/test/functional/test_front.rb +287 -216
- data/test/functional/test_user_manager.rb +1 -1
- data/test/test_helper.rb +15 -11
- data/test/unit/test_alias.rb +32 -25
- data/test/unit/test_asset_bundler.rb +1 -1
- data/test/unit/test_assets.rb +34 -33
- data/test/unit/test_authentication.rb +1 -1
- data/test/unit/test_boxes.rb +16 -2
- data/test/unit/test_changesets.rb +23 -11
- data/test/unit/test_content.rb +15 -0
- data/test/unit/test_context.rb +139 -0
- data/test/unit/test_controllers.rb +374 -0
- data/test/{experimental → unit}/test_crypt.rb +0 -0
- data/test/unit/test_datamapper.rb +260 -237
- data/test/unit/test_datamapper_content.rb +42 -12
- data/test/{experimental → unit}/test_features.rb +85 -3
- data/test/unit/test_fields.rb +117 -42
- data/test/unit/test_formats.rb +11 -1
- data/test/unit/test_generators.rb +2 -2
- data/test/unit/test_helpers.rb +7 -8
- data/test/unit/test_images.rb +39 -2
- data/test/unit/test_layouts.rb +14 -12
- data/test/unit/test_media.rb +32 -23
- data/test/unit/test_output_store.rb +342 -0
- data/test/unit/test_page.rb +8 -1
- data/test/unit/test_permissions.rb +11 -7
- data/test/unit/test_plugins.rb +3 -3
- data/test/unit/test_prototype_set.rb +8 -1
- data/test/unit/test_publishing.rb +67 -54
- data/test/unit/test_render.rb +91 -38
- data/test/unit/test_revisions.rb +4 -4
- data/test/unit/test_schema.rb +109 -84
- data/test/unit/test_search.rb +42 -42
- data/test/unit/test_serialisation.rb +3 -2
- data/test/unit/test_site.rb +39 -27
- data/test/unit/test_storage.rb +9 -6
- data/test/unit/test_styles.rb +25 -32
- data/test/unit/test_templates.rb +8 -4
- metadata +89 -54
- data/lib/spontaneous/model/page/request.rb +0 -105
- 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
|
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 =
|
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 =
|
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
|
@@ -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(
|
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!(
|
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 = {},
|
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,
|
14
|
+
output(format).render(params, parent_context)
|
15
15
|
end
|
16
16
|
|
17
|
-
def render_using(renderer, format = :html, params = {},
|
18
|
-
output(format).render_using(renderer, params,
|
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 =
|
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
|
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
|
-
|
24
|
-
|
25
|
-
|
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
|
-
|
28
|
-
|
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
|
-
|
37
|
-
|
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
|
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
|
-
|
61
|
-
|
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
|
109
|
-
|
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(
|
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, :
|
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
|
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
|
26
|
-
|
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
|
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 }
|
data/lib/spontaneous/output.rb
CHANGED
@@ -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
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
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.
|
140
|
-
Template::
|
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.
|
144
|
-
|
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,
|
156
|
-
autoload :Context,
|
157
|
-
autoload :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
|
|