scrivito_sdk 0.65.2 → 0.66.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 (83) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/scrivito/binary_redirect_controller.rb +19 -0
  3. data/app/controllers/scrivito/objs_controller.rb +6 -2
  4. data/app/controllers/scrivito/webservice_controller.rb +1 -1
  5. data/app/controllers/scrivito/workspaces_controller.rb +1 -7
  6. data/app/helpers/scrivito_helper.rb +115 -64
  7. data/app/views/scrivito/objs/is_outdated.json.jbuilder +1 -0
  8. data/app/views/scrivito/ui/index.html.erb +1 -0
  9. data/config/ca-bundle.crt +1 -1
  10. data/config/precedence_routes.rb +6 -4
  11. data/config/routes.rb +1 -1
  12. data/lib/assets/images/scrivito/source_too_large.png +0 -0
  13. data/lib/assets/images/scrivito/source_type_invalid.png +0 -0
  14. data/lib/assets/javascripts/scrivito_ui.js +2975 -357
  15. data/lib/assets/stylesheets/scrivito_sdk.css +1 -3
  16. data/lib/assets/stylesheets/scrivito_ui.css +1 -3
  17. data/lib/generators/scrivito/install/templates/scrivito/migrate/install_scrivito_migration.rb +0 -2
  18. data/lib/generators/scrivito/migration/templates/migration.erb +6 -8
  19. data/lib/scrivito/attribute_content.rb +16 -52
  20. data/lib/scrivito/attribute_deserializer.rb +3 -5
  21. data/lib/scrivito/attribute_serializer.rb +42 -45
  22. data/lib/scrivito/backend/content_state_node.rb +71 -19
  23. data/lib/scrivito/backend/index.rb +20 -0
  24. data/lib/scrivito/backend/obj_data_cache.rb +157 -31
  25. data/lib/scrivito/backend/obj_data_from_rest.rb +1 -0
  26. data/lib/scrivito/backend/obj_load.rb +10 -6
  27. data/lib/scrivito/backend/obj_query.rb +2 -1
  28. data/lib/scrivito/backend/parent_path_index.rb +5 -1
  29. data/lib/scrivito/backend/path_index.rb +5 -1
  30. data/lib/scrivito/backend/permalink_index.rb +18 -10
  31. data/lib/scrivito/basic_obj.rb +62 -42
  32. data/lib/scrivito/basic_widget.rb +5 -5
  33. data/lib/scrivito/binary.rb +154 -13
  34. data/lib/scrivito/binary_param_verifier.rb +31 -0
  35. data/lib/scrivito/binary_rewrite.rb +35 -0
  36. data/lib/scrivito/cache_middleware.rb +5 -0
  37. data/lib/scrivito/child_list_tag.rb +3 -3
  38. data/lib/scrivito/cms_backend.rb +89 -57
  39. data/lib/scrivito/cms_data_cache.rb +21 -4
  40. data/lib/scrivito/cms_dispatch_controller.rb +13 -0
  41. data/lib/scrivito/cms_field_tag.rb +16 -3
  42. data/lib/scrivito/cms_rest_api.rb +2 -2
  43. data/lib/scrivito/cms_routing.rb +41 -18
  44. data/lib/scrivito/configuration.rb +22 -0
  45. data/lib/scrivito/content_state.rb +1 -9
  46. data/lib/scrivito/content_state_caching.rb +0 -20
  47. data/lib/scrivito/controller_actions.rb +3 -2
  48. data/lib/scrivito/controller_runtime.rb +16 -8
  49. data/lib/scrivito/dialog_size_helper.rb +11 -0
  50. data/lib/scrivito/diff.rb +0 -2
  51. data/lib/scrivito/editing_context.rb +24 -13
  52. data/lib/scrivito/editing_context_middleware.rb +6 -1
  53. data/lib/scrivito/errors.rb +18 -0
  54. data/lib/scrivito/image_tag.rb +55 -0
  55. data/lib/scrivito/link.rb +12 -0
  56. data/lib/scrivito/membership_collection.rb +3 -2
  57. data/lib/scrivito/migrations/cms_backend.rb +6 -13
  58. data/lib/scrivito/migrations/migrator.rb +2 -23
  59. data/lib/scrivito/migrations/workspace_lock.rb +23 -11
  60. data/lib/scrivito/named_link.rb +1 -1
  61. data/lib/scrivito/obj_collection.rb +1 -1
  62. data/lib/scrivito/obj_data_from_service.rb +0 -7
  63. data/lib/scrivito/obj_search_enumerator.rb +2 -2
  64. data/lib/scrivito/parent_path.rb +9 -0
  65. data/lib/scrivito/routing_helper.rb +2 -2
  66. data/lib/scrivito/user.rb +2 -2
  67. data/lib/scrivito/user_definition.rb +2 -2
  68. data/lib/scrivito/widget_garbage_collection.rb +2 -2
  69. data/lib/scrivito/widget_tag.rb +6 -3
  70. data/lib/scrivito/workspace.rb +60 -41
  71. data/lib/scrivito/workspace_data.rb +40 -4
  72. data/lib/scrivito/workspace_data_from_service.rb +0 -10
  73. data/lib/scrivito_sdk.rb +0 -16
  74. metadata +12 -12
  75. data/lib/scrivito/attribute.rb +0 -152
  76. data/lib/scrivito/attribute_collection.rb +0 -66
  77. data/lib/scrivito/attribute_definition_migrator.rb +0 -188
  78. data/lib/scrivito/cms_rest_api/legacy_attribute_serializer.rb +0 -105
  79. data/lib/scrivito/image_tag_helper.rb +0 -46
  80. data/lib/scrivito/obj_class.rb +0 -258
  81. data/lib/scrivito/obj_class_collection.rb +0 -71
  82. data/lib/scrivito/obj_class_data.rb +0 -37
  83. data/lib/tasks/migrate_attribute_definitions.rake +0 -6
