scrivito_sdk 0.65.2 → 0.66.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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