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
@@ -27,17 +27,16 @@ module CmsDataCache
27
27
  end
28
28
 
29
29
  SCHEMA = {
30
- workspace_data: 'workspace/#{workspace_id}',
31
-
32
30
  # CONTENT SERVICE
33
31
  content_state: 'content/#{content_state_id}',
34
32
  obj_data: 'content/#{content_state_id}/obj/#{index}/#{key}',
35
- obj_classes_data: 'content/#{content_state_id}/obj_classes',
33
+ workspace_data: 'workspace/#{workspace_id}',
36
34
 
37
35
  # REST API
38
36
  obj_data_rest: 'obj/#{cache_id}/#{index}/#{key}',
39
37
  content_state_node: 'csn/#{content_state_id}',
40
- workspace_csid: 'wscsid/#{workspace_id}'
38
+ workspace_state: 'wrkstt/#{workspace_id}',
39
+ tag_data: 'tagd/#{tag}'
41
40
  }
42
41
 
43
42
  SCHEMA.each do |name, schema|
@@ -59,6 +58,24 @@ module CmsDataCache
59
58
  cache.write("#{schema}", data)
60
59
  end
61
60
  END
61
+
62
+ # for test purposes
63
+ class_eval(<<-END, __FILE__, __LINE__ + 1)
64
+ def evict_#{name}(#{params_code})
65
+ cache.write("#{schema}", nil)
66
+ end
67
+ END
68
+ end
69
+
70
+ def write_data_to_tag(data)
71
+ tag = Digest::SHA1.base64digest(Marshal::dump(data))
72
+ write_tag_data(tag, data)
73
+
74
+ tag
75
+ end
76
+
77
+ def read_data_from_tag(tag)
78
+ read_tag_data(tag)
62
79
  end
63
80
 
64
81
  private
@@ -17,6 +17,11 @@ module Scrivito
17
17
  end
18
18
  end
19
19
 
20
+ if obj_not_found? && editing_context.workspace_changed?
21
+ redirect_to scrivito_path(Obj.homepage)
22
+ return self.response
23
+ end
24
+
20
25
  controller = target_controller(env)
21
26
  env["action_dispatch.request.path_parameters"]["controller"] = controller.controller_path
22
27
 
@@ -35,6 +40,14 @@ module Scrivito
35
40
  Rails.application.routes.url_helpers
36
41
  end
37
42
 
43
+ def scrivito_engine
44
+ Scrivito::SdkEngine.routes.url_helpers
45
+ end
46
+
47
+ def editing_context
48
+ EditingContextMiddleware.from_request(request)
49
+ end
50
+
38
51
  def target_controller(env)
39
52
  return default_controller if obj_not_found?
40
53
  controller = "#{loaded_obj.controller_name}Controller".constantize
@@ -1,7 +1,7 @@
1
1
  module Scrivito
2
2
 
3
3
  # this class is the server-side equivalent of the JavaScript class `cms_field_element`