@@ -28,10 +28,15 @@ class EditingContextMiddleware
28
28
  header_params['workspace_id'] ||
29
29
  cookie_params['workspace_id']
30
30
 
31
+ if cookie_params['workspace_id']
32
+ workspace_changed = workspace_id != cookie_params['workspace_id']
33
+ end
34
+
31
35
  env[ENVKEY] = EditingContext.new(
32
36
  display_mode: display_mode,
33
37
  editor: editor_proc(env),
34
- selected_workspace_id: workspace_id
38
+ selected_workspace_id: workspace_id,
39
+ workspace_changed: workspace_changed
35
40
  )
36
41
 
37
42
  @app.call(env)
@@ -17,4 +17,22 @@ end
17
17
  class InternalError < ScrivitoError
18
18
  end
19
19
 
20
+ # @api beta
21
+ class TransformationError < ScrivitoError
22
+ attr_reader :code
23
+
24
+ def initialize(message, code)
25
+ @code = code
26
+ super(message)
27
+ end
28
+ end
29
+
30
+ # @api beta
31
+ class TransformationSourceError < TransformationError
32
+ end
33
+
34
+ # @api beta
35
+ class TransformationDefinitionError < TransformationError
36
+ end
37
+
20
38
  end # module Scrivito
@@ -0,0 +1,55 @@
1
+ module Scrivito
2
+
3
+ class ImageTag < Struct.new(:view_context)
4
+ def options(obj, attribute_name, tag_options, editing_options)
5
+ tag_options.reverse_merge(
6
+ src: src(obj, attribute_name, editing_options),
7
+ alt: alt(obj, attribute_name)
8
+ )
9
+ end
10
+
11
+ private
12
+
13
+ def src(obj, attribute_name, editing_options)
14
+ path(obj, attribute_name, editing_options) ||
15
+ editing_options[:placeholder] ||
16
+ view_context.image_path('scrivito/image_placeholder.png')
17
+ end
18
+
19
+ def alt(obj, attribute_name)
20
+ case target = obj[attribute_name]
21
+ when Binary then obj.try(:alt_description)
22
+ when Enumerable then target.first.try(:alt_description)
23
+ else target.try(:alt_description)
24
+ end
25
+ end
26
+
27
+ def path(obj, attribute_name, editing_options)
28
+ if target = target(obj, attribute_name, editing_options)
29
+ image_options = editing_options.slice(:transform)
30
+ cms_routing = CmsRouting.new(request, main_app, scrivito_engine, image_options)
31
+ cms_routing.path_or_url(target, :path)
32
+ end
33
+ end
34
+
35
+ def target(obj, attribute_name, editing_options)
36
+ target = obj[attribute_name]
37
+ target = link_target(target) if target.is_a?(Link)
38
+ target = linklist_target(target) if target.is_a?(Enumerable)
39
+ target
40
+ end
41
+
42
+ def link_target(link)
43
+ link.internal? ? link.obj : link
44
+ end
45
+
46
+ def linklist_target(linklist)
47
+ if linklist.any?
48
+ link_target(linklist.first)
49
+ end
50
+ end
51
+
52
+ delegate :request, :main_app, :scrivito_engine, to: :view_context
53
+ end
54
+
55
+ end
@@ -135,6 +135,18 @@ module Scrivito
135
135
  dt
