scrivito_sdk 0.30.0 → 0.40.0.rc1
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/app/controllers/scrivito/objs_controller.rb +29 -20
- data/app/controllers/scrivito/ui_controller.rb +18 -0
- data/app/helpers/scrivito_helper.rb +21 -4
- data/app/views/scrivito/objs/obj.json.jbuilder +1 -0
- data/app/views/scrivito/objs/update.json.jbuilder +1 -1
- data/app/views/scrivito/ui/index.html.erb +13 -0
- data/config/ca-bundle.crt +565 -3
- data/config/routes.rb +4 -0
- data/lib/assets/javascripts/scrivito_sdk.js +28 -19545
- data/lib/assets/javascripts/scrivito_ui.js +30398 -0
- data/lib/assets/stylesheets/scrivito_sdk.css +228 -232
- data/lib/assets/stylesheets/scrivito_ui.css +3148 -0
- data/lib/generators/scrivito/install/install_generator.rb +4 -0
- data/lib/generators/scrivito/install/templates/app/views/layouts/scrivito_dialog.html.erb +13 -0
- data/lib/generators/scrivito/page/templates/details.html.erb +1 -1
- data/lib/generators/scrivito/widget/templates/details.html.erb +1 -1
- data/lib/generators/scrivito/widget/templates/show.html.erb +1 -1
- data/lib/generators/scrivito/widget/templates/thumbnail.html.erb +2 -2
- data/lib/generators/scrivito/widget/widget_generator.rb +12 -0
- data/lib/scrivito/attribute_content.rb +4 -5
- data/lib/scrivito/basic_obj.rb +47 -8
- data/lib/scrivito/basic_widget.rb +41 -14
- data/lib/scrivito/cache.rb +2 -0
- data/lib/scrivito/child_list_tag.rb +1 -1
- data/lib/scrivito/client_config.rb +9 -11
- data/lib/scrivito/cms_backend.rb +5 -4
- data/lib/scrivito/cms_field_tag.rb +6 -2
- data/lib/scrivito/cms_rest_api/attribute_serializer.rb +2 -0
- data/lib/scrivito/cms_rest_api/widget_extractor.rb +5 -5
- data/lib/scrivito/connection_manager.rb +1 -0
- data/lib/scrivito/controller_actions.rb +24 -3
- data/lib/scrivito/image_tag_helper.rb +0 -12
- data/lib/scrivito/layout_tags.rb +1 -8
- data/lib/scrivito/link_parser.rb +5 -0
- data/lib/scrivito/{memberships_collection.rb → membership_collection.rb} +2 -2
- data/lib/scrivito/obj_class.rb +3 -6
- data/lib/scrivito/{objs_collection.rb → obj_collection.rb} +1 -1
- data/lib/scrivito/obj_create_params_parser.rb +15 -0
- data/lib/scrivito/obj_params_parser.rb +37 -45
- data/lib/scrivito/obj_update_params_parser.rb +25 -0
- data/lib/scrivito/revision.rb +6 -2
- data/lib/scrivito/sdk_engine.rb +6 -1
- data/lib/scrivito/test_request.rb +4 -0
- data/lib/scrivito/uploaded_binary.rb +4 -0
- data/lib/scrivito/user.rb +8 -0
- data/lib/scrivito/widget_collection.rb +22 -0
- data/lib/scrivito/workspace.rb +11 -6
- metadata +17 -11
- data/app/views/scrivito/objs/copy.json.jbuilder +0 -1
- data/app/views/scrivito/objs/create.json.jbuilder +0 -1
- data/app/views/scrivito/objs/details.json.jbuilder +0 -1
- data/lib/scrivito/widget_field_params.rb +0 -61
@@ -22,6 +22,10 @@ module Scrivito
|
|
22
22
|
copy_file 'app/controllers/cms_controller.rb'
|
23
23
|
end
|
24
24
|
|
25
|
+
def copy_dialog_layout
|
26
|
+
copy_file 'app/views/layouts/scrivito_dialog.html.erb'
|
27
|
+
end
|
28
|
+
|
25
29
|
def copy_migration
|
26
30
|
migration_template 'scrivito/migrate/install_scrivito_migration.rb',
|
27
31
|
File.join(Scrivito::Configuration.migration_path, 'install_scrivito_migration.rb')
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<%= scrivito_head_tags %>
|
5
|
+
<%= stylesheet_link_tag 'application', media: 'all' %>
|
6
|
+
<%= csrf_meta_tags %>
|
7
|
+
</head>
|
8
|
+
<body class="scrivito_dialog">
|
9
|
+
<%= scrivito_body_tags %>
|
10
|
+
<%= yield %>
|
11
|
+
<%= javascript_include_tag 'application' %>
|
12
|
+
</body>
|
13
|
+
</html>
|
@@ -1 +1 @@
|
|
1
|
-
<%= scrivito_tag :div, @obj, :title %>
|
1
|
+
<b>Title:</b> <%= scrivito_tag :div, @obj, :title %>
|
@@ -1,2 +1,2 @@
|
|
1
|
-
This is the details view of the <%=
|
1
|
+
This is the details view of the <%= human_name %>.
|
2
2
|
Edit "app/views/<%= file_name %>/details.html.erb" to change its appearance.
|
@@ -1,2 +1,2 @@
|
|
1
|
-
This is the show view of the <%=
|
1
|
+
This is the show view of the <%= human_name %>.
|
2
2
|
Edit "app/views/<%= file_name %>/show.html.erb" to change its appearance.
|
@@ -1,3 +1,3 @@
|
|
1
|
-
<%%= scrivito_thumbnail '<%=
|
2
|
-
|
1
|
+
<%%= scrivito_thumbnail '<%= human_name %>' do %>
|
2
|
+
<!-- Add the detailed description of the widget here. -->
|
3
3
|
<%% end %>
|
@@ -23,6 +23,18 @@ module Scrivito
|
|
23
23
|
migration_template 'migration.erb',
|
24
24
|
File.join(Scrivito::Configuration.migration_path, "create_#{file_name}_migration.rb")
|
25
25
|
end
|
26
|
+
|
27
|
+
def file_name
|
28
|
+
super.ends_with?('_widget') ? super : "#{super}_widget"
|
29
|
+
end
|
30
|
+
|
31
|
+
def class_name
|
32
|
+
super.ends_with?('Widget') ? super : "#{super}Widget"
|
33
|
+
end
|
34
|
+
|
35
|
+
def human_name
|
36
|
+
class_name.underscore.humanize
|
37
|
+
end
|
26
38
|
end
|
27
39
|
end
|
28
40
|
end
|
@@ -59,16 +59,15 @@ module AttributeContent
|
|
59
59
|
has_attribute?(key) ? read_attribute(key) : nil
|
60
60
|
end
|
61
61
|
|
62
|
-
# Hook method to control which widget classes should be available for this page
|
63
|
-
# Override it to allow only certain classes or none.
|
62
|
+
# Hook method to control which widget classes should be available for this page
|
63
|
+
# or widget. Override it to allow only certain classes or none.
|
64
64
|
# Must return either +NilClass+, or +Array+.
|
65
65
|
#
|
66
|
-
# If +nil+ is returned (default), then all widget classes will be available for this page.
|
66
|
+
# If +nil+ is returned (default), then all widget classes will be available for this page or widget.
|
67
67
|
#
|
68
68
|
# If +Array+ is returned, then it should include desired class names.
|
69
69
|
# Each class name must be either a +String+ or a +Symbol+.
|
70
|
-
# Only
|
71
|
-
# Order of the class names will be preserved.
|
70
|
+
# Only these class names will be available and their order will be preserved.
|
72
71
|
#
|
73
72
|
# @param [String] field_name Name of the widget field.
|
74
73
|
# @return [nil, Array<Symbol, String>]
|
data/lib/scrivito/basic_obj.rb
CHANGED
@@ -76,12 +76,12 @@ module Scrivito
|
|
76
76
|
# @example Arrays of {String Strings} allow you to set multi enum fields
|
77
77
|
# Obj.create(:tags => ["ruby", "rails"])
|
78
78
|
#
|
79
|
-
# @example Simply pass an Array of {Scrivito::BasicWidget Widgets} to change a widget field. See {Scrivito::BasicWidget#
|
79
|
+
# @example Simply pass an Array of {Scrivito::BasicWidget Widgets} to change a widget field. See {Scrivito::BasicWidget#copy Widget#copy} on how to copy a widget.
|
80
80
|
# # Add new widgets
|
81
81
|
# Obj.create(:widgets => [Widget.new(_obj_class: 'TitleWidget', title: 'My Title')])
|
82
82
|
#
|
83
|
-
# # Add a widget
|
84
|
-
# Obj.create(:widgets => [another_obj.widgets.first.
|
83
|
+
# # Add a widget copy
|
84
|
+
# Obj.create(:widgets => [another_obj.widgets.first.copy])
|
85
85
|
#
|
86
86
|
# # Changing a widget field
|
87
87
|
# obj.update(:widgets => [obj.widgets.first])
|
@@ -304,7 +304,7 @@ module Scrivito
|
|
304
304
|
self
|
305
305
|
end
|
306
306
|
|
307
|
-
#
|
307
|
+
# Creates a copy of the +Obj+.
|
308
308
|
# @api public
|
309
309
|
# @param [Hash] options
|
310
310
|
# @option options [String,Symbol] :_path (nil) the path of the copy.
|
@@ -315,7 +315,7 @@ module Scrivito
|
|
315
315
|
# @example Copy a blog post.
|
316
316
|
# blog_post = Obj.find_by_path('/blog/first_post')
|
317
317
|
# blog_post.copy(_path: '/blog/second_post')
|
318
|
-
def copy(options)
|
318
|
+
def copy(options={})
|
319
319
|
options = options.stringify_keys.assert_valid_keys('_path', '_id', '_permalink')
|
320
320
|
json = workspace.api_request(:post, '/objs', obj: copyable_attributes.merge(options))
|
321
321
|
self.class.find(json['_id'])
|
@@ -390,7 +390,7 @@ module Scrivito
|
|
390
390
|
BasicObj.find_by_path('/') or raise ResourceNotFound,
|
391
391
|
'"Obj.root" not found: There is no "Obj" with path "/". '\
|
392
392
|
'Maybe you forgot the migration when setting up your Scrivito application? '\
|
393
|
-
'Try "rake scrivito:migrate
|
393
|
+
'Try "bundle exec rake scrivito:migrate scrivito:migrate:publish".'
|
394
394
|
end
|
395
395
|
|
396
396
|
# Returns the homepage obj. This can be overwritten in your application's +Obj+.
|
@@ -720,6 +720,17 @@ module Scrivito
|
|
720
720
|
instantiate_widget(widget_id, widget_data) if widget_data
|
721
721
|
end
|
722
722
|
|
723
|
+
# @api public
|
724
|
+
# Allows accessing the {Scrivito::BasicWidget Widgets} of this Obj
|
725
|
+
#
|
726
|
+
# @example Access a widget by its id
|
727
|
+
# obj.widgets['widget_id']
|
728
|
+
#
|
729
|
+
# @return [Scrivito::WidgetCollection]
|
730
|
+
def widgets
|
731
|
+
@widgets ||= WidgetCollection.new(self)
|
732
|
+
end
|
733
|
+
|
723
734
|
# for internal testing purposes only
|
724
735
|
def blob_id
|
725
736
|
find_blob.try(:id)
|
@@ -756,6 +767,30 @@ module Scrivito
|
|
756
767
|
end
|
757
768
|
end
|
758
769
|
|
770
|
+
def restore_widget(widget_id)
|
771
|
+
Workspace.current.assert_revertable
|
772
|
+
|
773
|
+
return if modification == Modification::UNMODIFIED
|
774
|
+
if modification == Modification::DELETED
|
775
|
+
raise ScrivitoError, 'Can not restore a widget inside a deleted obj'
|
776
|
+
end
|
777
|
+
|
778
|
+
unless widget = in_revision(Workspace.current.base_revision).widgets[widget_id]
|
779
|
+
raise ResourceNotFound, "Could not find widget with id #{widget_id}"
|
780
|
+
end
|
781
|
+
|
782
|
+
container = widget.container
|
783
|
+
if container.kind_of?(BasicWidget) && !widgets[container.id]
|
784
|
+
raise ScrivitoError, 'Can not restore a widget inside a deleted widget'
|
785
|
+
end
|
786
|
+
|
787
|
+
widget_copy = widget.copy_for_restore(read_widget_pool.keys)
|
788
|
+
field_name = widget.container_field_name
|
789
|
+
current_container = widgets[container.id] || self
|
790
|
+
current_container.update(field_name =>
|
791
|
+
current_container[field_name].insert(widget.container_field_index, widget_copy))
|
792
|
+
end
|
793
|
+
|
759
794
|
def mark_resolved
|
760
795
|
workspace.api_request(:put, "/objs/#{id}", obj: {_conflicts: nil})
|
761
796
|
reload
|
@@ -802,10 +837,13 @@ module Scrivito
|
|
802
837
|
raise ScrivitoError.new('Could not generate a new unused widget id')
|
803
838
|
end
|
804
839
|
|
840
|
+
#
|
805
841
|
# Generates a +Hash+ containing all public attributes. The hash will _not_ include attributes,
|
806
842
|
# which are read-only or used for internal purpose.
|
807
|
-
#
|
843
|
+
#
|
844
|
+
# @api private
|
808
845
|
# @return [Hash] a hash containing all public attributes.
|
846
|
+
#
|
809
847
|
# @example
|
810
848
|
# old_obj = Obj.homepage
|
811
849
|
# attrs = old_obj.to_h
|
@@ -816,12 +854,13 @@ module Scrivito
|
|
816
854
|
# new_obj = Obj.create(attrs)
|
817
855
|
# puts new_obj == old_obj
|
818
856
|
# #=> true
|
857
|
+
#
|
819
858
|
def to_h
|
820
859
|
data_from_cms.to_h.except(*GENERATED_ATTRIBUTES)
|
821
860
|
end
|
822
861
|
|
823
862
|
def parent_path
|
824
|
-
unless root?
|
863
|
+
unless root? || path.nil?
|
825
864
|
path.gsub(/\/[^\/]+$/, '').presence || '/'
|
826
865
|
end
|
827
866
|
end
|
@@ -66,25 +66,42 @@ class BasicWidget
|
|
66
66
|
container.update(container_field_name => new_widget_list)
|
67
67
|
end
|
68
68
|
|
69
|
-
# Clones the {Scrivito::BasicWidget Widget}. The clone gets all
|
70
|
-
# attributes of the original widget except nested widget attributes.
|
71
|
-
# The clone is not attached to an {Scrivito::BasicObj Obj} initially.
|
72
|
-
# It only becomes usable by assigning it to a widget attribute of an Obj.
|
73
69
|
#
|
74
|
-
#
|
75
|
-
# # From another_obj, take the first widget in my_widgets,
|
76
|
-
# # and put a clone in obj's my_widgets.
|
77
|
-
# obj.update(my_widgets: [another_obj.my_widgets.first.clone])
|
70
|
+
# Create a copy of a {Scrivito::BasicWidget Widget}.
|
78
71
|
#
|
79
72
|
# @api public
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
73
|
+
#
|
74
|
+
# The copy will have all attributes of the original widget including its widgets.
|
75
|
+
# Its attributes can be accessed only after it has been stored in a widget field of an
|
76
|
+
# {Scrivito::BasicObj Obj}, since initially the copy is not stored in any widget field.
|
77
|
+
#
|
78
|
+
# @example Duplicate the first widget in field +my_widget+
|
79
|
+
# obj.update(my_widgets: obj.my_widgets.push(obj.my_widgets.first.copy))
|
80
|
+
#
|
81
|
+
def copy
|
82
|
+
attrs = {}
|
83
|
+
each_custom_attribute do |attr_name, attr_value, attr_type|
|
84
|
+
attrs[attr_name] = attr_type == 'widget' ? attr_value.map(&:copy) : attr_value
|
85
|
+
end
|
86
|
+
self.class.new(attrs)
|
87
|
+
end
|
88
|
+
|
89
|
+
def copy_for_restore(referenced_ids)
|
90
|
+
attrs = {}
|
91
|
+
each_custom_attribute do |attr_name, attr_value, attr_type|
|
92
|
+
attrs[attr_name] = if attr_type == 'widget'
|
93
|
+
attr_value.reject { |widget| referenced_ids.include?(widget.id) }
|
94
|
+
.map { |widget| widget.copy_for_restore(referenced_ids) }
|
95
|
+
else
|
96
|
+
attr_value
|
85
97
|
end
|
86
98
|
end
|
87
|
-
|
99
|
+
attrs['_id'] = id
|
100
|
+
self.class.new(attrs)
|
101
|
+
end
|
102
|
+
|
103
|
+
def clone
|
104
|
+
raise "The method `clone' was removed. Please use `copy' instead"
|
88
105
|
end
|
89
106
|
|
90
107
|
def id
|
@@ -193,6 +210,10 @@ class BasicWidget
|
|
193
210
|
@container_field_name || cache_container_and_field_name_for_widget.second
|
194
211
|
end
|
195
212
|
|
213
|
+
def container_field_index
|
214
|
+
container[container_field_name].index(self)
|
215
|
+
end
|
216
|
+
|
196
217
|
def has_attribute?(key)
|
197
218
|
key.to_s == '_obj_class' || super
|
198
219
|
end
|
@@ -265,6 +286,12 @@ class BasicWidget
|
|
265
286
|
def cache_container_and_field_name_for_widget
|
266
287
|
@cache_container_and_field_name_for_widget ||= obj.container_and_field_name_for_widget(id)
|
267
288
|
end
|
289
|
+
|
290
|
+
def each_custom_attribute
|
291
|
+
data_from_cms.all_custom_attributes.each do |attr_name|
|
292
|
+
yield attr_name, read_attribute(attr_name), type_of_attribute(attr_name)
|
293
|
+
end
|
294
|
+
end
|
268
295
|
end
|
269
296
|
|
270
297
|
end
|
data/lib/scrivito/cache.rb
CHANGED
@@ -11,7 +11,7 @@ class ChildListTag < Struct.new(:tag_name, :obj, :field_name, :view)
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def options
|
14
|
-
return {} unless user_present?
|
14
|
+
return {} unless user_present? || obj.path.nil?
|
15
15
|
|
16
16
|
options = {
|
17
17
|
'private-child-list-allowed-classes' => Obj.valid_page_classes_beneath(obj.path).to_json,
|
@@ -7,9 +7,9 @@ class ClientConfig < Struct.new(:obj, :editing_context, :lookup_context, :resour
|
|
7
7
|
|
8
8
|
def to_json
|
9
9
|
config = {}
|
10
|
+
config[:current_page] = current_page_config
|
10
11
|
config[:editing_context] = editing_context_config
|
11
12
|
config[:i18n] = i18n_config
|
12
|
-
config[:obj] = obj_config
|
13
13
|
config[:resource_dialog] = resource_dialog_config
|
14
14
|
config[:user] = user_config
|
15
15
|
config[:user_permissions] = user_permissions_config
|
@@ -39,18 +39,16 @@ class ClientConfig < Struct.new(:obj, :editing_context, :lookup_context, :resour
|
|
39
39
|
{locale: I18n.locale}
|
40
40
|
end
|
41
41
|
|
42
|
-
def
|
42
|
+
def current_page_config
|
43
43
|
if obj
|
44
44
|
{
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
restriction_messages: editor.restriction_messages_for(obj),
|
53
|
-
}
|
45
|
+
id: obj.id,
|
46
|
+
obj_class_name: obj.obj_class_name,
|
47
|
+
has_children: obj.children.any?,
|
48
|
+
has_conflict: obj.has_conflict?,
|
49
|
+
has_details_view: obj_has_details_view?,
|
50
|
+
modification: modification(obj),
|
51
|
+
restriction_messages: editor.restriction_messages_for(obj),
|
54
52
|
}
|
55
53
|
else
|
56
54
|
{}
|
data/lib/scrivito/cms_backend.rb
CHANGED
@@ -246,7 +246,7 @@ module Scrivito
|
|
246
246
|
end
|
247
247
|
|
248
248
|
def blob_metadata_cache_key(id)
|
249
|
-
"blob_metadata/#{
|
249
|
+
"blob_metadata/#{id}"
|
250
250
|
end
|
251
251
|
|
252
252
|
def find_obj_data_filtering_deleted_by(revision, index, keys, include_deleted)
|
@@ -312,9 +312,10 @@ module Scrivito
|
|
312
312
|
include_deleted: true
|
313
313
|
}
|
314
314
|
|
315
|
-
#
|
316
|
-
#
|
317
|
-
|
315
|
+
# A base revision doesn't have a directly corresponding workspace. Instead it uses its
|
316
|
+
# derivative workspace as fallback to access the contents. Thus fallback workspace of a base
|
317
|
+
# revision may not be used for backend requests.
|
318
|
+
params[:workspace_id] = revision.workspace.id unless revision.base?
|
318
319
|
|
319
320
|
params
|
320
321
|
end
|
@@ -43,7 +43,7 @@ class CmsFieldTag < Struct.new(
|
|
43
43
|
|
44
44
|
if FIELD_TYPES_WITH_ORIGINAL_CONTENT.include?(field_type)
|
45
45
|
original_value = view.scrivito_value(current_value)
|
46
|
-
original_content = original_content(field_type, original_value)
|
46
|
+
original_content = original_content(field_type, original_value, current_value)
|
47
47
|
encoded_content = Base64.strict_encode64(MultiJson.encode(original_content))
|
48
48
|
options['private-field-original-content'] = encoded_content
|
49
49
|
end
|
@@ -99,6 +99,8 @@ class CmsFieldTag < Struct.new(
|
|
99
99
|
referencelist
|
100
100
|
string
|
101
101
|
text
|
102
|
+
binary
|
103
|
+
date
|
102
104
|
]
|
103
105
|
|
104
106
|
def authenticated_editor?
|
@@ -109,10 +111,12 @@ class CmsFieldTag < Struct.new(
|
|
109
111
|
EditingContextMiddleware.from_request(view.request)
|
110
112
|
end
|
111
113
|
|
112
|
-
def original_content(field_type, field_value)
|
114
|
+
def original_content(field_type, field_value, raw_value)
|
113
115
|
case field_type
|
114
116
|
when 'reference' then field_value.try(:id)
|
115
117
|
when 'referencelist' then field_value.map(&:id)
|
118
|
+
when 'binary' then field_value && {}
|
119
|
+
when 'date' then raw_value.try(:utc).try(:iso8601)
|
116
120
|
else field_value
|
117
121
|
end
|
118
122
|
end
|
@@ -31,11 +31,7 @@ module Scrivito
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def self.attach_widget_to_obj(widget, obj)
|
34
|
-
widget.id =
|
35
|
-
obj.generate_widget_pool_id
|
36
|
-
else
|
37
|
-
BasicObj.generate_widget_pool_id
|
38
|
-
end
|
34
|
+
widget.id = widget.attributes_to_be_saved.delete('_id') || generate_widget_pool_id(obj)
|
39
35
|
widget.obj = obj
|
40
36
|
end
|
41
37
|
|
@@ -47,6 +43,10 @@ module Scrivito
|
|
47
43
|
end
|
48
44
|
end
|
49
45
|
end
|
46
|
+
|
47
|
+
def self.generate_widget_pool_id(obj)
|
48
|
+
obj.presence ? obj.generate_widget_pool_id : BasicObj.generate_widget_pool_id
|
49
|
+
end
|
50
50
|
end
|
51
51
|
end
|
52
52
|
end
|