4
- class CmsFieldTag < Struct.new(:view, :tag_name, :obj_or_widget, :field_name, :widget_template_name)
4
+ class CmsFieldTag < Struct.new(:view, :tag_name, :obj_or_widget, :editing_options)
5
5
  FIELD_TYPES_WITH_ORIGINAL_CONTENT = %w[
6
6
  binary
7
7
  date
@@ -11,7 +11,7 @@ class CmsFieldTag < Struct.new(:view, :tag_name, :obj_or_widget, :field_name, :w
11
11
  reference
12
12
  referencelist
13
13
  string
14
- text
14
+ stringlist
15
15
  ]
16
16
 
17
17
  include TagRenderer
@@ -21,7 +21,7 @@ class CmsFieldTag < Struct.new(:view, :tag_name, :obj_or_widget, :field_name, :w
21
21
  raise ArgumentError, 'No block allowed for widgetlist fields' if block_given?
22
22
  modifications = modification_info || []
23
23
  rendered_widgets = default_content.each_with_index.map do |widget, index|
24
- WidgetTag.new(view, widget, modifications[index], widget_template_name).render
24
+ WidgetTag.new(view, widget, modifications[index], widget_template_name, inner_tag).render
25
25
  end
26
26
  view.safe_join(rendered_widgets)
27
27
  else
@@ -59,6 +59,7 @@ class CmsFieldTag < Struct.new(:view, :tag_name, :obj_or_widget, :field_name, :w
59
59
  end
60
60
 
61
61
  if field_type == 'widgetlist'
62
+ options["private-field-widget-inner-tag"] = inner_tag
62
63
  options['private-field-widget-allowed-classes'] = build_valid_widget_classes.to_json
63
64
  options['private-field-widget-template'] = widget_template_name
64
65
  end
@@ -83,6 +84,18 @@ class CmsFieldTag < Struct.new(:view, :tag_name, :obj_or_widget, :field_name, :w
83
84
  end
84
85
  end
85
86
 
87
+ def widget_template_name
88
+ editing_options[:widget_template_name]
89
+ end
90
+
91
+ def field_name
92
+ editing_options[:field_name]
93
+ end
94
+
95
+ def inner_tag
96
+ editing_options[:inner_tag] || WidgetTag::DEFAULT_TAG
97
+ end
98
+
86
99
  def field_type
87
100
  @field_type ||= obj_or_widget.type_of_attribute(field_name)
88
101
  end
@@ -18,11 +18,11 @@ module Scrivito
18
18
  #
19
19
  # @example Specify a poll interval (in seconds; default: 2) to use in case the response
20
20
  # is a task reference response and the final response is polled for:
21
- # Scrivito::CmsRestApi.put('workspace/rtc/publish', nil, :interval => 10)
21
+ # Scrivito::CmsRestApi.put('workspace/001384beff9e5845/publish', nil, :interval => 10)
22
22
  #
23
23
  # @example Return immediately with the first response (without polling in case it is a
24
24
  # task reference response):
25
- # Scrivito::CmsRestApi.task_unaware_request(:put, 'workspace/rtc/publish', nil)
25
+ # Scrivito::CmsRestApi.task_unaware_request(:put, 'workspace/001384beff9e5845/publish', nil)
26
26
  #
27
27
  class CmsRestApi
28
28
  METHOD_TO_NET_HTTP_CLASS = {
@@ -1,6 +1,6 @@
1
1
  module Scrivito
2
2
 
3
- class CmsRouting < Struct.new(:request, :main_app)
3
+ class CmsRouting < Struct.new(:request, :main_app, :scrivito_engine, :image_options)
4
4
  LINK_TO_EMPTY_LINKLIST = "#__empty_linklist"
5
5
  LINK_TO_EMPTY_BLOB = "#__empty_blob"
6
6
 
@@ -9,8 +9,8 @@ class CmsRouting < Struct.new(:request, :main_app)
9
9
  end
10
10
 
11
11
  def path_or_url(target, path_or_url, options = {})
12
- if cms_with_editing_context?(target)
13
- path_or_url_with_editing_context(target, path_or_url, options)
12
+ if needs_editing_context?(target)
13
+ path_or_url_needs_editing_context(target, path_or_url, options)
14
14
  else
15
15
  path_or_url_without_editing_context(target, path_or_url, options)
16
16
  end
@@ -31,7 +31,11 @@ class CmsRouting < Struct.new(:request, :main_app)
31
31
  end
32
32
  end
33
33
 
34
- path_or_url(obj, "path", options)
34
+ if editing_context.display_mode == 'editing'
35
+ id_path_or_url_for_objs(obj, :path, options)
36
+ else
37
+ path_or_url(obj, :path, options)
38
+ end
35
39
  else
36
40
  "#__target_object_not_reachable"
37
41
  end
@@ -41,9 +45,9 @@ class CmsRouting < Struct.new(:request, :main_app)
41
45
 
42
46
  private
43
47
 
44
- def path_or_url_with_editing_context(target, path_or_url, options)
48
+ def path_or_url_needs_editing_context(target, path_or_url, options)
45
49
  path_or_url_without_editing_context(target, path_or_url,
46
- options.merge(editing_context.to_params))
50
+ options.merge(editing_context.to_params))
47
51
  end
48
52
 
49
53
  def path_or_url_without_editing_context(target, path_or_url, options)
@@ -58,33 +62,30 @@ class CmsRouting < Struct.new(:request, :main_app)
58
62
  return LINK_TO_EMPTY_LINKLIST
59
63
  end
60
64
  elsif target.is_a?(Binary)
61
- target.url
65
+ binary_url(target, path_or_url)
62
66
  else
63
67
  raise "scrivito_path or scrivito_url was called with an instance of #{target.class}. "+
64
68
  "It must only be called with an Obj or a Link or a non-empty LinkList."
65
69
  end
66
70
  end
67
71
 
68
- def path_or_url_for_links(link, path_or_url, options = {})
72
+ def path_or_url_for_links(link, path_or_url, options)
69
73
  url = basic_url_or_path_for_link(link, path_or_url,
70
- Rack::Utils.parse_nested_query(link.query).merge(options))
74
+ Rack::Utils.parse_nested_query(link.query).merge(options))
71
75
  url = url + "##{link.fragment}" if link.fragment.present?
72
76
  url
73
77
  end
74
78
 
75
- def path_or_url_for_objs(obj, path_or_url, options = {})
76
- if editing_context.display_mode == "editing"
77
- return id_path_or_url_for_objs(obj, path_or_url, options)
78
- end
79
-
79
+ def path_or_url_for_objs(obj, path_or_url, options)
80
80
  permalink = obj.permalink
81
81
  if permalink
82
- main_app.public_send("scrivito_permalink_#{path_or_url}", options.merge(:permalink => permalink))
82
+ main_app
83
+ .public_send("scrivito_permalink_#{path_or_url}", options.merge(:permalink => permalink))
83
84
  elsif obj.homepage?
84
85
  main_app.public_send("scrivito_root_#{path_or_url}", options)
85
86
  elsif obj.binary?
86
- if obj.binary_url
87
- obj.binary_url
87
+ if binary = obj.binary
88
+ binary_url(binary, path_or_url)
88
89
  else
89
90
  LINK_TO_EMPTY_BLOB
90
91
  end
@@ -112,7 +113,7 @@ class CmsRouting < Struct.new(:request, :main_app)
112
113
  EditingContextMiddleware.from_request(request)
113
114
  end
114
115
 
115
- def cms_with_editing_context?(target)
116
+ def needs_editing_context?(target)
116
117
  editor_authenticated? && (!target.is_a?(Link) || target.internal?)
117
118
  end
118
119
 
@@ -139,6 +140,28 @@ class CmsRouting < Struct.new(:request, :main_app)
139
140
  def extract_query(uri)
140
141
  Rack::Utils.parse_query(uri.query)
141
142
  end
143
+
144
+ def binary_url(binary, path_or_url)
145
+ binary = transform_binary(binary)
146
+ if url_from_cache = binary.url_from_cache
147
+ BinaryRewrite.call(request, url_from_cache)
148
+ else
149
+ encrypted_params = BinaryParamVerifier.generate(binary)
150
+ scrivito_engine.public_send("binary_#{path_or_url}", encrypted_params: encrypted_params)
151
+ end
152
+ end
153
+
154
+ def transform_binary(binary)
155
+ if transformation_definition = image_options[:transform]
156
+ binary.transform(transformation_definition)
157
+ else
158
+ binary
159
+ end
160
+ end
161
+
162
+ def image_options
163
+ super || {}
164
+ end
142
165
  end
143
166
 
144
167
  end
@@ -207,6 +207,7 @@ module Scrivito
207
207
  self.endpoint = 'api.scrivito.com'
208
208
  self.check_batch_size = 100
209
209
  self.legacy_routing = false
210
+ self.default_image_transformation = {}
210
211
  end
211
212
 
212
213
  #
@@ -234,6 +235,27 @@ module Scrivito
234
235
 
235
236
  attr_accessor :choose_homepage_callback, :check_batch_size
236
237
 
238
+ #
239
+ # Set the default {Scrivito::Binary#transform image transformation}.
240
+ #
241
+ # @api beta
242
+ #
243
+ # When delivering binary Objs, the default image transformation will be applied if
244
+ # {Scrivito::BasicObj#apply_image_transformation? Obj#apply_image_transformation?} returns
245
+ # +true+.
246
+ #
247
+ # If not changed the default image transformation is an empty transformation (an empty +Hash+).
248
+ # Set it to +false+ to disabled the default image transformation completely.
249
+ #
250
+ # @param [Hash] value the {Scrivito::Binary#transform transformation definition}
251
+ #
252
+ # @see Scrivito::Binary#transform
253
+ # @see Scrivito::BasicObj#apply_image_transformation?
254
+ #
255
+ attr_writer :default_image_transformation
256
+
257
+ attr_reader :default_image_transformation
258
+
237
259
  # Configure a callback to be invoked when the Scrivito SDK delivers the homepage.
238
260
  # The given callback will receive the rack env
239
261
  # and must return an {BasicObj Obj} to be used as the homepage.
@@ -48,14 +48,6 @@ class ContentState < Struct.new(:content_state_id, :changes, :changes_index, :fr
48
48
  CmsDataCache.read_obj_data(content_state_id, index, key)
49
49
  end
50
50
 
51
- def save_obj_classes_data(data)
52
- CmsDataCache.write_obj_classes_data(content_state_id, data)
53
- end
54
-
55
- def find_obj_classes_data
56
- CmsDataCache.read_obj_classes_data(content_state_id)
57
- end
58
-
59
51
  # Fetches and caches the ancestor.
60
52
  # Returns nil if there is no ancestor.
61
53
  def from_content_state
@@ -82,7 +74,7 @@ class ContentState < Struct.new(:content_state_id, :changes, :changes_index, :fr
82
74
  id_index.add(hash['id'])
83
75
  if path = hash['modified_path']
84
76
  path_index.add(path)
85
- ppath_index.add(path.gsub(/\/[^\/]+$/, '').presence || '/') if path != '/'
77
+ ppath_index.add(ParentPath.of(path)) if path != '/'
86
78
  end
87
79
  end
88
80
  end
@@ -38,26 +38,6 @@ module ContentStateCaching
38
38
  nil
39
39
  end
40
40
  end
41
-
42
- def store_obj_classes_data(content_state, data)
43
- content_state.save_obj_classes_data(data)
44
- end
45
-
46
- def find_obj_classes_data(current_content_state)
47
- visitor = ContentStateVisitor.new(current_content_state)
48
-
49
- cache_lookup_depth.times do |depth|
50
- return unless content_state = visitor.visit_next
51
- if obj_classes_data = content_state.find_obj_classes_data
52
- if depth >= cache_replication_depth
53
- current_content_state.save_obj_classes_data(obj_classes_data)
54
- end
55
- return obj_classes_data
56
- end
57
- end
58
-
59
- nil
60
- end
61
41
  end
62
42
 
63
43
  self.cache_replication_depth = 5
@@ -39,7 +39,8 @@ module ControllerActions
39
39
 
40
40
  def show_widget
41
41
  widget = load_widget
42
- widget_tag = Scrivito::WidgetTag.new(view_context, widget, nil, params[:template_name])
42
+ widget_tag = Scrivito::WidgetTag.new(view_context, widget, nil,
43
+ params[:template_name], params[:inner_tag])
43
44
  render text: widget_tag.render, layout: false
44
45
  end
45
46
 
@@ -71,7 +72,7 @@ module ControllerActions
71
72
  # This method indicates if this controller should be used automatically when an +Obj+ is
72
73
  # requested via the SDK's standard routes. It returns +true+ by default.
73
74
  #
74
- # Overwrite it to return +false+ if you do want your controller to be excluded from +Obj+
75
+ # Override it to return +false+ if you do want your controller to be excluded from +Obj+
75
76
  # dispatching.
76
77
  #
77
78
  # @api public
@@ -7,28 +7,36 @@ module ControllerRuntime
7
7
 
8
8
  protected
9
9
 
10
- attr_internal :rc_runtime
10
+ attr_internal :scrivito_runtime
11
11
 
12
12
  def cleanup_view_runtime
13
- rc_rt_before_render = Scrivito::LogSubscriber.reset_runtime
13
+ self.scrivito_runtime = reset_scrivito_runtime
14
+
14
15
  runtime = super
15
- rc_rt_after_render = Scrivito::LogSubscriber.reset_runtime
16
- self.rc_runtime = rc_rt_before_render + rc_rt_after_render
17
- runtime - rc_rt_after_render
16
+
17
+ scrivito_rt_after_render = reset_scrivito_runtime
18
+ self.scrivito_runtime += scrivito_rt_after_render
19
+
20
+ runtime - scrivito_rt_after_render
18
21
  end
19
22
 
20
23
  def append_info_to_payload(payload)
21
24
  super
22
- payload[:rc_runtime] = rc_runtime
25
+ payload[:scrivito_runtime] =
26
+ (self.scrivito_runtime || 0) + reset_scrivito_runtime
23
27
  end
24
28
 
25
29
  module ClassMethods
26
30
  def log_process_action(payload)
27
- messages, rc_runtime = super, payload[:rc_runtime]
28
- messages << ("Scrivito: %.1fms" % rc_runtime.to_f)
31
+ messages, scrivito_runtime = super, payload[:scrivito_runtime]
32
+ messages << ("Scrivito: %.1fms" % scrivito_runtime.to_f)
29
33
  messages
30
34
  end
31
35
  end
36
+
37
+ def reset_scrivito_runtime
38
+ Scrivito::LogSubscriber.reset_runtime
39
+ end
32
40
  end
33
41
 
34
42
  end # module Scrivito
@@ -0,0 +1,11 @@
1
+ module Scrivito
2
+
3
+ class DialogSizeHelper
4
+ def self.render_dialog_with_size(view, size, &block)
5
+ view.content_tag(:div, 'data-scrivito-modal-size' => size) do
6
+ view.capture { yield }
7
+ end
8
+ end
9
+ end
10
+
11
+ end
@@ -11,8 +11,6 @@ class Diff; class << self
11
11
  ListComparison.for(mode, old || [], new || [])
12
12
  when "html"
13
13
  for_html(mode, old, new)
14
- when "text"
15
- for_string(mode, old, new)
16
14
  when "string"
17
15
  for_string(mode, old, new)
18
16
  end
@@ -5,11 +5,13 @@ class EditingContext
5
5
  # +:selected_workspace_id+: The id of the selected workspace. If empty +published+ workspace is used.
6
6
  # +:display_mode+: Can be +view+, +editing+, +added+ or +deleted+. If empty +view+ is used.
7
7
  # +:editor+: A block, which is lazy evaluated on first access, to determine the editor (details see {Scrivito::Configuration.editing_auth})
8
+ # +:workspace_changed+: A boolean, determining if the workspace has been changed with this request.
8
9
  # @param [Hash] options
9
10
  def initialize(options = {})
10
11
  @selected_workspace_id = options[:selected_workspace_id]
11
12
  @display_mode = options[:display_mode] || "view"
12
13
  @editor_callback = options[:editor] || proc { false }
14
+ @workspace_changed = !!options[:workspace_changed]
13
15
  end
14
16
 
15
17
  def editor
@@ -34,6 +36,10 @@ class EditingContext
34
36
  editor.present?
35
37
  end
36
38
 
39
+ def workspace_changed?
40
+ @workspace_changed
41
+ end
42
+
37
43
  # @return [String]
38
44
  def display_mode
39
45
  if authenticated_editor? && !selected_workspace.published?
@@ -80,31 +86,36 @@ class EditingContext
80
86
 
81
87
  def find_selected_workspace
82
88
  if @selected_workspace_id
83
- begin
84
- workspace = Workspace.find(@selected_workspace_id)
85
- if editor && editor.can?(:read, workspace)
86
- workspace
87
- else
88
- default_workspace
89
+ workspace =
90
+ begin
91
+ Workspace.find(@selected_workspace_id)
92
+ rescue
93
+ Rails.logger.info "Workspace with ID #{@selected_workspace_id} is " +
94
+ "not available, using 'published' instead."
95
+
96
+ published_workspace
89
97
  end
90
- rescue Scrivito::ResourceNotFound
91
- default_workspace
98
+
99
+ if editor && editor.can?(:read, workspace)
100
+ workspace
101
+ else
102
+ published_workspace
92
103
  end
93
104
  else
94
- default_workspace
105
+ published_workspace
95
106
  end
96
107
  end
97
108
 
98
109
  def find_visible_workspace
99
110
  if authenticated_editor?
100
- display_mode == 'deleted' ? default_workspace : selected_workspace
111
+ display_mode == 'deleted' ? published_workspace : selected_workspace
101
112
  else
102
- default_workspace
113
+ published_workspace
103
114
  end
104
115
  end
105
116
 
106
- def default_workspace
107
- Workspace.default
117
+ def published_workspace
118
+ Workspace.published
108
119
  end
109
120
 
110
121
  # @return [Revision] or +nil+