136
136
  end
137
137
 
138
+ # The alt description of a +Link+ used for {ScrivitoHelper#scrivito_image_tag}.
139
+ #
140
+ # By default this method returns the +title+ of this +Link+.
141
+ # If +title+ is nil and this +Link+ references an {BasicObj Obj}
142
+ # +alt_description+ of that {BasicObj Obj} is used.
143
+ #
144
+ # @api public
145
+ def alt_description
146
+ return title if title
147
+ obj.alt_description if internal?
148
+ end
149
+
138
150
  # Returns true this Link links to a CMS Object.
139
151
  # @api public
140
152
  def internal?
@@ -10,7 +10,7 @@ module Scrivito
10
10
 
11
11
  # @api public
12
12
  # @!method each
13
- # Iterate over all {Membership Memberships} of a specfic {Workspace}. Allows
13
+ # Iterate over all {Membership Memberships} of a specific {Workspace}. Allows
14
14
  # you to use all methods defined by ruby's Enumerable module.
15
15
  #
16
16
  # @yield [Membership]
@@ -18,7 +18,7 @@ module Scrivito
18
18
  # @return [Enumerator] if no block is given an Enumerator is returned
19
19
  #
20
20
  # @example
21
- # # Optain all owners of a workspace
21
+ # # Obtain all owners of a workspace
22
22
  # my_workspace.memberships.select do |membership|
23
23
  # membership.role == "owner"
24
24
  # end
@@ -71,6 +71,7 @@ module Scrivito
71
71
  private
72
72
 
73
73
  def memberships
74
+ return [] if workspace.published?
74
75
  @memberships ||= begin
75
76
  workspace.data.memberships.map do |id, data|
76
77
  Membership.new(id, data)
@@ -10,25 +10,18 @@ module Scrivito
10
10
  end
11
11
 
12
12
  def save(value)
13
- if Workspace.current.uses_obj_classes
14
- CmsRestApi.put(endpoint("objs/#{migration_store_obj.id}"), obj: {versions: value})
15
- else
16
- CmsRestApi.put(endpoint("objs/#{migration_store_obj.id}"),
17
- obj: {versions: ['string', value]})
18
- end
13
+ CmsRestApi.put(endpoint("objs/#{migration_store_obj.id}"),
14
+ obj: {versions: ['string', value]})
15
+
19
16
  Workspace.current.reload
20
17
  end
21
18
 
22
19
  private
23
20
 
24
21
  def create
25
- if Workspace.current.uses_obj_classes
26
- CmsRestApi.post(endpoint('objs'),
27
- obj: {_path: path, _obj_class: 'MigrationStore', versions: ''})
28
- else
29
- CmsRestApi.post(endpoint('objs'),
30
- obj: {_path: path, _obj_class: 'MigrationStore', versions: ['string', '']})
31
- end
22
+ CmsRestApi.post(endpoint('objs'),
23
+ obj: {_path: path, _obj_class: 'MigrationStore', versions: ['string', '']})
24
+
32
25
  Workspace.current.reload
33
26
  end
