scrivito_sdk 1.8.1 → 1.9.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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/scrivito/binary_redirect_controller.rb +0 -1
  3. data/app/controllers/scrivito/obj_class_controller.rb +18 -0
  4. data/app/controllers/scrivito/objs_controller.rb +6 -6
  5. data/app/controllers/scrivito/workspaces_controller.rb +2 -18
  6. data/app/views/scrivito/obj_class/thumbnails.json.jbuilder +1 -0
  7. data/app/views/scrivito/objs/valid_page_classes.json.jbuilder +1 -0
  8. data/config/ca-bundle.crt +1 -1
  9. data/config/precedence_routes.rb +7 -12
  10. data/lib/assets/javascripts/scrivito.js +101 -10
  11. data/lib/assets/javascripts/scrivito_ui_redirect.js +85 -6
  12. data/lib/assets/javascripts/scrivito_with_js_sdk.js +22205 -18338
  13. data/lib/assets/stylesheets/scrivito.css +1 -1
  14. data/lib/generators/scrivito/install/templates/app/models/image.rb +0 -5
  15. data/lib/scrivito/attribute_content.rb +5 -4
  16. data/lib/scrivito/base_widget_tag.rb +1 -0
  17. data/lib/scrivito/basic_obj.rb +21 -41
  18. data/lib/scrivito/basic_widget.rb +1 -21
  19. data/lib/scrivito/binary.rb +0 -7
  20. data/lib/scrivito/binary_routing.rb +5 -6
  21. data/lib/scrivito/child_list_tag.rb +8 -1
  22. data/lib/scrivito/cms_env.rb +6 -2
  23. data/lib/scrivito/cms_field_tag.rb +2 -0
  24. data/lib/scrivito/cms_routing.rb +25 -13
  25. data/lib/scrivito/configuration.rb +1 -4
  26. data/lib/scrivito/disable_browser_cache_for_ui_middleware.rb +19 -0
  27. data/lib/scrivito/editing_context.rb +4 -0
  28. data/lib/scrivito/editing_context_middleware.rb +5 -1
  29. data/lib/scrivito/obj_collection.rb +4 -0
  30. data/lib/scrivito/page_config.rb +1 -1
  31. data/lib/scrivito/preset_routes.rb +1 -1
  32. data/lib/scrivito/revision.rb +1 -1
  33. data/lib/scrivito/sdk_engine.rb +1 -0
  34. data/lib/scrivito/ui_config.rb +6 -42
  35. data/lib/scrivito/ui_obj_classes_json_formatter.rb +48 -0
  36. data/lib/scrivito/user.rb +3 -0
  37. data/lib/scrivito/user_definition.rb +1 -1
  38. data/lib/scrivito/workspace.rb +1 -1
  39. metadata +8 -10
  40. data/app/controllers/scrivito/completion_controller.rb +0 -12
  41. data/app/views/scrivito/completion/suggest.json.jbuilder +0 -1
  42. data/app/views/scrivito/objs/show.json.jbuilder +0 -2
  43. data/app/views/scrivito/webservice/workspaces.json.jbuilder +0 -1
  44. data/app/views/scrivito/workspaces/show.json.jbuilder +0 -1
  45. data/lib/assets/images/scrivito/source_type_invalid.png +0 -0
@@ -1,9 +1,4 @@
1
1
  class Image < Obj
2
2
  attribute :blob, :binary
3
3
  attribute :tags, :stringlist
4
-
5
- # activate image resizing and optimization
6
- def apply_image_transformation?
7
- true
8
- end
9
4
  end
@@ -4,7 +4,7 @@ module Scrivito
4
4
  # default values, restricting the types of widgets that may be added to a +widgetlist+
5
5
  # attribute, plus a couple of convenience methods.
6
6
  # @api public
7
- # @see http://scrivito.com/attribute-types Attributes and their type
7
+ # @see https://scrivito.com/attribute-types Attributes and their type
8
8
  #
9
9
  module AttributeContent
