spontaneous 0.2.0.beta9 → 0.2.0.beta10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
@@ -53,6 +53,12 @@ module Spontaneous
|
|
53
53
|
def export(user)
|
54
54
|
{}
|
55
55
|
end
|
56
|
+
|
57
|
+
# Allows for field type classes to map a human readable default value
|
58
|
+
# to the correct serialized value
|
59
|
+
def make_default_value(instance, value)
|
60
|
+
value
|
61
|
+
end
|
56
62
|
end
|
57
63
|
|
58
64
|
extend ClassMethods
|
@@ -380,6 +386,10 @@ module Spontaneous
|
|
380
386
|
self.prototype.owner
|
381
387
|
end
|
382
388
|
|
389
|
+
def site
|
390
|
+
owner.try(:site)
|
391
|
+
end
|
392
|
+
|
383
393
|
def owner_sid
|
384
394
|
schema_owner.schema_id
|
385
395
|
end
|
@@ -7,6 +7,12 @@ module Spontaneous::Field
|
|
7
7
|
class File < Base
|
8
8
|
has_editor
|
9
9
|
|
10
|
+
def blank?
|
11
|
+
values[:path].blank?
|
12
|
+
end
|
13
|
+
|
14
|
+
alias_method :empty?, :blank?
|
15
|
+
|
10
16
|
# In the case of clearing the field we will have been given a pending_value of ""
|
11
17
|
# we don't want that to run asynchronously
|
12
18
|
def asynchronous?
|
@@ -15,7 +21,7 @@ module Spontaneous::Field
|
|
15
21
|
end
|
16
22
|
|
17
23
|
def outputs
|
18
|
-
[:html, :path, :filesize, :filename]
|
24
|
+
[:html, :path, :filesize, :filename, :storage_name]
|
19
25
|
end
|
20
26
|
|
21
27
|
def set_pending_value(value, site)
|
@@ -115,6 +121,17 @@ module Spontaneous::Field
|
|
115
121
|
generate_path(input, site)
|
116
122
|
end
|
117
123
|
|
124
|
+
def generate_storage_name(input, site)
|
125
|
+
if (storage = input.try(:storage))
|
126
|
+
return storage.name
|
127
|
+
end
|
128
|
+
nil
|
129
|
+
end
|
130
|
+
|
131
|
+
def storage
|
132
|
+
site.storage(storage_name)
|
133
|
+
end
|
134
|
+
|
118
135
|
def export(user = nil)
|
119
136
|
super(user).merge({
|
120
137
|
:processed_value => processed_values
|
@@ -133,8 +150,21 @@ module Spontaneous::Field
|
|
133
150
|
@file_info ||= Spontaneous::JSON.parse(unprocessed_value)
|
134
151
|
end
|
135
152
|
|
153
|
+
def value(format = :html)
|
154
|
+
case format
|
155
|
+
when :html, "html"
|
156
|
+
path
|
157
|
+
else
|
158
|
+
super
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
136
162
|
def path
|
137
|
-
|
163
|
+
storage.to_url(super)
|
164
|
+
end
|
165
|
+
|
166
|
+
def url
|
167
|
+
path
|
138
168
|
end
|
139
169
|
|
140
170
|
self.register
|
@@ -46,12 +46,26 @@ module Spontaneous::Field
|
|
46
46
|
[ {}, proc { width 300 } ]
|
47
47
|
end
|
48
48
|
|
49
|
+
def self.default_attributes
|
50
|
+
@default_attributes ||= {}
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.default_attributes=(default_attributes = {})
|
54
|
+
@default_attributes = default_attributes
|
55
|
+
end
|
56
|
+
|
49
57
|
def image?
|
50
58
|
true
|
51
59
|
end
|
52
60
|
|
61
|
+
def blank?
|
62
|
+
original.blank?
|
63
|
+
end
|
64
|
+
|
53
65
|
def sizes
|
54
|
-
@sizes ||= Hash.new { |hash, key|
|
66
|
+
@sizes ||= Hash.new { |hash, key|
|
67
|
+
hash[key] = S::Media::Image::Attributes.new(site, processed_values[key])
|
68
|
+
}
|
55
69
|
end
|
56
70
|
|
57
71
|
# value used to show conflicts between the current value and the value they're attempting to enter
|
@@ -93,6 +107,10 @@ module Spontaneous::Field
|
|
93
107
|
original.src
|
94
108
|
end
|
95
109
|
|
110
|
+
def url
|
111
|
+
original.url
|
112
|
+
end
|
113
|
+
|
96
114
|
def filepath
|
97
115
|
unprocessed_value
|
98
116
|
end
|
@@ -122,8 +140,12 @@ module Spontaneous::Field
|
|
122
140
|
|
123
141
|
|
124
142
|
def export(user = nil)
|
143
|
+
processed = Hash[outputs.map { |size|
|
144
|
+
[size, sizes[size].export(user)]
|
145
|
+
}]
|
146
|
+
processed.update(__pending__: pending_value) if has_pending_value?
|
125
147
|
super(user).merge({
|
126
|
-
:
|
148
|
+
processed_value: processed
|
127
149
|
})
|
128
150
|
end
|
129
151
|
|
@@ -78,6 +78,14 @@ module Spontaneous::Field
|
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
81
|
+
# Maps a configured default value to the appropriate JSON encoded [value, label] array
|
82
|
+
def self.make_default_value(instance, value)
|
83
|
+
return nil if value.blank?
|
84
|
+
option = option_list(instance.owner).detect { |opt, label| opt == value }
|
85
|
+
return nil if option.nil?
|
86
|
+
Spontaneous::JSON.encode option
|
87
|
+
end
|
88
|
+
|
81
89
|
def option_list
|
82
90
|
self.class.option_list(self.owner)
|
83
91
|
end
|
@@ -75,6 +75,10 @@ module Spontaneous::Field
|
|
75
75
|
hash[k] = 0 if v == false
|
76
76
|
}
|
77
77
|
end
|
78
|
+
|
79
|
+
def name
|
80
|
+
self.class.id
|
81
|
+
end
|
78
82
|
end
|
79
83
|
|
80
84
|
def self.providers
|
@@ -151,6 +155,10 @@ module Spontaneous::Field
|
|
151
155
|
src
|
152
156
|
end
|
153
157
|
|
158
|
+
def aspect_ratio
|
159
|
+
values.fetch(:width, 1).to_f / values.fetch(:height, 1).to_f
|
160
|
+
end
|
161
|
+
|
154
162
|
self.register(:webvideo)
|
155
163
|
end
|
156
164
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# The following controls the default render output or image fields.
|
2
|
+
#
|
3
|
+
# By default inserting an image field instance into a template like this:
|
4
|
+
#
|
5
|
+
# ${ image }
|
6
|
+
#
|
7
|
+
# will output an `img` tag with the image's `src` attribute and an empty `alt`
|
8
|
+
# value:
|
9
|
+
#
|
10
|
+
# <img src="/path/to/image.jpg" alt="" />
|
11
|
+
#
|
12
|
+
# You can override the default attributes by setting an options hash here:
|
13
|
+
#
|
14
|
+
Spontaneous::Field::Image.default_attributes = {
|
15
|
+
# Include the image's natural width & height by default when rendering an image field
|
16
|
+
# size: true,
|
17
|
+
|
18
|
+
# Include only the images’ natural width
|
19
|
+
# `true`, `:auto` or `'auto'` are equivalent
|
20
|
+
|
21
|
+
# width: true,
|
22
|
+
|
23
|
+
# Force all images to render at a fixed width (odd but possible)
|
24
|
+
|
25
|
+
# width: 42,
|
26
|
+
|
27
|
+
# Or the same for the image height:
|
28
|
+
|
29
|
+
# height: true,
|
30
|
+
# height: 42,
|
31
|
+
|
32
|
+
# Set a default alt attribute (not generally recommended)
|
33
|
+
|
34
|
+
# alt: 'Inappropriate',
|
35
|
+
|
36
|
+
# Or, more usefully, if you want to use a dynamic value based on the field
|
37
|
+
# being rendered then pass a proc
|
38
|
+
|
39
|
+
# alt: proc { |field| field.page.title },
|
40
|
+
|
41
|
+
# Or you can set any attribute you want by just adding it in here:
|
42
|
+
|
43
|
+
# crossorigin: 'crossorigin',
|
44
|
+
|
45
|
+
# If you want to set data attributes then you can pass a hash, e.g. to add a data-id attribute
|
46
|
+
# based on the images’ owning page e.g.
|
47
|
+
#
|
48
|
+
# <img src="..." alt="..." data-id="1234" />
|
49
|
+
#
|
50
|
+
# You would set a data attribute thusly:
|
51
|
+
|
52
|
+
# data: {
|
53
|
+
# id: proc { |field| field.owner.page.id }
|
54
|
+
# },
|
55
|
+
}
|
data/lib/spontaneous/json.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
require 'yajl'
|
3
|
+
# require 'yajl'
|
4
|
+
require 'oj'
|
4
5
|
|
5
6
|
Oj.default_options = { mode: :compat } if defined?(Oj)
|
6
7
|
|
@@ -23,7 +24,7 @@ module Spontaneous
|
|
23
24
|
if defined?(::Yajl)
|
24
25
|
module YajlParser
|
25
26
|
def parser
|
26
|
-
Yajl::Parser.new(:
|
27
|
+
Yajl::Parser.new(symbolize_keys: true)
|
27
28
|
end
|
28
29
|
def encoder
|
29
30
|
Yajl::Encoder.new
|
data/lib/spontaneous/logger.rb
CHANGED
@@ -136,8 +136,8 @@ module Spontaneous
|
|
136
136
|
# Setup a new logger with options
|
137
137
|
#
|
138
138
|
def self.setup(options = {})
|
139
|
-
config_level = (SPOT_LOG_LEVEL || Spontaneous.env || :
|
140
|
-
config = Config[config_level]
|
139
|
+
config_level = (SPOT_LOG_LEVEL || Spontaneous.env || :production).to_sym # need this for SPOT_LOG_LEVEL
|
140
|
+
config = Config[config_level] || Config[:production] # default to a production level
|
141
141
|
stream = \
|
142
142
|
if logfile = options[:logfile]
|
143
143
|
FileUtils.mkdir_p(File.dirname(logfile)) unless File.directory?(File.dirname(logfile))
|
@@ -41,7 +41,7 @@ module Spontaneous::Media
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def url
|
44
|
-
storage.
|
44
|
+
storage.url_path(storage_path)
|
45
45
|
end
|
46
46
|
|
47
47
|
def mimetype
|
@@ -59,7 +59,7 @@ module Spontaneous::Media
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def storage
|
62
|
-
@storage ||= @site.
|
62
|
+
@storage ||= @site.storage_for_mimetype(mimetype)
|
63
63
|
end
|
64
64
|
|
65
65
|
def padded_id
|
@@ -95,7 +95,7 @@ module Spontaneous::Media
|
|
95
95
|
end
|
96
96
|
|
97
97
|
def serialize
|
98
|
-
{ :
|
98
|
+
{ url: url, type: mimetype, filename: filename, storage_name: storage.name }
|
99
99
|
end
|
100
100
|
end
|
101
101
|
end
|
@@ -3,15 +3,19 @@ module Spontaneous::Media
|
|
3
3
|
class Attributes
|
4
4
|
include Renderable
|
5
5
|
|
6
|
-
attr_reader :
|
6
|
+
attr_reader :storage, :filepath, :storage
|
7
7
|
|
8
|
-
def initialize(params={})
|
9
|
-
params
|
10
|
-
@
|
8
|
+
def initialize(site, params={})
|
9
|
+
@params = params.try(:dup) || {}
|
10
|
+
@storage = site.storage(storage_name)
|
11
11
|
end
|
12
12
|
|
13
13
|
def serialize
|
14
|
-
{ :
|
14
|
+
{ src: src, width: width, height: height, dimensions: dimensions, filesize: filesize, storage_name: storage_name }
|
15
|
+
end
|
16
|
+
|
17
|
+
def export(user = nil)
|
18
|
+
serialize.delete_if { |k, v| v.nil? }
|
15
19
|
end
|
16
20
|
|
17
21
|
def inspect
|
@@ -19,7 +23,69 @@ module Spontaneous::Media
|
|
19
23
|
end
|
20
24
|
|
21
25
|
def blank?
|
22
|
-
src.blank?
|
26
|
+
@params[:src].blank?
|
27
|
+
end
|
28
|
+
|
29
|
+
alias_method :empty?, :blank?
|
30
|
+
|
31
|
+
def src
|
32
|
+
storage.to_url(@params[:src])
|
33
|
+
end
|
34
|
+
|
35
|
+
alias_method :url, :src
|
36
|
+
|
37
|
+
def storage_name
|
38
|
+
@params[:storage_name]
|
39
|
+
end
|
40
|
+
|
41
|
+
def width
|
42
|
+
@params[:width]
|
43
|
+
end
|
44
|
+
|
45
|
+
def height
|
46
|
+
@params[:height]
|
47
|
+
end
|
48
|
+
|
49
|
+
def filesize
|
50
|
+
@params[:filesize]
|
51
|
+
end
|
52
|
+
|
53
|
+
def dimensions
|
54
|
+
@params[:dimensions]
|
55
|
+
end
|
56
|
+
|
57
|
+
def filepath
|
58
|
+
@params[:path]
|
59
|
+
end
|
60
|
+
|
61
|
+
def src
|
62
|
+
storage.to_url(@params[:src])
|
63
|
+
end
|
64
|
+
|
65
|
+
alias_method :url, :src
|
66
|
+
|
67
|
+
def storage_name
|
68
|
+
@params[:storage_name]
|
69
|
+
end
|
70
|
+
|
71
|
+
def width
|
72
|
+
@params[:width]
|
73
|
+
end
|
74
|
+
|
75
|
+
def height
|
76
|
+
@params[:height]
|
77
|
+
end
|
78
|
+
|
79
|
+
def filesize
|
80
|
+
@params[:filesize]
|
81
|
+
end
|
82
|
+
|
83
|
+
def dimensions
|
84
|
+
@params[:dimensions]
|
85
|
+
end
|
86
|
+
|
87
|
+
def filepath
|
88
|
+
@params[:path]
|
23
89
|
end
|
24
90
|
|
25
91
|
# Will only work for files in local storage
|
@@ -14,32 +14,65 @@ module Spontaneous::Media::Image
|
|
14
14
|
|
15
15
|
alias_method :render_inline, :render
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
}
|
24
|
-
default_attr.delete(:width) if (width.nil? || width == 0)
|
25
|
-
default_attr.delete(:height) if (height.nil? || height == 0)
|
17
|
+
DEFAULT_SIZE_FLAGS = ['auto'.freeze, :auto, true].freeze
|
18
|
+
|
19
|
+
def to_html(opts={})
|
20
|
+
default_attr = { src: src, alt: "" }
|
21
|
+
attrs = Spontaneous::Field::Image.default_attributes.merge(opts)
|
22
|
+
|
26
23
|
if template_params && template_params.length > 0 && template_params[0].is_a?(Hash)
|
27
|
-
|
24
|
+
attrs = template_params[0].merge(attrs)
|
25
|
+
end
|
26
|
+
|
27
|
+
case attrs.delete(:size)
|
28
|
+
when true, :auto, 'auto'
|
29
|
+
attrs[:width] = width if has_width?
|
30
|
+
attrs[:height] = height if has_height?
|
28
31
|
end
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
|
33
|
+
if attrs.key?(:width) || attrs.key?(:height)
|
34
|
+
attrs.delete(:width) if (attrs.key?(:width) && !attrs[:width])
|
35
|
+
attrs.delete(:height) if (attrs.key?(:height) && !attrs[:height])
|
36
|
+
if has_width? && DEFAULT_SIZE_FLAGS.include?(attrs[:width])
|
37
|
+
attrs[:width] = width
|
38
|
+
end
|
39
|
+
if has_height? && DEFAULT_SIZE_FLAGS.include?(attrs[:height])
|
40
|
+
attrs[:height] = height
|
35
41
|
end
|
36
42
|
end
|
37
|
-
|
43
|
+
|
44
|
+
attrs = default_attr.merge(attrs)
|
45
|
+
params = parameterize_attributes(attrs)
|
46
|
+
%(<img #{params} />)
|
47
|
+
end
|
48
|
+
|
49
|
+
def parameterize_attributes(attrs, namespace = [])
|
38
50
|
params = []
|
39
|
-
|
40
|
-
|
51
|
+
attrs.each do |name, value|
|
52
|
+
key = (namespace + [name])
|
53
|
+
v = case value
|
54
|
+
when Hash
|
55
|
+
parameterize_attributes(value, key)
|
56
|
+
when Proc
|
57
|
+
%(#{key.join('-')}="#{value.call(self).to_s.escape_html}")
|
58
|
+
else
|
59
|
+
%(#{key.join('-')}="#{value.to_s.escape_html}")
|
60
|
+
end
|
61
|
+
params << v
|
41
62
|
end
|
42
|
-
|
63
|
+
params.join(' ')
|
64
|
+
end
|
65
|
+
|
66
|
+
def has_height?
|
67
|
+
has_dim?(height)
|
68
|
+
end
|
69
|
+
|
70
|
+
def has_width?
|
71
|
+
has_dim?(width)
|
72
|
+
end
|
73
|
+
|
74
|
+
def has_dim?(dim)
|
75
|
+
!(dim.nil? || dim == 0)
|
43
76
|
end
|
44
77
|
|
45
78
|
def to_s
|