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
@@ -6,8 +6,8 @@ module Spontaneous::Rack::Middleware
|
|
6
6
|
class Init
|
7
7
|
include Spontaneous::Rack::Constants
|
8
8
|
|
9
|
-
def initialize(app)
|
10
|
-
@app = app
|
9
|
+
def initialize(app, site)
|
10
|
+
@app, @site = app, site
|
11
11
|
end
|
12
12
|
|
13
13
|
def call(env)
|
@@ -20,7 +20,7 @@ module Spontaneous::Rack::Middleware
|
|
20
20
|
|
21
21
|
def authenticate(env)
|
22
22
|
remote_addr = env["REMOTE_ADDR"]
|
23
|
-
if (login =
|
23
|
+
if (login = @site.config.auto_login)
|
24
24
|
auto_login(login, remote_addr)
|
25
25
|
else
|
26
26
|
cookie_login(env, remote_addr)
|
@@ -10,9 +10,10 @@ module Spontaneous::Rack::Middleware
|
|
10
10
|
class Reloader
|
11
11
|
include Spontaneous::Rack::Back::TemplateHelpers
|
12
12
|
|
13
|
-
def initialize(app, *args)
|
13
|
+
def initialize(app, site, *args)
|
14
14
|
@app = app
|
15
|
-
@
|
15
|
+
@site = site
|
16
|
+
@active = @site.config.reload_classes
|
16
17
|
config = args.first || {}
|
17
18
|
@cooldown = config[:cooldown] || 3
|
18
19
|
@last = (Time.now - @cooldown)
|
@@ -1,33 +1,39 @@
|
|
1
1
|
module Spontaneous::Rack::Middleware
|
2
2
|
module Scope
|
3
|
-
class
|
4
|
-
|
5
|
-
|
6
|
-
@app = app
|
3
|
+
class Base
|
4
|
+
def initialize(app, site, options = {})
|
5
|
+
raise "Missing site instance" if site.nil?
|
6
|
+
@app, @site, @options = app, site, options
|
7
7
|
end
|
8
8
|
|
9
9
|
def call(env)
|
10
|
+
env[Spontaneous::Rack::SITE] = @site
|
11
|
+
call!(env)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class Edit < Base
|
16
|
+
def call!(env)
|
10
17
|
response = nil
|
11
|
-
|
18
|
+
@site.model.scope(nil, false) do
|
12
19
|
response = @app.call(env)
|
13
20
|
end
|
14
21
|
response
|
15
22
|
end
|
16
23
|
end
|
17
24
|
|
18
|
-
class Preview
|
25
|
+
class Preview < Base
|
19
26
|
include Spontaneous::Rack::Constants
|
20
27
|
|
21
|
-
def initialize(app)
|
22
|
-
|
23
|
-
@renderer = Spontaneous::Output.preview_renderer
|
24
|
-
Spontaneous::Output.renderer = @renderer
|
28
|
+
def initialize(app, site, options = {})
|
29
|
+
super
|
30
|
+
@renderer = Spontaneous::Output.preview_renderer(@site)
|
25
31
|
end
|
26
32
|
|
27
|
-
def call(env)
|
33
|
+
def call!(env)
|
28
34
|
env[RENDERER] = @renderer
|
29
35
|
response = nil
|
30
|
-
|
36
|
+
@site.model.scope(nil, true) do
|
31
37
|
response = @app.call(env)
|
32
38
|
end
|
33
39
|
response
|
@@ -38,19 +44,19 @@ module Spontaneous::Rack::Middleware
|
|
38
44
|
"X-Powered-By" => "Spontaneous CMS v#{Spontaneous::VERSION}"
|
39
45
|
}
|
40
46
|
|
41
|
-
class Front
|
47
|
+
class Front < Base
|
42
48
|
include Spontaneous::Rack::Constants
|
43
49
|
|
44
|
-
def initialize(app)
|
45
|
-
|
46
|
-
@renderer = Spontaneous::Output.published_renderer
|
50
|
+
def initialize(app, site, options = {})
|
51
|
+
super
|
52
|
+
@renderer = Spontaneous::Output.published_renderer(@site)
|
47
53
|
end
|
48
54
|
|
49
|
-
def call(env)
|
55
|
+
def call!(env)
|
50
56
|
status = headers = body = nil
|
51
57
|
env[RENDERER] = @renderer
|
52
|
-
env[REVISION] =
|
53
|
-
|
58
|
+
env[REVISION] = @site.published_revision
|
59
|
+
@site.model.with_published(@site) do
|
54
60
|
status, headers, body = @app.call(env)
|
55
61
|
end
|
56
62
|
[status, headers.merge(POWERED_BY), body]
|
@@ -4,28 +4,179 @@ require 'sinatra/base'
|
|
4
4
|
|
5
5
|
module Spontaneous::Rack
|
6
6
|
class PageController < Sinatra::Base
|
7
|
-
|
8
|
-
|
7
|
+
class << self
|
8
|
+
# We wrap Sinatra's route methods in order to do two things:
|
9
|
+
# 1. To provide a path of '/' when none is given and
|
10
|
+
# 2. To register the presence of a handler for each method in order to
|
11
|
+
# correctly respond to the #dynamic? test
|
12
|
+
def get(*args, &bk) __dynamic!(:get, super(*__route_args(args), &bk)) end
|
13
|
+
def put(*args, &bk) __dynamic!(:put, super(*__route_args(args), &bk)) end
|
14
|
+
def post(*args, &bk) __dynamic!(:post, super(*__route_args(args), &bk)) end
|
15
|
+
def delete(*args, &bk) __dynamic!(:delete, super(*__route_args(args), &bk)) end
|
16
|
+
def head(*args, &bk) __dynamic!(:head, super(*__route_args(args), &bk)) end
|
17
|
+
def options(*args, &bk) __dynamic!(:options, super(*__route_args(args), &bk)) end
|
18
|
+
def patch(*args, &bk) __dynamic!(:patch, super(*__route_args(args), &bk)) end
|
19
|
+
def link(*args, &bk) __dynamic!(:link, super(*__route_args(args), &bk)) end
|
20
|
+
def unlink(*args, &bk) __dynamic!(:unlink, super(*__route_args(args), &bk)) end
|
9
21
|
|
10
|
-
|
11
|
-
|
22
|
+
def dynamic?(method = :get)
|
23
|
+
__dynamic[method]
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def __route_args(args)
|
30
|
+
opts = args.extract_options!
|
31
|
+
path = String === args.first ? args.first : '/'
|
32
|
+
[path, opts]
|
33
|
+
end
|
34
|
+
|
35
|
+
def __dynamic!(method, action)
|
36
|
+
__dynamic[method] = true
|
37
|
+
end
|
38
|
+
|
39
|
+
def __dynamic
|
40
|
+
@__dynamic ||= {}
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
attr_reader :content, :site
|
45
|
+
|
46
|
+
def initialize(site, content, output)
|
47
|
+
@site, @content, @output, @locals = site, content, output, {}
|
12
48
|
@page = content.page
|
13
49
|
super(nil)
|
14
50
|
end
|
15
51
|
|
52
|
+
# render [instance (Content), output (Symbol), status (Fixnum), locals (Hash)]
|
53
|
+
# render [uid (Symbol), status (Fixnum), locals (Hash)] => [instance, output, status, locals]
|
54
|
+
# render [uid (Symbol)] => [uid, output, 200, {}]
|
55
|
+
# render [instance (Content)] => [instance, output, 200, {}]
|
56
|
+
# render [locals (Hash)] => [page, output, 200, locals]
|
57
|
+
# render [status (Fixnum)] => [page, output, status, {}]
|
58
|
+
# render(:home, :xml, 200, {logged_in: true}) # => :home => uid, :xml => output
|
59
|
+
# render(:home, 200, {logged_in: true}) # => :home => uid
|
60
|
+
# render(:home, {logged_in: true}) # => :home => uid
|
61
|
+
# render(:xml, 200, {logged_in: true}) # NOT ALLOWED: if you want to specify the output then you must also specify the page
|
62
|
+
# render(403, {logged_in: false})
|
63
|
+
#
|
64
|
+
# Every controller *must* include a call to render
|
16
65
|
def render(*args)
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
66
|
+
@locals = args.extract_options!
|
67
|
+
show(*args)
|
68
|
+
render_body
|
69
|
+
end
|
70
|
+
|
71
|
+
# Show provides a way to configure future calls to render without the overhead of
|
72
|
+
# calling #render itself. Good if you want to set up a default state & then override
|
73
|
+
# it later.
|
74
|
+
# Only #render accepts a locals hash that is passed into the render call
|
75
|
+
def show(*args)
|
76
|
+
page, output, status = self.page, self.output, self.status
|
77
|
+
case args.length
|
78
|
+
when 3
|
79
|
+
page, output, status = args
|
80
|
+
when 2
|
81
|
+
page, last = args
|
82
|
+
case last
|
83
|
+
when Fixnum
|
84
|
+
status = last
|
85
|
+
else
|
86
|
+
output = last
|
87
|
+
end
|
88
|
+
when 1
|
89
|
+
case (arg = args.first)
|
90
|
+
when Fixnum
|
91
|
+
status = arg
|
92
|
+
else
|
25
93
|
page = arg
|
26
94
|
end
|
27
95
|
end
|
28
|
-
|
96
|
+
page(page)
|
97
|
+
status(status)
|
98
|
+
output(output)
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
REDIRECTS = {
|
103
|
+
:permanent => 301,
|
104
|
+
:temporary => 302
|
105
|
+
}
|
106
|
+
|
107
|
+
def redirect(location, redirect_code=:temporary)
|
108
|
+
if String === location
|
109
|
+
destination = @site[location]
|
110
|
+
location = destination.path if destination and destination.respond_to?(:path)
|
111
|
+
else
|
112
|
+
location = location.path if location.respond_to?(:path)
|
113
|
+
end
|
114
|
+
redirect_code = REDIRECTS[redirect_code] if Symbol === redirect_code
|
115
|
+
redirect_code ||= REDIRECTS[:temporary]
|
116
|
+
# let Sinatra's helper method set up the proper Location headers for us
|
117
|
+
catch(:halt) { super(location) }
|
118
|
+
status(redirect_code)
|
119
|
+
# then re-throw the :halt
|
120
|
+
halt
|
121
|
+
end
|
122
|
+
|
123
|
+
def output(*args)
|
124
|
+
return @output if args.empty?
|
125
|
+
@output = args.first
|
126
|
+
end
|
127
|
+
|
128
|
+
def not_found
|
129
|
+
super(not_found_body)
|
130
|
+
end
|
131
|
+
|
132
|
+
def page(page = nil)
|
133
|
+
return @page if page.nil?
|
134
|
+
@page = fetch_page(page)
|
135
|
+
end
|
136
|
+
|
137
|
+
private
|
138
|
+
|
139
|
+
def renderer
|
140
|
+
env[Spontaneous::Rack::RENDERER]
|
141
|
+
end
|
142
|
+
|
143
|
+
def fetch_page(page)
|
144
|
+
return @site[page] if (String === page) || (Symbol === page)
|
145
|
+
page
|
146
|
+
end
|
147
|
+
|
148
|
+
def render_body
|
149
|
+
body(render_page)
|
150
|
+
end
|
151
|
+
|
152
|
+
def render_page
|
153
|
+
not_found if page.nil?
|
154
|
+
not_found unless page.provides_output?(self.output)
|
155
|
+
output = page.output(self.output)
|
156
|
+
render_output(output)
|
157
|
+
end
|
158
|
+
|
159
|
+
def render_output(output)
|
160
|
+
if output.public?
|
161
|
+
content_type(output.mime_type)
|
162
|
+
do_render(output, @locals)
|
163
|
+
else
|
164
|
+
not_found
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def do_render(output, locals)
|
169
|
+
locals = locals.merge({
|
170
|
+
params: params, # use sinatras indifferent params
|
171
|
+
request: request,
|
172
|
+
session: request.session,
|
173
|
+
env: request.env
|
174
|
+
})
|
175
|
+
output.render_using(renderer, locals)
|
176
|
+
end
|
177
|
+
|
178
|
+
def not_found_body
|
179
|
+
"not found"
|
29
180
|
end
|
30
181
|
end
|
31
182
|
end
|
@@ -5,7 +5,7 @@ module Spontaneous
|
|
5
5
|
module Rack
|
6
6
|
module Public
|
7
7
|
include Constants
|
8
|
-
include Sinatra::Helpers unless method_defined?(:redirect)
|
8
|
+
# include Sinatra::Helpers unless method_defined?(:redirect)
|
9
9
|
|
10
10
|
attr_reader :env, :response, :request
|
11
11
|
attr_accessor :page
|
@@ -17,10 +17,10 @@ module Spontaneous
|
|
17
17
|
response = catch(:halt) do
|
18
18
|
if @page
|
19
19
|
case @request.request_method
|
20
|
-
when METHOD_GET
|
20
|
+
when METHOD_GET, METHOD_HEAD
|
21
21
|
render_get
|
22
22
|
else
|
23
|
-
|
23
|
+
render_other
|
24
24
|
end
|
25
25
|
else
|
26
26
|
not_found!
|
@@ -41,17 +41,10 @@ module Spontaneous
|
|
41
41
|
[status, header, body]
|
42
42
|
end
|
43
43
|
|
44
|
-
def halt(*response)
|
45
|
-
response = response.first if response.length == 1
|
46
|
-
throw :halt, response
|
47
|
-
end
|
48
|
-
|
49
|
-
|
50
|
-
|
51
44
|
# stolen from Sinatra
|
52
45
|
def parse_response(response)
|
53
46
|
case
|
54
|
-
when response.is_a?(
|
47
|
+
when response.is_a?(site.model)
|
55
48
|
@page = response
|
56
49
|
when response.respond_to?(:to_str)
|
57
50
|
@response.body = [response]
|
@@ -81,45 +74,13 @@ module Spontaneous
|
|
81
74
|
DOT = '.'.freeze
|
82
75
|
ACTION = "/#{S::Model::Page::Controllers::ACTION_SEPARATOR}".freeze
|
83
76
|
|
84
|
-
def show(page, status=200)
|
85
|
-
page = Spontaneous::Site[page] if String === page
|
86
|
-
@page = page
|
87
|
-
status(status)
|
88
|
-
end
|
89
|
-
|
90
|
-
def render(page, template_params = {})
|
91
|
-
@template_params = template_params
|
92
|
-
show(page)
|
93
|
-
end
|
94
|
-
|
95
|
-
REDIRECTS = {
|
96
|
-
:permanent => 301,
|
97
|
-
:temporary => 302
|
98
|
-
}
|
99
|
-
|
100
|
-
def redirect(location, redirect_code=:temporary)
|
101
|
-
if String === location
|
102
|
-
destination = Spontaneous::Site[location]
|
103
|
-
location = destination.path if destination and destination.respond_to?(:path)
|
104
|
-
else
|
105
|
-
location = location.path if location.respond_to?(:path)
|
106
|
-
end
|
107
|
-
redirect_code = REDIRECTS[redirect_code] if Symbol === redirect_code
|
108
|
-
redirect_code ||= REDIRECTS[:temporary]
|
109
|
-
# let Sinatra's helper method set up the proper Location headers for us
|
110
|
-
catch(:halt) { super(location) }
|
111
|
-
status(redirect_code)
|
112
|
-
# then re-throw the :halt
|
113
|
-
halt
|
114
|
-
end
|
115
|
-
|
116
77
|
def content_type(type, params={})
|
117
|
-
default
|
78
|
+
default = params.delete :default
|
118
79
|
mime_type = mime_type(type) || default
|
119
80
|
fail "Unknown media type: %p" % type if mime_type.nil?
|
120
81
|
mime_type = mime_type.dup
|
121
82
|
unless params.include? :charset
|
122
|
-
params[:charset] = params.delete('charset') ||
|
83
|
+
params[:charset] = params.delete('charset') || site.config.default_charset || 'utf-8'
|
123
84
|
end
|
124
85
|
mime_type << ";#{params.map { |kv| kv.join('=') }.join(', ')}" unless params.empty?
|
125
86
|
response['Content-Type'] = mime_type
|
@@ -131,7 +92,7 @@ module Spontaneous
|
|
131
92
|
end
|
132
93
|
|
133
94
|
def find_page_by_path(path)
|
134
|
-
|
95
|
+
site.by_path(path)
|
135
96
|
end
|
136
97
|
|
137
98
|
def output(name)
|
@@ -143,34 +104,34 @@ module Spontaneous
|
|
143
104
|
end
|
144
105
|
|
145
106
|
def render_get
|
146
|
-
if @action
|
147
|
-
|
107
|
+
return call_action! if @action
|
108
|
+
if page.dynamic?(request.request_method)
|
109
|
+
invoke_action { page.process_root_action(site, env.dup, @output) }
|
148
110
|
else
|
149
|
-
block = page.request_block(request)
|
150
|
-
parse_response(instance_eval(&block)) if (block)
|
151
111
|
render_page_with_output
|
152
112
|
end
|
153
113
|
end
|
154
114
|
|
155
|
-
#
|
156
|
-
|
157
|
-
|
158
|
-
return not_found! unless (
|
115
|
+
# Only pages that provide a controller for the current URL should respond
|
116
|
+
# to anything other than GET or HEAD
|
117
|
+
def render_other
|
118
|
+
return not_found! unless (page.dynamic?(request.request_method) or @action)
|
159
119
|
|
160
|
-
if @action
|
161
|
-
|
162
|
-
|
163
|
-
parse_response(instance_eval(&block)) if (block)
|
164
|
-
render_page_with_output
|
165
|
-
end
|
120
|
+
return call_action! if @action
|
121
|
+
|
122
|
+
invoke_action { page.process_root_action(site, env.dup, @output) }
|
166
123
|
end
|
167
124
|
|
168
125
|
def call_action!
|
169
|
-
|
126
|
+
invoke_action { @page.process_action(site, action, env.dup, @output) }
|
127
|
+
end
|
128
|
+
|
129
|
+
def invoke_action
|
130
|
+
status, headers, result = yield
|
170
131
|
if status == 404
|
171
132
|
not_found!
|
172
133
|
else
|
173
|
-
if result.is_a?(
|
134
|
+
if result.is_a?(site.model)
|
174
135
|
@page = result
|
175
136
|
render_page_with_output
|
176
137
|
else
|