10
10
  ATTRIBUTE_TYPES = %w[
@@ -128,7 +128,8 @@ module AttributeContent
128
128
  # @api public
129
129
  # @param [String] field_name Name of the widget attribute.
130
130
  # @return [nil, Array<Class>]
131
- # @see http://scrivito.com/limiting-widget-and-page-types Limiting available widget and page types
131
+ # @see
132
+ # https://scrivito.com/limiting-widget-and-page-types Limiting available widget and page types
132
133
  #
133
134
  def valid_widget_classes_for(field_name)
134
135
  end
@@ -451,7 +452,7 @@ module AttributeContent
451
452
  # ImageWidget.attribute_definitions[:my_reference2].valid_classes
452
453
  # #=> [Image, Video]
453
454
  #
454
- # @see http://scrivito.com/default-attribute-values Specifying default attribute values
455
+ # @see https://scrivito.com/default-attribute-values Specifying default attribute values
455
456
  #
456
457
  def attribute(name, type, options = {})
457
458
  name, type, options = name.to_s, type.to_s, options
@@ -562,7 +563,7 @@ module AttributeContent
562
563
  # my_page = MyPage.create({_path: '/en/test'}, bob)
563
564
  # my_page.title # => 'Hier den Titel eingeben'
564
565
  #
565
- # @see http://scrivito.com/default-attribute-values Specifying default attribute values
566
+ # @see https://scrivito.com/default-attribute-values Specifying default attribute values
566
567
  #
567
568
  def default_for(attribute_name, &block)
568
569
  attribute_name = attribute_name.to_s
@@ -23,6 +23,7 @@ class BaseWidgetTag < Struct.new(
23
23
  options = {}
24
24
 
25
25
  if inplace_editing_allowed?
26
+ options['private-widget'] = true
26
27
  options['private-widget-id'] = widget.id
27
28
  options['widget-obj-class'] = widget.obj_class
28
29
  options['private-widget-description-for-editor'] = description_for_editor
@@ -16,7 +16,7 @@ module Scrivito
16
16
  # @note Please do not use {Scrivito::BasicObj} directly
17
17
  # as it is intended as an abstract class.
18
18
  # Always use {Obj} or a subclass of {Obj}.
19
- # @see http://scrivito.com/objects-widgets-classes CMS objects, widgets, and classes
19
+ # @see https://scrivito.com/objects-widgets-classes CMS objects, widgets, and classes
20
20
  # @api public
21
21
  #
22
22
  class BasicObj
@@ -581,21 +581,13 @@ module Scrivito
581
581
  blob_attribute_definition.present? && blob_attribute_definition.type == 'binary'
582
582
  end
583
583
 
584
- #
585
- # When delivering binary objects, this method decides whether the image transformations should
586
- # be applied by default.
587
584
  #
588
585
  # @api public
589
- #
590
- # By default, this method returns +false+.
591
- # Override it in subclasses to fit your needs.
592
- #
593
- # @note Only relevant for binary objects
594
- # @see Scrivito::Configuration.default_image_transformation=
595
- # @see Scrivito::Binary#transform
586
+ # @deprecated Has no effect anymore: Image transformation will be applied if possible.
596
587
  #
597
588
  def apply_image_transformation?
598
- false
589
+ Scrivito::Deprecation.warn(
590
+ 'Scrivito::BasicObj#apply_image_transformation? is deprecated and has no effect anymore.')
599
591
  end
600
592
 
601
593
  # Returns true if this Obj is the root Obj.
@@ -623,11 +615,11 @@ module Scrivito
623
615
  #
624
616
  # @return [Array<Obj>]
625
617
  def sorted_toclist
626
- if sortable_toclist?
627
- (child_order & toclist) + (toclist - child_order).sort_by(&:id)
628
- else
629
- toclist
630
- end
618
+ sort_toclist(toclist)
619
+ end
620
+
621
+ def sorted_toclist_including_deleted
622
+ sort_toclist(children_including_deleted.reject(&:binary?))
631
623
  end
632
624
 
633
625
  def sortable_toclist?
@@ -908,30 +900,6 @@ module Scrivito
908
900
  end
909
901
  end
910
902
 
911
- def restore_widget(widget_id)
912
- Workspace.current.assert_revertable
913
-
914
- return if modification == Modification::UNMODIFIED
915
- if modification == Modification::DELETED
916
- raise ScrivitoError, 'Can not restore a widget inside a deleted obj'
917
- end
918
-
919
- unless widget = in_revision(Workspace.current.base_revision).widgets[widget_id]
920
- raise ResourceNotFound, "Could not find widget with id #{widget_id}"
921
- end
922
-
923
- container = widget.container
924
- if container.kind_of?(BasicWidget) && !widgets[container.id]
925
- raise ScrivitoError, 'Can not restore a widget inside a deleted widget'
926
- end
927
-
928
- widget_copy = widget.copy_for_restore(read_widget_pool.keys)
929
- attribute_name = widget.container_attribute_name
930
- current_container = widgets[container.id] || self
931
- current_container.update(attribute_name =>
932
- current_container[attribute_name].insert(widget.container_attribute_index, widget_copy))
933
- end
934
-
935
903
  def mark_resolved
936
904
  workspace.api_request(:put, "/objs/#{id}", obj: {_conflicts: nil})
937
905
  reload
@@ -995,6 +963,18 @@ module Scrivito
995
963
 
996
964
  private
997
965
 
966
+ def children_including_deleted
967
+ workspace.objs.find_by_parent_path_including_deleted(path)
968
+ end
969
+
970
+ def sort_toclist(unsorted_toclist)
971
+ if sortable_toclist?
972
+ (child_order & unsorted_toclist) + (unsorted_toclist - child_order).sort_by(&:id)
973
+ else
974
+ unsorted_toclist
975
+ end
976
+ end
977
+
998
978
  def cms_data_for_revision(revision)
999
979
  return nil unless revision
1000
980
 
@@ -4,7 +4,7 @@ module Scrivito
4
4
  # of content editors want to place on pages or into widgets. All widget classes are based on
5
5
  # subclasses of {Scrivito::BasicWidget Widget}. As with CMS objects, the content of a widget
6
6
  # is stored in its attributes.
7
- # @see http://scrivito.com/page-with-widgets Creating a page type with widgets
7
+ # @see https://scrivito.com/page-with-widgets Creating a page type with widgets
8
8
  # @api public
9
9
  class BasicWidget
10
10
  extend AttributeContent::ClassMethods
@@ -204,22 +204,6 @@ class BasicWidget
204
204
  self.class.new(attributes)
205
205
  end
206
206
 
207
- def copy_for_restore(referenced_ids)
208
- attributes = {}
209
- attribute_definitions.each do |attribute_definition|
210
- attribute_name = attribute_definition.name
211
- attribute_value = read_attribute(attribute_name)
212
- if attribute_definition.widgetlist?
213
- attribute_value = attribute_value
214
- .reject { |widget| referenced_ids.include?(widget.id) }
215
- .map { |widget| widget.copy_for_restore(referenced_ids) }
216
- end
217
- attributes[attribute_name] = attribute_value
218
- end
219
- attributes['_id'] = id
220
- self.class.new(attributes)
221
- end
222
-
223
207
  def clone
224
208
  raise "The method `clone' was removed. Please use `copy' instead"
225
209
  end
@@ -347,10 +331,6 @@ class BasicWidget
347
331
  container_attribute_name
348
332
  end
349
333
 
350
- def container_attribute_index
351
- container[container_attribute_name].index(self)
352
- end
353
-
354
334
  def has_attribute?(key)
355
335
  key.to_s == '_obj_class' || super
356
336
  end
@@ -283,13 +283,6 @@ class Binary
283
283
  # Otherwise +self+.
284
284
  #
285
285
  # @return [Scrivito::Binary] original binary
286
- #
287
- # @example
288
- # @obj.blob.id # => "abc123"
289
- # @obj.blob.original.id # => "abc123"
290
- # @obj.blob.transform(width: 50).original.id # => "abc123"
291
- # @obj.blob.transform(width: 50).transform(height: 50).original.id # => "abc123"
292
- #
293
286
  def original
294
287
  @original || self
295
288
  end
@@ -9,13 +9,13 @@ class BinaryRouting < Struct.new(:request, :scrivito_engine)
9
9
  binary = if image_options.key?(:transform)
10
10
  apply_custom_transformation(binary, image_options[:transform])
11
11
  else
12
- apply_default_transformation(binary, obj)
12
+ apply_default_transformation(binary)
13
13
  end
14
14
  binary_url(binary)
15
15
  end
16
16
 
17
17
  def resolved_binary_obj_url(obj, binary)
18
- apply_default_transformation(binary, obj).url
18
+ BinaryRewrite.call(request, apply_default_transformation(binary).url)
19
19
  end
20
20
 
21
21
  private
@@ -39,10 +39,9 @@ class BinaryRouting < Struct.new(:request, :scrivito_engine)
39
39
  end
40
40
  end
41
41
 
42
- def apply_default_transformation(binary, obj)
43
- if (transformation_definition = Scrivito::Configuration.default_image_transformation) &&
44
- obj.apply_image_transformation?
45
- binary.transform(transformation_definition)
42
+ def apply_default_transformation(binary)
43
+ if Scrivito::Configuration.default_image_transformation
44
+ binary.transform(Scrivito::Configuration.default_image_transformation)
46
45
  else
47
46
  binary
48
47
  end
@@ -37,8 +37,15 @@ class ChildListTag < Struct.new(:tag_name, :obj, :field_name, :view)
37
37
  def content(&block)
38
38
  return unless block_given?
39
39
 
40
+ toclist =
41
+ if EditingContextMiddleware.from_request(view.request).include_deleted_objs?
42
+ obj.sorted_toclist_including_deleted
43
+ else
44
+ obj.sorted_toclist
45
+ end
46
+
40
47
  is_sortable = obj.sortable_toclist? && user_present?
41
- rendered_children = obj.sorted_toclist.map do |child|
48
+ rendered_children = toclist.map do |child|
42
49
  obj_tag = ObjTag.new(child, is_sortable, comparison.modification(child), view)
43
50
  yield obj_tag, child
44
51
  obj_tag.rendered
@@ -28,8 +28,12 @@ module Scrivito
28
28
 
29
29
  def find_obj
30
30
  found_obj =
31
- if params[:id]
32
- Obj.find(params[:id])
31
+ if id = params[:id]
32
+ if EditingContextMiddleware.from_env(env).include_deleted_objs?
33
+ Obj.find_including_deleted(id)
34
+ else
35
+ Obj.find(id)
36
+ end
33
37
  elsif params[:permalink].present?
34
38
  permalink = Array(params[:permalink]).join("/")
35
39
  Obj.find_by_permalink!(permalink)
@@ -149,6 +149,8 @@ class CmsFieldTag < Struct.new(:view, :tag_name, :obj_or_widget, :editing_option
149
149
  if %w[
150
150
  binary
151
151
  date
152
+ enum
153
+ multienum
152
154
  reference
153
155
  referencelist
154
156
  ].include?(field_type)
@@ -76,21 +76,33 @@ class CmsRouting < Struct.new(:request, :context, :scrivito_engine, :image_optio
76
76
  end
77
77
 
78
78
  def path_or_url_for_objs(obj, path_or_url, options)
79
- permalink = obj.permalink
80
- if permalink && (route = find_route(:permalink)) && permalink.split('/').first != 'scrivito'
81
- route.generate(path_or_url, options.merge(:permalink => permalink))
82
- elsif homepage?(obj) && route = find_route(:homepage)
83
- route.generate(path_or_url, options)
84
- elsif obj.binary?
85
- binary_obj_url(obj) || LINK_TO_EMPTY_BLOB
86
- elsif route = find_route(:slug_id)
79
+ if permalink_route_applicable?(obj) && route = find_route(:permalink)
80
+ return route.generate(path_or_url, options.merge(permalink: obj.permalink))
81
+ end
82
+
83
+ if homepage?(obj) && route = find_route(:homepage)
84
+ return route.generate(path_or_url, options)
85
+ end
86
+
87
+ if obj.binary?
88
+ return binary_obj_url(obj) || LINK_TO_EMPTY_BLOB
89
+ end
90
+
91
+ if route = find_route(:slug_id)
87
92
  slug = obj.slug.present? ? obj.slug.sub(/^\//, '') : nil
88
- route.generate(path_or_url, options.merge(id: obj.id, slug: slug))
89
- else
90
- raise ScrivitoError, "The required scrivito route 'slug_id' is not defined. "\
91
- "Please add a 'slug_id' definition to your routes.rb. See the documentation"\
92
- " of 'scrivito_route' for further details."
93
+
94
+ return route.generate(path_or_url, options.merge(id: obj.id, slug: slug))
93
95
  end
96
+
97
+ raise ScrivitoError, "The required scrivito route 'slug_id' is not defined. "\
98
+ "Please add a 'slug_id' definition to your routes.rb. See the documentation"\
99
+ " of 'scrivito_route' for further details."
100
+ end
101
+
102
+ def permalink_route_applicable?(obj)
103
+ permalink = obj.permalink
104
+
105
+ permalink && permalink.split('/').first != 'scrivito' && !obj.deleted?
94
106
  end
95
107
 
96
108
  def find_route(name)
@@ -323,9 +323,7 @@ Please use the new scrivito_route api to replicate the legacy routes:
323
323
  #
324
324
  # @api public
325
325
  #
326
- # When delivering binary Objs, the default image transformation will be applied if
327
- # {Scrivito::BasicObj#apply_image_transformation? Obj#apply_image_transformation?} returns
328
- # +true+.
326
+ # When delivering binary Objs, the default image transformation will be applied.
329
327
  #
330
328
  # If not changed the default image transformation is an empty transformation (an empty
331
329
  # +Hash+). Set it to +false+ to disabled the default image transformation completely.
@@ -333,7 +331,6 @@ Please use the new scrivito_route api to replicate the legacy routes:
333
331
  # @param [Hash] value the {Scrivito::Binary#transform transformation definition}
334
332
  #
335
333
  # @see Scrivito::Binary#transform
336
- # @see Scrivito::BasicObj#apply_image_transformation?
337
334
  #
338
335
  attr_writer :default_image_transformation
339
336
 
@@ -0,0 +1,19 @@
1
+ module Scrivito
2
+ class DisableBrowserCacheForUiMiddleware
3
+ def initialize(app)
4
+ @app = app
5
+ end
6
+
7
+ def call(env)
8
+ status, headers, response = @app.call(env)
9
+
10
+ editing_context = EditingContextMiddleware.from_env(env)
11
+
12
+ if editing_context.authenticated_editor?
13
+ headers['Cache-Control'] = 'no-store, must-revalidate'
14
+ end
15
+
16
+ [status, headers, response]
17
+ end
18
+ end
19
+ end
@@ -80,6 +80,10 @@ class EditingContext
80
80
  display_mode == 'editing'
81
81
  end
82
82
 
83
+ def include_deleted_objs?
84
+ display_mode == 'diff'
85
+ end
86
+
83
87
  def to_params
84
88
  {
85
89
  _scrivito_display_mode: display_mode,
@@ -6,7 +6,11 @@ class EditingContextMiddleware
6
6
  ENVKEY = 'SCRIVITO_EDITING_CONTEXT'
7
7
 
8
8
  def self.from_request(request)
9
- request.env[ENVKEY] || EditingContext.new
9
+ from_env(request.env)
10
+ end
11
+
12
+ def self.from_env(env)
13
+ env[ENVKEY] || EditingContext.new
10
14
  end
11
15
 
12
16
  def initialize(app)
@@ -102,6 +102,10 @@ module Scrivito
102
102
  find_by(:ppath, [path]).first
103
103
  end
104
104
 
105
+ def find_by_parent_path_including_deleted(path)
106
+ find_by_including_deleted(:ppath, [path]).first
107
+ end
108
+
105
109
  def find_by_id(id)
106
110
  find_by(:id, [id]).first.first
107
111
  end
@@ -41,7 +41,7 @@ class PageConfig < Struct.new(:obj, :editing_context, :lookup_context)
41
41
  has_details_view: obj_has_details_view?,
42
42
  modification: modification(obj),
43
43
  parent_path: obj.parent_path,
44
- restriction_messages: editor.restriction_messages_for(obj),
44
+ is_restricted: editor.restriction_messages_for(obj).any?,
45
45
  }
46
46
  end
47
47
 
@@ -13,7 +13,7 @@ module Scrivito
13
13
  scrivito_route '(/)(*slug-):id', using: "slug_id", via: :all
14
14
 
15
15
  match ':id(/*slug)', to: 'scrivito/legacy_redirect#index', via: :all, constraints: {
16
- id: /[a-z0-9]{16}/
16
+ id: /[a-f0-9]{16}/
17
17
  }
18
18
  end
19
19
 
@@ -40,7 +40,7 @@ class Revision < Struct.new(:id, :workspace, :base)
40
40
  def internal_obj_search(query, result, continuation=nil, tentative=false)
41
41
  response = workspace.api_request(:get, "/objs/search",
42
42
  query: query,
43
- include_deleted: true,
43
+ options: {include_deleted: true},
44
44
  size: 100,
45
45
  continuation: continuation,
46
46
  consistent_with: content_state_id
@@ -69,6 +69,7 @@ module ::Scrivito
69
69
  config.app_middleware.use Scrivito::EditingContextMiddleware
70
70
  config.app_middleware.use Scrivito::CacheMiddleware
71
71
  config.app_middleware.use Scrivito::WorkspaceSelectionMiddleware
72
+ config.app_middleware.use Scrivito::DisableBrowserCacheForUiMiddleware
72
73
  end
73
74
  end
74
75
 
@@ -9,59 +9,33 @@ class UiConfig < Struct.new(:editing_context, :resource, :return_to, :app_extens
9
9
  def to_json
10
10
  {
11
11
  app_extension_tags: app_extension_tags,
12
- editing_context: editing_context_config,
13
12
  backend_endpoint: Configuration.endpoint,
14
13
  tenant: Configuration.tenant,
15
14
  i18n: i18n_config,
16
15
  is_development_mode: Rails.env.development?,
17
16
  resource_dialog: resource_dialog_config,
18
- revision: revision_config,
19
17
  user: user_config,
20
18
  user_permissions: user_permissions_config,
21
- obj_class: obj_class_config,
22
- widget_class: widget_class_config,
19
+ class_datas: obj_class_config + widget_class_config,
20
+ useRailsEngine: true,
23
21
  }.to_json
24
22
  end
25
23
 
26
24
  private
27
25
 
28
- def editing_context_config
29
- {
30
- display_mode: editing_context.display_mode,
31
- selected_workspace: workspace_config(selected_workspace),
32
- visible_workspace: workspace_config(visible_workspace),
33
- }
34
- end
35
-
36
- def workspace_config(workspace)
37
- {
38
- id: workspace.id,
39
- memberships: workspace.memberships.map do |membership|
40
- {
41
- user_id: membership.user_id,
42
- role: membership.role,
43
- description: membership.user.description
44
- }
45
- end,
46
- outdated: workspace.outdated?,
47
- auto_update: workspace.auto_update?,
48
- title: workspace.title,
49
- }
50
- end
51
-
52
26
  def i18n_config
53
27
  {locale: Scrivito::Configuration.ui_locale || I18n.locale}
54
28
  end
55
29
 
56
30
  def obj_class_config
57
31
  obj_models.map do |obj_class|
58
- obj_class.as_json.merge(hasDetailsView: details_view?(obj_class.name))
32
+ obj_class_formatter.format(obj_class)
59
33
  end
60
34
  end
61
35
 
62
36
  def widget_class_config
63
37
  widget_models.map do |widget_class|
64
- widget_class.as_json.merge(hasDetailsView: details_view?(widget_class.name))
38
+ obj_class_formatter.format(widget_class)
65
39
  end
66
40
  end
67
41
 
@@ -90,10 +64,6 @@ class UiConfig < Struct.new(:editing_context, :resource, :return_to, :app_extens
90
64
  }
91
65
  end
92
66
 
93
- def revision_config
94
- {published_revision_id: Workspace.published.revision_id}
95
- end
96
-
97
67
  def editor
98
68
  editing_context.editor
99
69
  end
@@ -102,14 +72,8 @@ class UiConfig < Struct.new(:editing_context, :resource, :return_to, :app_extens
102
72
  editing_context.selected_workspace
103
73
  end
104
74
 
105
- def visible_workspace
106
- editing_context.visible_workspace
107
- end
108
-
109
- def details_view?(obj_class_name)
110
- lookup_context.find("#{obj_class_name.underscore}/details").present?
111
- rescue ActionView::MissingTemplate
112
- false
75
+ def obj_class_formatter
76
+ @obj_class_formatter ||= UiObjClassesJsonFormatter.new(lookup_context)
113
77
  end
114
78
  end
115
79
 
@@ -0,0 +1,48 @@
1
+ module Scrivito
2
+ class UiObjClassesJsonFormatter < Struct.new(:lookup_context)
3
+ def format(obj_class)
4
+ data = base_obj_class_data(obj_class)
5
+ if obj_class.ancestors.include?(Scrivito::BasicWidget)
6
+ data[:embeds] = obj_class.embeds?
7
+ data[:embeddingAttribute] =
8
+ obj_class.embeds? ? obj_class.embedding_attribute.name.camelcase(:lower) : nil
9
+
10
+ data[:validContainerClasses] = convert_classes_array(obj_class.valid_container_classes)
11
+ end
12
+
13
+ data[:hasServerDetailsTemplate] = details_view?(obj_class.name)
14
+ data
15
+ end
16
+
17
+ private
18
+
19
+ def base_obj_class_data(obj_class)
20
+ {
21
+ name: obj_class.name,
22
+ type: obj_class.ancestors.include?(Scrivito::BasicWidget) ? 'Widget' : 'Obj',
23
+ title: obj_class.description_for_editor,
24
+ attributes: obj_class.attribute_definitions.map { |attr| convert_attribute(attr) },
25
+ usesServerCallbacks: true,
26
+ hideFromEditor: obj_class.hide_from_editor?,
27
+ }
28
+ end
29
+
30
+ def convert_attribute(attribute)
31
+ attribute_json = attribute.as_json
32
+ attribute_json[:name] = attribute_json[:name].camelcase(:lower)
33
+ attribute_json
34
+ end
35
+
36
+ def details_view?(obj_class_name)
37
+ lookup_context.find("#{obj_class_name.underscore}/details").present?
38
+ rescue ActionView::MissingTemplate
39
+ false
40
+ end
41
+
42
+ def convert_classes_array(arr)
43
+ if arr
44
+ arr.map(&:name)
45
+ end
46
+ end
47
+ end
48
+ end
data/lib/scrivito/user.rb CHANGED
@@ -26,6 +26,9 @@ module Scrivito
26
26
 
27
27
  # Permits the user to publish the working copy.
28
28
  :publish,
29
+
30
+ # Permits the user to access the publishing history
31
+ :read_history,
29
32
  ].freeze
30
33
 
31
34
  class << self
@@ -18,7 +18,7 @@ module Scrivito
18
18
  # perform a specific action. This method lets you add an exception to this logic and thus
19
19
  # should be used carefully.
20
20
  # @note By default, all users are allowed to create a new workspace.
21
- # @see http://scrivito.com/user-permissions Defining users and their permissions
21
+ # @see https://scrivito.com/user-permissions Defining users and their permissions
22
22
  #
23
23
  # @param [Symbol] verb the verb of the action (see {Scrivito::User::VERBS}).
24
24
  # @param [Symbol] subject the subject of the action. Currently, only +:workspace+ is supported.
@@ -6,7 +6,7 @@ module Scrivito
6
6
  # This class represents a CMS workspace, called "working copy" in the UI. A working copy lets
7
7
  # editors create and modify content independently of the published content or other working copies.
8
8
  # On creation, a working copy is based on the currently published content.
9
- # @see http://scrivito.com/about-working-copies About working copies
9
+ # @see https://scrivito.com/about-working-copies About working copies
10
10
 
11
11
  class Workspace
12
12
  extend ActiveModel::Naming