34
27
 
@@ -69,33 +69,12 @@ module Scrivito
69
69
  private
70
70
 
71
71
  def workspace
72
- workspace = migration_workspace
73
-
74
- if workspace
75
- if workspace_lock.exists?
76
- workspace_lock.validate(workspace)
77
- end
78
- else
79
- workspace = Workspace.create(title: 'Migration Working Copy', id: 'rtc')
80
- workspace_lock.write(workspace)
81
- end
82
-
83
- workspace
84
- end
85
-
86
- def migration_workspace
87
- Workspace.find('rtc')
88
- rescue ResourceNotFound
72
+ @workspace = workspace_lock.get
89
73
  end
90
74
 
91
75
  def remove_workspace_with(&block)
92
- workspace = migration_workspace
93
-
94
- if workspace
95
- workspace_lock.validate(workspace)
96
-
76
+ if workspace_lock.exists?
97
77
  yield
98
-
99
78
  workspace_lock.remove
100
79
  else
101
80
  raise ScrivitoError.new('Migration workspace does not exist')
@@ -5,17 +5,15 @@ module Scrivito
5
5
  class WorkspaceLock
6
6
  include Singleton
7
7
 
8
- def validate(workspace)
9
- unless exists? && workspace.revision_id == File.read(filename)
10
- raise ScrivitoError.new("There is a migration in progress right now. \
11
- Please try again after the migration working copy '#{workspace.id}' has \
12
- been published or removed.")
13
- end
14
- end
15
-
16
- def write(workspace)
17
- File.open(filename, 'w') do |file|
18
- file.write(workspace.revision_id)
8
+ def get
9
+ if exists?
10
+ begin
11
+ Workspace.find(workspace_id)
12
+ rescue Scrivito::ResourceNotFound
13
+ create_workspace
14
+ end
15
+ else
16
+ create_workspace
19
17
  end
20
18
  end
21
19
 
@@ -31,6 +29,20 @@ module Scrivito
31
29
 
32
30
  private
33
31
 
32
+ def create_workspace
33
+ Workspace.create(title: 'Migration Working Copy').tap do |workspace|
34
+ write(workspace)
35
+ end
36
+ end
37
+
38
+ def write(workspace)
39
+ File.write(filename, workspace.id)
40
+ end
41
+
42
+ def workspace_id
43
+ File.read(filename)
44
+ end
45
+
34
46
  def filename
35
47
  File.join(Rails.root, 'tmp/migration_store.lock')
36
48
  end
@@ -11,7 +11,7 @@ module Scrivito
11
11
 
12
12
  # This method will be called to retrieve the NamedLink {BasicObj Obj}.
13
13
  # By default it will look for the Obj at the path "_named_links".
14
- # Overwrite this method only if you know what you are doing.
14
+ # Override this method only if you know what you are doing.
15
15
  # @api public
16
16
  def self.find_named_link_obj
17
17
  BasicObj.find_by_path("/_named_links")
@@ -70,7 +70,7 @@ module Scrivito
70
70
  end
71
71
 
72
72
  # Returns a {ObjSearchEnumerator} of all Objs with the given +obj_class+.
73
- # @param [String] obj_class Name of the ObjClass.
73
+ # @param [String] obj_class name of the obj class.
74
74
  # @return [ObjSearchEnumerator]
75
75
  # @api public
76
76
  def find_all_by_obj_class(obj_class)
@@ -19,13 +19,6 @@ module Scrivito
19
19
  def convert_value(value, type)
20
20
  case type
21
21
  when 'html' then convert_text_links(value)
22
- when 'widget'
23
- if value.is_a?(Hash) && value.size == 1 && value.has_key?('list')
24
- # Legacy data with obj classes.
25
- value['list'].map { |item| item['widget'] }
26
- else
27
- value
28
- end
29
22
  else value
30
23
  end
31
24
  end
@@ -4,7 +4,7 @@ module Scrivito
4
4
  # This is done using the {http://ruby-doc.org/core-2.1.3/Enumerable.html <code>Enumerable</code> mixin},
5
5
  # which provides methods such as <code>map</code>, <code>select</code> or <code>take</code>.
6
6
  #
7
- # This enumerator is lazy. If for example you are looking for {BasicObj Obj}s with the ObjClass "Publication",
7
+ # This enumerator is lazy. If for example you are looking for {BasicObj Obj}s with the obj class "Publication",
8
8
  # and there are 93 objs in total, than <code>enum.take(10)</code> will fetch the first 10 objs only,
9
9
  # ignoring the other 83 objs.
10
10
  # This also means, that iterating multiple times over this enumerator causes the search results and objs to be fetched again.
@@ -22,7 +22,7 @@ module Scrivito
22
22
  # [+:title+] Title of an {BasicObj Obj}. This is a +string+ field.
23
23
  # [+:body+] Body of an {BasicObj Obj}. This is an +html+ field. Thus, only the +contains+ and
24
24
  # +contains_prefix+ operators can be applied to this field.
25
- # [+:_obj_class+] ObjClass of an {BasicObj Obj}. This is a +string+ field.
25
+ # [+:_obj_class+] obj class of an {BasicObj Obj}. This is a +string+ field.
26
26
  # [+:_permalink+] Permalink of an {BasicObj Obj}. This is a +string+ field.
27
27
  # [+:_last_changed+] Date of last change of an {BasicObj Obj}.
28
28
  # [every <em><code>:custom_attribute</code></em>] Custom attribute of an {BasicObj Obj}. Note that
@@ -0,0 +1,9 @@
1
+ module Scrivito
2
+ class ParentPath
3
+ def self.of(path)
4
+ return if path.nil?
5
+ return if path == '/'
6
+ path.gsub(/\/[^\/]+$/, '').presence || '/'
7
+ end
8
+ end
9
+ end
@@ -20,7 +20,7 @@ module Scrivito
20
20
  # @return [String]
21
21
  #
22
22
  def scrivito_path(target, options = {})
23
- CmsRouting.new(request, main_app).path_or_url(target, "path", options)
23
+ CmsRouting.new(request, main_app, scrivito_engine).path_or_url(target, "path", options)
24
24
  end
25
25
 
26
26
  #
@@ -36,7 +36,7 @@ module Scrivito
36
36
  # @return [String]
37
37
  #
38
38
  def scrivito_url(target, options = {})
39
- CmsRouting.new(request, main_app).path_or_url(target, "url", options)
39
+ CmsRouting.new(request, main_app, scrivito_engine).path_or_url(target, "url", options)
40
40
  end
41
41
  end
42
42
  end
@@ -52,8 +52,8 @@ module Scrivito
52
52
  # user.can_never(:create, :workspace, 'You are not allowed to create workspaces.')
53
53
  # user.can_always(:read, :workspace)
54
54
  #
55
- # user.restrict_obj_publish(using: :_obj_class) do |obj_class|
56
- # if obj_class.name == 'BlogPost'
55
+ # user.restrict_obj_publish(using: :_obj_class_name) do |obj_class_name|
56
+ # if obj_class_name == 'BlogPost'
57
57
  # false
58
58
  # else
59
59
  # 'You are not allowed to publish blog posts.'
@@ -184,8 +184,8 @@ module Scrivito
184
184
  # end
185
185
  # end
186
186
  #
187
- # user.restrict_obj_publish(using: :_obj_class) do |obj_class|
188
- # if obj_class.name == 'BlogPost'
187
+ # user.restrict_obj_publish(using: :_obj_class_name) do |obj_class_name|
188
+ # if obj_class_name == 'BlogPost'
189
189
  # false
190
190
  # else
191
191
  # 'You are only allowed to edit Blog Posts'
@@ -80,8 +80,8 @@ class WidgetGarbageCollection
80
80
  else
81
81
  params.each do |key, value|
82
82
  if content.type_of_attribute(key) == 'widgetlist'
83
- current = content[key]
84
- new = value
83
+ current = content[key] || []
84
+ new = value || []
85
85
 
86
86
  dereferenced_ids += current - new
87
87
  newreferenced_ids += new - current
@@ -1,16 +1,19 @@
1
1
  module Scrivito
2
2
 
3
- class WidgetTag < Struct.new(:view, :widget, :placement_modification, :template_name)
3
+ class WidgetTag < Struct.new(:view, :widget, :placement_modification, :template_name, :inner_tag)
4
+ DEFAULT_TAG = "div"
5
+
4
6
  include TagRenderer
5
7
 
6
8
  def tag_name
7
- :div
9
+ inner_tag || DEFAULT_TAG
8
10
  end
9
11
 
10
12
  def content
11
13
  view.render(template: template_path, locals: {widget: widget})
12
14
  rescue ActionView::MissingTemplate
13
- %{Missing Ruby model class for "#{widget.obj_class_name}"} if view.scrivito_user
15
+ raise if Rails.env.development? || Rails.env.test?
16
+ "Missing show template for #{widget.description_for_editor}" if view.scrivito_user
14
17
  end
15
18
 
16
19
  def options
@@ -5,8 +5,6 @@ module Scrivito
5
5
  # This class represents a CMS workspace
6
6
  # @api public
7
7
  class Workspace
8
- PUBLISHED_ID = 'published'
9
-
10
8
  extend ActiveModel::Naming
11
9
 
12
10
  include ModelIdentity
@@ -31,7 +29,7 @@ class Workspace
31
29
  if @current.respond_to? :call
32
30
  @current = @current.call
33
31
  else
34
- @current ||= default
32
+ @current ||= published
35
33
  end
36
34
  end
37
35
 
@@ -41,19 +39,13 @@ class Workspace
41
39
  def self.all
42
40
  result_json = CmsRestApi.get('/workspaces')
43
41
 
44
- result_json['results'].map do |workspace_json|
45
- Workspace.find(workspace_json['id'])
42
+ result_json['results'].map do |raw_data|
43
+ Workspace.new(WorkspaceData.new(raw_data))
46
44
  end
47
45
  end
48
46
 
49
- def self.default
50
- published
51
- end
52
-
53
47
  def self.published
54
- cache.fetch(PUBLISHED_ID) do
55
- cache[PUBLISHED_ID] = find(PUBLISHED_ID)
56
- end
48
+ find("published")
57
49
  end
58
50
 
59
51
  # Find a workspace by its id
@@ -62,10 +54,14 @@ class Workspace
62
54
  # @return [Scrivito::Workspace]
63
55
  # @raise [Scrivito::ResourceNotFound]
64
56
  def self.find(id)
65
- if workspace_data = CmsBackend.instance.find_workspace_data_by_id(id)
66
- Workspace.new workspace_data
67
- else
68
- raise ResourceNotFound, "Could not find #{self} with id #{id}"
57
+ cache.fetch(id) do
58
+ workspace_data = CmsBackend.instance.find_workspace_data_by_id(id)
59
+
60
+ unless workspace_data
61
+ raise ResourceNotFound, "Could not find #{self} with id #{id}"
62
+ end
63
+
64
+ cache[id] = Workspace.new(workspace_data)
69
65
  end
70
66
  end
71
67
 
@@ -79,8 +75,38 @@ class Workspace
79
75
  all.detect { |workspace| workspace.title == title }
80
76
  end
81
77
 
78
+ # Find a workspace by its id or title and set it as the currently used workspace.
79
+ # @example
80
+ # Scrivito::Workspace.use('6a75fe694eeeb093')
81
+ #
82
+ # Scrivito::Workspace.current.id
83
+ # # => '6a75fe694eeeb093'
84
+ #
85
+ # Scrivito::Workspace.use('my working copy')
86
+ #
87
+ # Scrivito::Workspace.current.title
88
+ # # => 'my working copy'
89
+ #
90
+ # # raises Scrivito::ResourceNotFound:
91
+ # Scrivito::Workspace.use('missing')
92
+ # @api public
93
+ # @param [String] id_or_title
94
+ # @return [void]
95
+ # @raise [Scrivito::ResourceNotFound]
96
+ def self.use(id_or_title)
97
+ workspace = begin
98
+ find(id_or_title)
99
+ rescue ResourceNotFound
100
+ find_by_title(id_or_title)
101
+ end
102
+ if workspace.blank?
103
+ raise(ResourceNotFound, "Could not find #{self} with id or title #{id_or_title}")
104
+ end
105
+ self.current = workspace
106
+ end
107
+
82
108
  delegate :content_state_id, :base_content_state_id, :content_state,
83
- :base_revision_id, :base_content_state, :uses_obj_classes, to: :data
109
+ :base_revision_id, :base_content_state, to: :data
84
110
 
85
111
  # Create a new workspace
86
112
  # @api public
@@ -96,8 +122,7 @@ class Workspace
96
122
  # since it was loaded
97
123
  # @api public
98
124
  def self.reload
99
- id = current.id
100
- self.current_using_proc = proc { find(id) }
125
+ current.reload
101
126
  end
102
127
 
103
128
  def self.cache
@@ -135,6 +160,7 @@ class Workspace
135
160
  # @param [Hash] attributes
136
161
  # @return [Scrivito::Workspace]
137
162
  def update(attributes)
163
+ raise ScrivitoError, 'published workspace is not modifiable' if published?
138
164
  CmsRestApi.put(backend_url, workspace: attributes)
139
165
  reload
140
166
  end
@@ -151,6 +177,8 @@ class Workspace
151
177
  def publish
152
178
  CmsRestApi.put("#{backend_url}/publish", {})
153
179
 
180
+ Workspace.published.reload
181
+
154
182
  reset_workspace_if_current
155
183
  end
156
184
 
@@ -172,11 +200,12 @@ class Workspace
172
200
  @workspace_data.revision_id
173
201
  end
174
202
 
175
- # Returns the title of the workspace
203
+ # Returns the title of the workspace or an empty +String+
176
204
  # @api public
177
205
  # @return [String]
178
206
  def title
179
- @workspace_data.title
207
+ return '' if published?
208
+ @workspace_data.title || ''
180
209
  end
181
210
 
182
211
  # @api public
@@ -195,15 +224,18 @@ class Workspace
195
224
  self.id == 'published'
196
225
  end
197
226
 
198
- def rtc?
199
- self.id == 'rtc'
200
- end
201
-
202
227
  def outdated?
203
228
  !published? && Workspace.published.revision.id != base_revision_id
204
229
  end
205
230
 
206
231
  def revision
232
+ unless data.content_state_id?
233
+ # reload data from changes feed in order to obtain content_state_id
234
+ reload
235
+
236
+ raise InternalError unless data.content_state_id?
237
+ end
238
+
207
239
  @revision ||= Revision.new(id: revision_id, workspace: self)
208
240
  end
209
241
 
@@ -231,7 +263,6 @@ class Workspace
231
263
 
232
264
  def assert_revertable
233
265
  raise ScrivitoError, 'published workspace is not modifiable' if published?
234
- raise ScrivitoError, 'rtc workspace may contain attribute and class changes' if rtc?
235
266
  end
236
267
 
237
268
  # {ObjCollection} for this working copy
@@ -241,19 +272,6 @@ class Workspace
241
272
  @objs ||= ObjCollection.new(self)
242
273
  end
243
274
 
244
- # Returns all obj classes of this working copy.
245
- #
246
- # @api public
247
- # @deprecated
248
- #
249
- # @example Find the obj class named "Homepage" in the "rtc" {Workspace}.
250
- # Workspace.find('rtc').obj_classes['Homepage']
251
- #
252
- # @return {ObjClassCollection}
253
- def obj_classes
254
- @obj_classes ||= ObjClassCollection.new(self)
255
- end
256
-
257
275
  def inspect
258
276
  "<#{self.class} id=\"#{id}\" title=\"#{title}\">"
259
277
  end
@@ -281,11 +299,12 @@ class Workspace
281
299
  end
282
300
 
283
301
  def reset_workspace_if_current
302
+ Workspace.cache.delete(id)
303
+
284
304
  if Workspace.current == self
285
- Workspace.current = Workspace.default
305
+ Workspace.current = Workspace.published
286
306
  end
287
307
  end
288
-
289
308
  end
290
309
 
291
310
  end