spontaneous 0.2.0.beta9 → 0.2.0.beta10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +61 -0
- data/LICENSE +18 -17
- data/Rakefile +1 -1
- data/application/css/core.css.scss +1 -1
- data/application/css/dialogue.css.scss +8 -20
- data/application/js/preview.js +28 -7
- data/application/js/publish.js +15 -4
- data/application/js/top_bar.js +0 -16
- data/application/js/views/piece_view.js +1 -1
- data/lib/spontaneous/asset/environment.rb +16 -1
- data/lib/spontaneous/box.rb +68 -0
- data/lib/spontaneous/capistrano/deploy.rb +7 -4
- data/lib/spontaneous/capistrano/sync.rb +2 -2
- data/lib/spontaneous/cli/init.rb +70 -19
- data/lib/spontaneous/cli/init/db.rb +34 -55
- data/lib/spontaneous/cli/init/mysql.rb +5 -5
- data/lib/spontaneous/cli/init/postgresql.rb +8 -9
- data/lib/spontaneous/cli/init/sqlite.rb +1 -2
- data/lib/spontaneous/cli/migrate.rb +0 -1
- data/lib/spontaneous/cli/site.rb +4 -0
- data/lib/spontaneous/collections/entry_set.rb +11 -0
- data/lib/spontaneous/data_mapper/content_model.rb +2 -0
- data/lib/spontaneous/data_mapper/content_model/serialization.rb +2 -2
- data/lib/spontaneous/extensions/array.rb +12 -2
- data/lib/spontaneous/field/base.rb +10 -0
- data/lib/spontaneous/field/file.rb +32 -2
- data/lib/spontaneous/field/image.rb +24 -2
- data/lib/spontaneous/field/select.rb +8 -0
- data/lib/spontaneous/field/webvideo.rb +8 -0
- data/lib/spontaneous/generators/site/config/initializers/fields.rb +55 -0
- data/lib/spontaneous/json.rb +3 -2
- data/lib/spontaneous/logger.rb +2 -2
- data/lib/spontaneous/media/file.rb +3 -3
- data/lib/spontaneous/media/image/attributes.rb +72 -6
- data/lib/spontaneous/media/image/renderable.rb +53 -20
- data/lib/spontaneous/media/store.rb +3 -3
- data/lib/spontaneous/media/store/backend.rb +16 -0
- data/lib/spontaneous/media/store/cloud.rb +52 -12
- data/lib/spontaneous/media/store/local.rb +6 -3
- data/lib/spontaneous/model.rb +3 -0
- data/lib/spontaneous/model/core/entries.rb +34 -13
- data/lib/spontaneous/model/core/entry.rb +3 -1
- data/lib/spontaneous/model/page/controllers.rb +1 -2
- data/lib/spontaneous/model/page/paths.rb +18 -7
- data/lib/spontaneous/output/context.rb +0 -8
- data/lib/spontaneous/output/template/renderer.rb +2 -0
- data/lib/spontaneous/plugins/application/state.rb +0 -4
- data/lib/spontaneous/prototypes/field_prototype.rb +4 -0
- data/lib/spontaneous/publishing/immediate.rb +0 -5
- data/lib/spontaneous/publishing/progress.rb +2 -2
- data/lib/spontaneous/publishing/rerender.rb +1 -4
- data/lib/spontaneous/publishing/simultaneous.rb +19 -17
- data/lib/spontaneous/publishing/steps.rb +12 -3
- data/lib/spontaneous/rack.rb +2 -0
- data/lib/spontaneous/rack/asset_server.rb +5 -2
- data/lib/spontaneous/rack/back.rb +9 -1
- data/lib/spontaneous/rack/back/base.rb +1 -0
- data/lib/spontaneous/rack/back/changes.rb +5 -0
- data/lib/spontaneous/rack/back/preview.rb +4 -4
- data/lib/spontaneous/rack/back/private.rb +11 -0
- data/lib/spontaneous/rack/middleware/scope.rb +16 -4
- data/lib/spontaneous/rack/page_controller.rb +2 -2
- data/lib/spontaneous/rack/public.rb +52 -4
- data/lib/spontaneous/sequel.rb +10 -13
- data/lib/spontaneous/site.rb +28 -8
- data/lib/spontaneous/site/publishing.rb +1 -1
- data/lib/spontaneous/site/storage.rb +7 -4
- data/lib/spontaneous/tasks/environment.rake +3 -0
- data/lib/spontaneous/utils/database/postgres_dumper.rb +23 -2
- data/lib/spontaneous/version.rb +1 -1
- data/spontaneous.gemspec +7 -12
- data/test/fixtures/assets/public1/css/data.css.scss +1 -1
- data/test/functional/test_application.rb +15 -0
- data/test/functional/test_cli.rb +109 -3
- data/test/functional/test_front.rb +108 -10
- data/test/test_helper.rb +3 -3
- data/test/unit/fields/test_boolean_fields.rb +80 -0
- data/test/unit/fields/test_date_fields.rb +47 -0
- data/test/unit/fields/test_file_field.rb +210 -0
- data/test/unit/{test_images.rb → fields/test_image_fields.rb} +133 -15
- data/test/unit/fields/test_location_fields.rb +41 -0
- data/test/unit/fields/test_option_fields.rb +61 -0
- data/test/unit/fields/test_tag_list_fields.rb +45 -0
- data/test/unit/fields/test_text_fields.rb +124 -0
- data/test/unit/fields/test_web_video_fields.rb +198 -0
- data/test/unit/test_assets.rb +22 -22
- data/test/unit/test_boxes.rb +34 -13
- data/test/unit/test_changesets.rb +1 -0
- data/test/unit/test_extensions.rb +17 -0
- data/test/unit/test_fields.rb +20 -643
- data/test/unit/test_media.rb +9 -9
- data/test/unit/test_page.rb +47 -0
- data/test/unit/test_publishing_pipeline.rb +2 -2
- data/test/unit/test_serialisation.rb +37 -0
- data/test/unit/test_storage.rb +42 -3
- metadata +37 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 75f4d83b1920a348269f6d51f4060015a6f567fd
|
4
|
+
data.tar.gz: ef4257ad7ada51eed31e316efb5f712ee77be7ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d8874945d474270fd5c73d376f65d2b31385a0d14c33d386bb55c3f61ae6495e28ffd70d64fe9aaa366f94f17347f4be3dd713a293a213ef0aa1849111c88395
|
7
|
+
data.tar.gz: 7c58d0ef193f9f709563eb6c1c34e33dacbb3823169d9b377714386d7aacd9b943f9d6c0ce59f007e6f75ae3b843e23469e1f00e8f6e814b908e67395f1ddc38
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,64 @@
|
|
1
|
+
## 0.2.0.beta10, released 2015-03-20
|
2
|
+
|
3
|
+
Is it wise to release a new version during a solar eclipse?
|
4
|
+
|
5
|
+
#### New Features
|
6
|
+
|
7
|
+
- Enabled previewing of private pages within the CMS. Previously this would
|
8
|
+
invoke some Inception-like preview-within-preview loop
|
9
|
+
|
10
|
+
- Boxes can now define a `path_origin` function that returns a `Content::Page` instance or a string which sets the root path for all pages added to it. This allows for your content & path hierarchies to differ (e.g. having child pages of the `/bands` page, e.g. `/bands/the-beatles` appear publicly at the root of the site i.e. `/the-beatles`).
|
11
|
+
|
12
|
+
- Page types can set a custom default slug root so that instead of being added as `page-YMD-HMS` they can be configured to default to `something-YMD-HMS` by overriding the value returned by `Content::Page#default_slug_root`.
|
13
|
+
|
14
|
+
- You can now get a list of content ids for a box using the `Box#ids` method
|
15
|
+
|
16
|
+
- The db connection can now be set using a `DATABASE_URL` env setting
|
17
|
+
|
18
|
+
- File and Image fields now generate their URLs dynamically. In the case of cloud hosted media this means you can change the way you address the media without having to regenerate the values e.g. in the case that you move from a direct S3 bucket to a CDN. You can also use any object that responds to `#call(path)` to generate the URLs which opens the door to splitting your media across multiple asset hosts.
|
19
|
+
|
20
|
+
- Pages can now declare 'wildcard' routes without namespaces which makes them more like standard controllers. E.g. declaring
|
21
|
+
|
22
|
+
controller do
|
23
|
+
get '/wibble/:id' do ... end
|
24
|
+
end
|
25
|
+
|
26
|
+
will allow a page mounted at `/womble` to accept requests to `/womble/wibble/23` etc.
|
27
|
+
|
28
|
+
- The publish dialogue now has a `Rerender` button that allows developers to re-render the site without publishing any content in the case of a template/asset change. Great if you need to push a fix but don't want to wait for or force the editors to publish something.
|
29
|
+
|
30
|
+
- You can now configure some default options for rendering image fields (and the default output for `${ image }` no longer includes the width & height by default (we’re responsive now, right?)).
|
31
|
+
|
32
|
+
#### Misc
|
33
|
+
|
34
|
+
- JSON de/en-coding is now handled by [Oj](https://github.com/ohler55/oj) not [Yajl](https://lloyd.github.io/yajl/) after some informal testing showed a ~50% speed improvement.
|
35
|
+
- The site initialization has been re-written to improve clarity & reliability
|
36
|
+
- Capistrano tasks can now be configured to use a custom binary for `rake` and `spot` commands
|
37
|
+
- Boxes now have a `#clear!` method to remove all their contents
|
38
|
+
- `Content#/` is an alias for `#get` by id
|
39
|
+
- The db timezone is set to UTC which results in some improved performance
|
40
|
+
- `Site#inspect` output is less mad
|
41
|
+
- The asset serving in preview mode has been moved before the authentication checks so we aren't running hundreds of db calls just to return some JS and images.
|
42
|
+
- The sprockets context has been given some Rails-compatible methods to help with using 3rd party sprockets plugins, e.g. `sprockets-less`.
|
43
|
+
- Select fields can now have a default value set
|
44
|
+
- Video fields now have an `aspect_ratio` method
|
45
|
+
- `spot site rerender` is an alias for `spot site render`
|
46
|
+
|
47
|
+
#### Fixes
|
48
|
+
|
49
|
+
- Front server no longer needs restarting to pick up a new revision in development mode (https://github.com/SpontaneousCMS/spontaneous/issues/47)
|
50
|
+
- Fixed entry deletion confirmation popup
|
51
|
+
- `Array#render` now calls `render_inline` rather than `render` so that rendering an array of pages doesn’t do mad things.
|
52
|
+
- The postgres database dumper/loader now works with custom hosts and ports and correctly authenticates itself when password authentication is in place
|
53
|
+
- File & image fields `#blank?` methods now work correctly (and are aliased as `#empty?`)
|
54
|
+
- Removed broken render context implementations of `#first?` and `#last?`
|
55
|
+
- `spot site init` ensures that the `log` & `tmp` directories exist
|
56
|
+
- Don't try to set encoding values when there's no content-type header returned
|
57
|
+
- `asset-data-uri` is now correctly wrapping the result in a `url()` declaration.
|
58
|
+
- Displaying exceptions in development preview now works
|
59
|
+
- Second level boxes now correctly show an 'add' toolbar below the last entry
|
60
|
+
- The 'no changes' message is now a more pleasing size & the spinner goes away
|
61
|
+
|
1
62
|
## 0.2.0.beta9, released 2014-10-30
|
2
63
|
|
3
64
|
#### Fixes
|
data/LICENSE
CHANGED
@@ -1,20 +1,21 @@
|
|
1
|
-
|
1
|
+
The MIT License (MIT)
|
2
2
|
|
3
|
-
|
4
|
-
a copy of this software and associated documentation files (the
|
5
|
-
"Software"), to deal in the Software without restriction, including
|
6
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
-
permit persons to whom the Software is furnished to do so, subject to
|
9
|
-
the following conditions:
|
3
|
+
Copyright (c) 2011-2014 Garry Richard Hill
|
10
4
|
|
11
|
-
|
12
|
-
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
13
11
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/Rakefile
CHANGED
@@ -28,7 +28,7 @@ require 'rake/testtask'
|
|
28
28
|
Rake::TestTask.new(:test) do |test|
|
29
29
|
test.libs << 'test'
|
30
30
|
test.ruby_opts << '-rubygems'
|
31
|
-
test.pattern = 'test/{unit,functional,experimental}
|
31
|
+
test.pattern = 'test/{unit,functional,experimental}/**/test_*.rb'
|
32
32
|
test.verbose = false
|
33
33
|
end
|
34
34
|
|
@@ -84,7 +84,7 @@ $dialogue-title-height: 32px;
|
|
84
84
|
float: right;
|
85
85
|
}
|
86
86
|
.disabled, .disabled:hover {
|
87
|
-
|
87
|
+
@include button-color(#333, #333);
|
88
88
|
color: #6b6b6b !important;
|
89
89
|
}
|
90
90
|
}
|
@@ -142,6 +142,12 @@ $dialogue-title-height: 32px;
|
|
142
142
|
#dialogue-wrap #dialogue-outer.publishing {
|
143
143
|
left: 5%;
|
144
144
|
right: 5%;
|
145
|
+
.dialogue-actions {
|
146
|
+
.button.rerender {
|
147
|
+
position: absolute;
|
148
|
+
left: 0;
|
149
|
+
}
|
150
|
+
}
|
145
151
|
}
|
146
152
|
|
147
153
|
#publishing-dialogue {
|
@@ -251,25 +257,7 @@ $dialogue-title-height: 32px;
|
|
251
257
|
font-size: 24px;
|
252
258
|
padding-top: 24px;
|
253
259
|
color: #fff;
|
254
|
-
|
255
|
-
// margin-top: 0;
|
256
|
-
// .publish-all {
|
257
|
-
// @include button(#666);
|
258
|
-
// @include interface;
|
259
|
-
// width: 128px;
|
260
|
-
// float: right;
|
261
|
-
// text-align: left;
|
262
|
-
// // background-color: #666666;
|
263
|
-
// input {
|
264
|
-
// margin: 1px 8px 0 8px;
|
265
|
-
// padding: 0;
|
266
|
-
// vertical-align: top;
|
267
|
-
// position: relative;
|
268
|
-
// }
|
269
|
-
// }
|
270
|
-
// .publish-all.checked {
|
271
|
-
// background-color: $action;
|
272
|
-
// }
|
260
|
+
max-height: 55px;
|
273
261
|
}
|
274
262
|
.change-set {
|
275
263
|
cursor: pointer;
|
data/application/js/preview.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
// console.log('Loading Preview...');
|
2
2
|
|
3
3
|
Spontaneous.Preview = (function($, S, $window) {
|
4
|
-
var dom = S.Dom, goto_id = 0;
|
4
|
+
var dom = S.Dom, goto_id = 0, Ajax = S.Ajax;
|
5
5
|
var click_param = function() {
|
6
6
|
return '?__click='+(++goto_id);
|
7
7
|
};
|
@@ -31,13 +31,16 @@ Spontaneous.Preview = (function($, S, $window) {
|
|
31
31
|
if (currentLocation !== location) {
|
32
32
|
location = currentLocation;
|
33
33
|
S.Preview.set({
|
34
|
-
'title':
|
35
|
-
'path':
|
34
|
+
'title': icw.document.title,
|
35
|
+
'path': icw.location.pathname
|
36
36
|
});
|
37
37
|
$(icw).bind('unload', function(e) {
|
38
38
|
// trigger a progress indicator here
|
39
39
|
});
|
40
|
-
|
40
|
+
// don't load the page details into the top-bar if we're viewing a private page
|
41
|
+
if (preview.pathIsPublic(icw.location.pathname)) {
|
42
|
+
S.Location.load_path(icw.location.pathname);
|
43
|
+
}
|
41
44
|
}
|
42
45
|
};
|
43
46
|
|
@@ -48,18 +51,36 @@ Spontaneous.Preview = (function($, S, $window) {
|
|
48
51
|
preview.previewPathMonitor = $window.setInterval(monitor, monitorInterval);
|
49
52
|
}
|
50
53
|
});
|
51
|
-
this.
|
54
|
+
this._goto_page(page, path)
|
55
|
+
},
|
56
|
+
pathIsPublic: function(path) {
|
57
|
+
return (path.indexOf([Ajax.namespace, 'private'].join('/')) === -1)
|
52
58
|
},
|
53
59
|
goto_path: function(path) {
|
54
60
|
if (path) {
|
55
61
|
// path += click_param();
|
56
|
-
this.
|
62
|
+
this.load_url(path);
|
63
|
+
}
|
64
|
+
},
|
65
|
+
goto_private: function(page) {
|
66
|
+
if (page) {
|
67
|
+
this.load_url([Ajax.namespace, 'private', page.id].join('/'));
|
57
68
|
}
|
58
69
|
},
|
70
|
+
load_url: function(url) {
|
71
|
+
this.iframe[0].contentWindow.location.href = url;
|
72
|
+
},
|
59
73
|
goto_page: function(page) {
|
60
74
|
var current = this.get('path');
|
61
75
|
if (!current || (page && (page.path !== current))) {
|
62
|
-
this.
|
76
|
+
this._goto_page(page, page.path)
|
77
|
+
}
|
78
|
+
},
|
79
|
+
_goto_page: function(page, path) {
|
80
|
+
if (page && page.private) {
|
81
|
+
this.goto_private(page);
|
82
|
+
} else {
|
83
|
+
this.goto_path(path);
|
63
84
|
}
|
64
85
|
},
|
65
86
|
hide: function() {
|
data/application/js/publish.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
// console.log('Loading Publishing...')
|
2
2
|
|
3
3
|
Spontaneous.Publishing = (function($, S) {
|
4
|
-
var dom = S.Dom, Dialogue = Spontaneous.Dialogue;
|
4
|
+
var dom = S.Dom, Dialogue = Spontaneous.Dialogue, User = S.User;
|
5
5
|
|
6
6
|
var PublishingDialogue = new JS.Class(Dialogue, {
|
7
7
|
initialize: function(content) {
|
@@ -50,6 +50,9 @@ Spontaneous.Publishing = (function($, S) {
|
|
50
50
|
},
|
51
51
|
buttons: function() {
|
52
52
|
btns = {};
|
53
|
+
if (User.is_developer()) {
|
54
|
+
btns['Rerender'] = this.rerender.bind(this);
|
55
|
+
}
|
53
56
|
btns['Publish'] = this.publish.bind(this);
|
54
57
|
return btns;
|
55
58
|
},
|
@@ -64,6 +67,9 @@ Spontaneous.Publishing = (function($, S) {
|
|
64
67
|
}
|
65
68
|
},
|
66
69
|
|
70
|
+
rerender: function() {
|
71
|
+
Spontaneous.Ajax.post('/changes/rerender', {}, this.publish_requested.bind(this));
|
72
|
+
},
|
67
73
|
|
68
74
|
publish_requested: function() {
|
69
75
|
Spontaneous.TopBar.publishing_started();
|
@@ -78,7 +84,12 @@ Spontaneous.Publishing = (function($, S) {
|
|
78
84
|
, publish_wrap = dom.div('#to-publish.change-list').css('opacity', 0)
|
79
85
|
, must_publish_all = outstanding.first_publish || outstanding.must_publish_all
|
80
86
|
, spinner = this.spinner
|
81
|
-
,
|
87
|
+
, spinnerWrap = this.spinnerWrap
|
88
|
+
, append_to
|
89
|
+
, stop_spinner = function() {
|
90
|
+
spinner.stop();
|
91
|
+
spinnerWrap.remove();
|
92
|
+
};
|
82
93
|
if (must_publish_all) {
|
83
94
|
w.addClass('first-publish');
|
84
95
|
}
|
@@ -86,6 +97,7 @@ Spontaneous.Publishing = (function($, S) {
|
|
86
97
|
var summary = dom.p('.publish-up-to-date').text('The site is up to date');
|
87
98
|
w.append(summary);
|
88
99
|
self.disable_button('Publish');
|
100
|
+
stop_spinner();
|
89
101
|
} else {
|
90
102
|
var publish_all = dom.a('.button').text('Publish All').click(function() {
|
91
103
|
self.set_publish_all(true);
|
@@ -114,8 +126,7 @@ Spontaneous.Publishing = (function($, S) {
|
|
114
126
|
if (!must_publish_all) {
|
115
127
|
publish_entries.append(dom.div('.instructions').text('Add pages to publish from the list on the left'));
|
116
128
|
}
|
117
|
-
|
118
|
-
this.spinnerWrap.remove();
|
129
|
+
stop_spinner();
|
119
130
|
w.empty();
|
120
131
|
w.append(changed_wrap, publish_wrap);
|
121
132
|
changed_wrap.add(publish_wrap).velocity({opacity: 1});
|
data/application/js/top_bar.js
CHANGED
@@ -468,22 +468,6 @@ Spontaneous.TopBar = (function($, S) {
|
|
468
468
|
var children_node = new ChildrenNode(location);
|
469
469
|
self.location.append(children_node.element());
|
470
470
|
self.children_node = children_node;
|
471
|
-
self.updateModeCompatibility(location);
|
472
|
-
},
|
473
|
-
updateModeCompatibility: function(location) {
|
474
|
-
var self = this;
|
475
|
-
if (location.private) {
|
476
|
-
self.previewModeDisabled = true;
|
477
|
-
self.mode_switch.addClass('disabled');
|
478
|
-
} else {
|
479
|
-
self.previewModeDisabled = false;
|
480
|
-
self.mode_switch.removeClass('disabled');
|
481
|
-
}
|
482
|
-
if (self.previewModeDisabled) {
|
483
|
-
this.topBar.set_mode('edit');
|
484
|
-
} else {
|
485
|
-
|
486
|
-
}
|
487
471
|
},
|
488
472
|
page_loaded: function(page) {
|
489
473
|
var self = this, children_node = self.children_node;
|
@@ -181,7 +181,7 @@ Spontaneous.Views.PieceView = (function($, S) {
|
|
181
181
|
this.fields_preview.removeClass('hover');
|
182
182
|
}
|
183
183
|
},
|
184
|
-
confirm_destroy: function() {
|
184
|
+
confirm_destroy: function(event) {
|
185
185
|
if (this._dialogue && !this._dialogue.is_open) { this.close_destroy_dialogue(); }
|
186
186
|
if (!this._dialogue) {
|
187
187
|
this._dialogue = Spontaneous.Popover.open(event, new ConfirmDeletePopup(this));
|
@@ -38,12 +38,23 @@ module Spontaneous::Asset
|
|
38
38
|
|
39
39
|
module SassFunctions
|
40
40
|
def asset_data_uri(path)
|
41
|
-
|
41
|
+
uri = sprockets_context.asset_data_uri(path.value)
|
42
|
+
Sass::Script::String.new("url(#{uri})")
|
42
43
|
end
|
43
44
|
end
|
44
45
|
|
45
46
|
::Sass::Script::Functions.send :include, SassFunctions
|
46
47
|
|
48
|
+
module RailsCompatibilityShim
|
49
|
+
# actually more a sprockets-less compatibility shim
|
50
|
+
def compute_public_path(path, root = nil)
|
51
|
+
asset_path(path)
|
52
|
+
end
|
53
|
+
|
54
|
+
def asset_paths
|
55
|
+
self
|
56
|
+
end
|
57
|
+
end
|
47
58
|
|
48
59
|
class Preview
|
49
60
|
attr_reader :environment, :site
|
@@ -83,6 +94,8 @@ module Spontaneous::Asset
|
|
83
94
|
Spontaneous::Asset::Environment.join_asset_path(make_absolute(asset.logical_path), query, fragment)
|
84
95
|
end
|
85
96
|
|
97
|
+
include RailsCompatibilityShim
|
98
|
+
|
86
99
|
def make_absolute(logical)
|
87
100
|
"/" << self.class.asset_mount_point << "/" << logical
|
88
101
|
end
|
@@ -294,6 +307,8 @@ module Spontaneous::Asset
|
|
294
307
|
Spontaneous::Asset::Environment.join_asset_path(make_absolute(asset), query, fragment)
|
295
308
|
end
|
296
309
|
|
310
|
+
include RailsCompatibilityShim
|
311
|
+
|
297
312
|
def make_absolute(logical)
|
298
313
|
"/" << self.class.asset_mount_point << "/" << logical
|
299
314
|
end
|
data/lib/spontaneous/box.rb
CHANGED
@@ -223,6 +223,8 @@ module Spontaneous
|
|
223
223
|
resolve_style(self)
|
224
224
|
end
|
225
225
|
|
226
|
+
# Container represents the object one level up from us,
|
227
|
+
# which in this case is the parent Content instance.
|
226
228
|
def container
|
227
229
|
owner
|
228
230
|
end
|
@@ -231,10 +233,62 @@ module Spontaneous
|
|
231
233
|
owner
|
232
234
|
end
|
233
235
|
|
236
|
+
# A pointer to the containing page. This may not be the same as the
|
237
|
+
# `owner` of the box in the case where the box is owned by a Piece.
|
234
238
|
def page
|
235
239
|
owner.page
|
236
240
|
end
|
237
241
|
|
242
|
+
# A convenience method to return the root of the page tree
|
243
|
+
def root
|
244
|
+
page.root
|
245
|
+
end
|
246
|
+
|
247
|
+
def site
|
248
|
+
owner.site
|
249
|
+
end
|
250
|
+
|
251
|
+
# Used to determine the page to use to define the path of any
|
252
|
+
# contained pages.
|
253
|
+
#
|
254
|
+
# Overwrite this to set up custom paths for pages.
|
255
|
+
#
|
256
|
+
# It can either return a page instance (in which case
|
257
|
+
# child pages will be based on the #path of the returned
|
258
|
+
# instance) or a string (which will form the root of the
|
259
|
+
# generated paths:
|
260
|
+
#
|
261
|
+
# Page.box :sections
|
262
|
+
#
|
263
|
+
# Page.box :custom do
|
264
|
+
# def path_origin
|
265
|
+
# root
|
266
|
+
# end
|
267
|
+
# end
|
268
|
+
#
|
269
|
+
# home = Page.create # set up a new site homepage
|
270
|
+
# section = Page.create(slug: 'a-section')
|
271
|
+
# home.sections << section # add section page to the root
|
272
|
+
# section.custom.path_origin.path #=> "/"
|
273
|
+
#
|
274
|
+
# child = Page.create(slug: 'child')
|
275
|
+
# section.custom << child
|
276
|
+
# child.path #=> "/child" # this would normally be "/a-section/child"
|
277
|
+
#
|
278
|
+
def path_origin
|
279
|
+
page
|
280
|
+
end
|
281
|
+
|
282
|
+
# This is used by new pages to generate the path component of the container.
|
283
|
+
def path!
|
284
|
+
case (origin = path_origin)
|
285
|
+
when @owner.content_model
|
286
|
+
origin.path!
|
287
|
+
else
|
288
|
+
origin.to_s
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
238
292
|
alias_method :to_page, :page
|
239
293
|
|
240
294
|
def depth
|
@@ -275,6 +329,14 @@ module Spontaneous
|
|
275
329
|
@modified
|
276
330
|
end
|
277
331
|
|
332
|
+
# Returns a list of the ids of the content within the box
|
333
|
+
#
|
334
|
+
# This is designed to be fast by not requiring the actual
|
335
|
+
# loading of the box contents.
|
336
|
+
def ids
|
337
|
+
owner.contents.ids(self)
|
338
|
+
end
|
339
|
+
|
278
340
|
def contents
|
279
341
|
owner.contents.for_box(self)
|
280
342
|
end
|
@@ -297,6 +359,12 @@ module Spontaneous
|
|
297
359
|
end
|
298
360
|
end
|
299
361
|
|
362
|
+
def clear!
|
363
|
+
contents.dup.each do |entry|
|
364
|
+
entry.destroy
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
300
368
|
def empty?
|
301
369
|
contents.count == 0
|
302
370
|
end
|