scrivito_sdk 0.66.0 → 0.70.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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/scrivito/blobs_controller.rb +5 -0
  3. data/app/controllers/scrivito/objs_controller.rb +2 -1
  4. data/app/controllers/scrivito/ui_controller.rb +33 -3
  5. data/app/helpers/scrivito_helper.rb +14 -20
  6. data/app/views/scrivito/objs/update.json.jbuilder +1 -1
  7. data/app/views/scrivito/ui/index.html.erb +1 -1
  8. data/app/views/scrivito/webservice/_workspace.json.jbuilder +2 -1
  9. data/config/ca-bundle.crt +1 -1
  10. data/config/precedence_routes.rb +3 -2
  11. data/lib/assets/javascripts/scrivito.js +46 -0
  12. data/lib/assets/javascripts/scrivito_ui.js +931 -501
  13. data/lib/assets/stylesheets/scrivito.css +1 -0
  14. data/lib/assets/stylesheets/scrivito_ui.css +1 -1
  15. data/lib/generators/scrivito/install/templates/app/views/page/index.html.erb +3 -3
  16. data/lib/generators/scrivito/page/page_generator.rb +3 -0
  17. data/lib/generators/scrivito/page/templates/model.erb +3 -0
  18. data/lib/generators/scrivito/widget/templates/model.erb +3 -0
  19. data/lib/generators/scrivito/widget/widget_generator.rb +3 -0
  20. data/lib/scrivito/attribute_content.rb +93 -60
  21. data/lib/scrivito/attribute_definition.rb +3 -3
  22. data/lib/scrivito/attribute_serializer.rb +2 -2
  23. data/lib/scrivito/backend/obj_data_cache.rb +22 -9
  24. data/lib/scrivito/basic_obj.rb +238 -130
  25. data/lib/scrivito/basic_widget.rb +32 -20
  26. data/lib/scrivito/binary.rb +74 -45
  27. data/lib/scrivito/binary_routing.rb +52 -0
  28. data/lib/scrivito/cache_middleware.rb +0 -5
  29. data/lib/scrivito/client_attribute_serializer.rb +134 -0
  30. data/lib/scrivito/cms_backend.rb +51 -33
  31. data/lib/scrivito/cms_data_cache.rb +1 -0
  32. data/lib/scrivito/cms_dispatch_controller.rb +1 -1
  33. data/lib/scrivito/cms_env.rb +1 -11
  34. data/lib/scrivito/cms_field_tag.rb +10 -7
  35. data/lib/scrivito/cms_rest_api/rate_limit.rb +5 -5
  36. data/lib/scrivito/cms_rest_api/request_timer.rb +27 -0
  37. data/lib/scrivito/cms_rest_api/widget_extractor.rb +8 -6
  38. data/lib/scrivito/cms_rest_api.rb +107 -54
  39. data/lib/scrivito/cms_routing.rb +13 -25
  40. data/lib/scrivito/configuration.rb +5 -2
  41. data/lib/scrivito/controller_actions.rb +68 -7
  42. data/lib/scrivito/controller_runtime.rb +8 -0
  43. data/lib/scrivito/date_attribute.rb +8 -0
  44. data/lib/scrivito/errors.rb +6 -3
  45. data/lib/scrivito/generator_helper.rb +13 -0
  46. data/lib/scrivito/image_tag.rb +24 -30
  47. data/lib/scrivito/layout_tags.rb +12 -6
  48. data/lib/scrivito/link.rb +46 -30
  49. data/lib/scrivito/log_subscriber.rb +15 -0
  50. data/lib/scrivito/membership.rb +3 -3
  51. data/lib/scrivito/membership_collection.rb +10 -10
  52. data/lib/scrivito/meta_data_collection.rb +22 -0
  53. data/lib/scrivito/model_library.rb +7 -1
  54. data/lib/scrivito/obj_collection.rb +18 -16
  55. data/lib/scrivito/obj_params_parser.rb +1 -1
  56. data/lib/scrivito/obj_search_enumerator.rb +35 -35
  57. data/lib/scrivito/page_config.rb +55 -0
  58. data/lib/scrivito/request_homepage.rb +23 -0
  59. data/lib/scrivito/routing_helper.rb +8 -8
  60. data/lib/scrivito/sdk_engine.rb +2 -3
  61. data/lib/scrivito/ui_config.rb +85 -0
  62. data/lib/scrivito/user.rb +30 -23
  63. data/lib/scrivito/user_definition.rb +48 -47
  64. data/lib/scrivito/widget_tag.rb +11 -0
  65. data/lib/scrivito/workspace.rb +93 -35
  66. data/lib/scrivito/workspace_selection_middleware.rb +8 -1
  67. data/lib/scrivito_sdk.rb +24 -24
  68. metadata +24 -33
  69. data/lib/assets/javascripts/scrivito_sdk.js +0 -57
  70. data/lib/assets/stylesheets/scrivito_sdk.css +0 -1
  71. data/lib/scrivito/client_config.rb +0 -113
  72. data/lib/scrivito/editing_context_helper.rb +0 -19
  73. data/lib/scrivito/named_link.rb +0 -39
@@ -9,32 +9,33 @@ module Scrivito
9
9
  end
10
10
 
11
11
  #
12
- # Adds an explicit rule, that allows the user to _always_ execute an action.
13
- # A rule consists of a verb of the action, the subject of the action and an optional message.
12
+ # Adds an explicit rule that allows the user to _always_ execute an action.
13
+ # A rule consists of an action verb, the subject of the action, and an optional message.
14
14
  #
15
15
  # @api public
16
16
  #
17
- # @note Normally the memberships of a workspace decide whether a user is allowed or not to
18
- # execute a specific action. This method allows to add an exception to this logic and thus
17
+ # @note Usually, the memberships of a workspace decide whether a user is allowed or not to
18
+ # perform a specific action. This method lets you add an exception to this logic and thus
19
19
  # should be used carefully.
20
- # @note By default all users are allowed to create a new workspace.
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
22
  #
22
23
  # @param [Symbol] verb the verb of the action (see {Scrivito::User::VERBS}).
23
- # @param [Symbol] subject the subject of the action. At the moment only +:workspace+ is supported.
24
+ # @param [Symbol] subject the subject of the action. Currently, only +:workspace+ is supported.
24
25
  # @param [String] message optional message to be displayed in the UI.
25
26
  #
26
27
  # @raise [Scrivito::ScrivitoError] if the given verb is invalid
27
- # @raise [Scrivito::ScrivitoError] if the specified rule conflicts with a rule specified with
28
- # {Scrivito::UserDefinition#can_never}.
28
+ # @raise [Scrivito::ScrivitoError] if the specified rule conflicts with a
29
+ # {Scrivito::UserDefinition#can_never} rule.
29
30
  #
30
31
  # @see Scrivito::User::VERBS
31
32
  # @see Scrivito::UserDefinition#can_never
32
33
  #
33
- # @example User can _always_ read, write and publish a workspace, ignoring the memberships
34
+ # @example User can _always_ read from, write to, and publish a workspace, ignoring the memberships:
34
35
  # Scrivito::User.define('alice') do |user|
35
36
  # user.can_always(:read, :workspace)
36
37
  # user.can_always(:write, :workspace)
37
- # user.can_always(:publish, :workspace, 'You can always publish a workspace')
38
+ # user.can_always(:publish, :workspace, 'You can always publish a workspace.')
38
39
  # end
39
40
  #
40
41
  def can_always(verb, subject, message = nil)
@@ -43,34 +44,34 @@ module Scrivito
43
44
  end
44
45
 
45
46
  #
46
- # Adds an explicit rule, that forbids the user to execute an action.
47
- # A rule consists of a verb of the action, the subject of the action and an optional message.
47
+ # Adds an explicit rule that forbids the user to execute an action.
48
+ # A rule consists of an action verb, the subject of the action, and an optional message.
48
49
  #
49
50
  # @api public
50
51
  #
51
- # @note Normally the memberships of a workspace decide whether a user is allowed or not to
52
- # execute a specific action. This method allows to add an exception to this logic and thus
52
+ # @note Usually, the memberships of a workspace decide whether a user is allowed or not to
53
+ # perform a specific action. This method lets you add an exception to this logic and thus
53
54
  # should be used carefully.
54
- # @note By default all users are allowed to create a new workspace. Use this method to forbid a
55
+ # @note By default, all users are allowed to create a new workspace. Use this method to forbid a
55
56
  # user to create a new workspace.
56
57
  #
57
58
  # @param [Symbol] verb the verb of the action (see {Scrivito::User::VERBS}).
58
- # @param [Symbol] subject the subject of the action. At the moment only +:workspace+ is supported.
59
+ # @param [Symbol] subject the subject of the action. Currently, only +:workspace+ is supported.
59
60
  # @param [String] message optional message to be displayed in the UI.
60
61
  #
61
62
  # @raise [Scrivito::ScrivitoError] if the given verb is invalid
62
- # @raise [Scrivito::ScrivitoError] if the specified rule conflicts with a rule specified with
63
- # {Scrivito::UserDefinition#can_always}.
63
+ # @raise [Scrivito::ScrivitoError] if the specified rule conflicts with a
64
+ # {Scrivito::UserDefinition#can_always} rule.
64
65
  #
65
66
  # @see Scrivito::User::VERBS
66
67
  # @see Scrivito::UserDefinition#can_always
67
68
  #
68
- # @example User can _never_ publish a workspace, even if she's a workspace owner
69
+ # @example User can _never_ publish a workspace, even if they're a workspace owner:
69
70
  # Scrivito::User.define('alice') do |user|
70
- # user.can_never(:publish, :workspace, 'You can not publish workspaces.')
71
+ # user.can_never(:publish, :workspace, 'You cannot publish workspaces.')
71
72
  # end
72
73
  #
73
- # @example User cannot create a workspace
74
+ # @example User cannot create a workspace:
74
75
  # Scrivito::User.define('bob') do |user|
75
76
  # user.can_never(:create, :workspace)
76
77
  # end
@@ -81,8 +82,8 @@ module Scrivito
81
82
  end
82
83
 
83
84
  #
84
- # Make the user to be always able to create workspaces, to read, to write, to publish, to delete
85
- # and to invite to any workspace.
85
+ # Enable the user to create workspaces, to read from, write to, publish, delete workspaces,
86
+ # and to invite others to collaborate on any workspace.
86
87
  #
87
88
  # @api public
88
89
  #
@@ -91,22 +92,21 @@ module Scrivito
91
92
  end
92
93
 
93
94
  #
94
- # Defines the user description to be displayed, when the user is shown in the in-place GUI.
95
+ # Defines the user description to be displayed in the in-place GUI, e.g. in the workspace menu.
95
96
  #
96
97
  # @api public
97
98
  #
98
- # @param [String] description_string the description. Defaults to the the user id.
99
- # @param [Proc] description_proc proc to calculate the description. Defaults to the the user id.
99
+ # @param [String] description_string the description, defaults to the the user id.
100
+ # @param [Proc] description_proc proc to calculate the description, defaults to the the user id.
100
101
  #
101
- # @note The description is calculated "lazy".
102
- # @note The calculated description will be cached.
102
+ # @note The description is calculated "lazyly". The calculated description is cached.
103
103
  #
104
104
  # @see Scrivito::User.define
105
105
  #
106
- # @example Display the user +alice+ as +"alice"+ in the in-place GUI
106
+ # @example Display the user +alice+ as "alice" in the in-place GUI:
107
107
  # alice = Scrivito::User.define('alice')
108
108
  #
109
- # @example Display the user +bob+ as +"Bob Doe"+ in the in-place GUI
109
+ # @example Display the user +bob+ as "Bob Doe" in the in-place GUI:
110
110
  # bob = Scrivito::User.define('bob') do |user|
111
111
  # user.description('Bob Doe')
112
112
  # end
@@ -126,20 +126,20 @@ module Scrivito
126
126
  end
127
127
 
128
128
  #
129
- # Defines the proc for fetching users for the user autocompletion of the in-place GUI.
130
- # The user autocompletion is for example used in the details dialog of a workspace.
131
- # If the proc is not set, then {Scrivito::User.find} will be used to fetch the suggested users with input
132
- # as the user id.
129
+ # Defines the proc for fetching users for autocompletion purposes in the in-place GUI.
130
+ # User autocompletion is used in the settings dialog of a workspace.
131
+ # If the proc is not set, {Scrivito::User.find} is used to fetch the suggested users,
132
+ # assuming the input is part of the user id.
133
133
  #
134
134
  # @api public
135
135
  #
136
- # @note Only the first 20 of the returnes users will be displayed in the in-place GUI.
136
+ # @note Only the first 20 users returned are displayed in the in-place GUI.
137
137
  # @note +suggest_users_proc+ may also be invoked with an empty string.
138
138
  #
139
139
  # @param [Proc] suggest_users_proc proc for fetching users to be suggested in the in-place GUI
140
- # @yieldparam [String] input an arbitrary string from the input field of a user autocompletion,
140
+ # @yieldparam [String] input an arbitrary string originating from the user autocompletion input field,
141
141
  # e.g. the first letters of a user name
142
- # @yieldreturn [Array<Scrivito::User>] users that were found for the given input string
142
+ # @yieldreturn [Array<Scrivito::User>] users that were found on account of the given input string
143
143
  #
144
144
  # @example
145
145
  # class MyUserModel
@@ -157,20 +157,21 @@ module Scrivito
157
157
  end
158
158
 
159
159
  #
160
- # Lets you restrict the rule of a user to publish a certain object. Each
161
- # registered callback can access a certain attribute of an object. Multiple
162
- # callbacks are possible
160
+ # Lets you restrict a user's capability to publish a specific CMS object. Each
161
+ # registered callback may refer to one attribute of an object. Multiple
162
+ # callbacks are possible.
163
163
  #
164
164
  # @api public
165
165
  #
166
- # @note the callback is only called with {BasicObj Objs} that have the attribute
167
- # specified by the :using option and if it is not a {BasicWidget Widget}-attribute
166
+ # @note The callback is only executed for {BasicObj Objs} equipped with the attribute
167
+ # specified using the +:using+ option. It is not executed for a {BasicWidget Widget}
168
+ # with this attribute.
168
169
  #
169
170
  # @param [Hash] options
170
- # @option options [Symbol] :using the attribute you need in the callback
171
+ # @option options [Symbol] :using the attribute you with to refer to in the callback
171
172
  # @yield [attribute] the value of the specified attribute
172
- # @yieldreturn [String, false] either return a message for the user or false if
173
- # no restriction is needed
173
+ # @yieldreturn [String, false] either return a message for the user or +false+ if
174
+ # no restriction applies
174
175
  #
175
176
  # @example
176
177
  # class MyUserModel
@@ -180,7 +181,7 @@ module Scrivito
180
181
  # if path.start_with?("/en")
181
182
  # false
182
183
  # else
183
- # "You are only allowed to edit the English site"
184
+ # "You are only allowed to edit the English site."
184
185
  # end
185
186
  # end
186
187
  #
@@ -188,7 +189,7 @@ module Scrivito
188
189
  # if obj_class_name == 'BlogPost'
189
190
  # false
190
191
  # else
191
- # 'You are only allowed to edit Blog Posts'
192
+ # 'You are only allowed to edit Blog Posts.'
192
193
  # end
193
194
  # end
194
195
  # end
@@ -5,6 +5,17 @@ class WidgetTag < Struct.new(:view, :widget, :placement_modification, :template_
5
5
 
6
6
  include TagRenderer
7
7
 
8
+ def render
9
+ super
10
+ rescue => error
11
+ if !['development', 'test'].include?(Rails.env) &&
12
+ view.controller.respond_to?(:on_scrivito_widget_error)
13
+ view.controller.on_scrivito_widget_error(widget, error)
14
+ else
15
+ raise error
16
+ end
17
+ end
18
+
8
19
  def tag_name
9
20
  inner_tag || DEFAULT_TAG
10
21
  end
@@ -2,8 +2,12 @@ require 'active_model/naming'
2
2
 
3
3
  module Scrivito
4
4
 
5
- # This class represents a CMS workspace
6
5
  # @api public
6
+ # This class represents a CMS workspace, called "working copy" in the UI. A working copy lets
7
+ # editors create and modify content independently of the published content or other working copies.
8
+ # On creation, a working copy is based on the currently published content.
9
+ # @see http://scrivito.com/about-working-copies About working copies
10
+
7
11
  class Workspace
8
12
  extend ActiveModel::Naming
9
13
 
@@ -11,7 +15,7 @@ class Workspace
11
15
 
12
16
  PublishPreventedDueToContentChange = Class.new(ScrivitoError)
13
17
 
14
- # Set the currently used workspace
18
+ # Set the workspace to use for subsequent workspace operations.
15
19
  # @api public
16
20
  # @param [Scrivito::Workspace] workspace
17
21
  def self.current=(workspace)
@@ -22,7 +26,7 @@ class Workspace
22
26
  @current = workspace_proc
23
27
  end
24
28
 
25
- # Returns the currently used workspace
29
+ # Returns the currently used workspace.
26
30
  # @api public
27
31
  # @return [Scrivito::Workspace]
28
32
  def self.current
@@ -33,7 +37,7 @@ class Workspace
33
37
  end
34
38
  end
35
39
 
36
- # Returns all the workspaces
40
+ # Returns all workspaces.
37
41
  # @api public
38
42
  # @return [Array<Scrivito::Workspace>]
39
43
  def self.all
@@ -48,7 +52,24 @@ class Workspace
48
52
  find("published")
49
53
  end
50
54
 
51
- # Find a workspace by its id
55
+ def self.published_with_fallback
56
+ cached_workspace_data = CmsBackend.instance.find_workspace_data_from_cache('published')
57
+
58
+ if cached_workspace_data
59
+ workspace_data = begin
60
+ CmsBackend.instance.find_workspace_data_by_id('published', 0.5)
61
+ rescue => e
62
+ warn_backend_not_available(e.message)
63
+ cached_workspace_data
64
+ end
65
+
66
+ from_workspace_data('published', workspace_data)
67
+ else
68
+ published
69
+ end
70
+ end
71
+
72
+ # Find a workspace by its id.
52
73
  # @api public
53
74
  # @param [String] id
54
75
  # @return [Scrivito::Workspace]
@@ -57,17 +78,13 @@ class Workspace
57
78
  cache.fetch(id) do
58
79
  workspace_data = CmsBackend.instance.find_workspace_data_by_id(id)
59
80
 
60
- unless workspace_data
61
- raise ResourceNotFound, "Could not find #{self} with id #{id}"
62
- end
63
-
64
- cache[id] = Workspace.new(workspace_data)
81
+ from_workspace_data(id, workspace_data)
65
82
  end
66
83
  end
67
84
 
68
85
  # Find a workspace by its title.
69
86
  # If multiple workspaces share the same title, one of them is returned.
70
- # If no workspace with the given title can be found, nil is returned.
87
+ # If no workspace with the given title can be found, +nil+ is returned.
71
88
  # @api public
72
89
  # @param [String] title
73
90
  # @return [Scrivito::Workspace]
@@ -108,7 +125,9 @@ class Workspace
108
125
  delegate :content_state_id, :base_content_state_id, :content_state,
109
126
  :base_revision_id, :base_content_state, to: :data
110
127
 
111
- # Create a new workspace
128
+ # Create a new workspace.
129
+ # @example Create a workspace, providing its title:
130
+ # Scrivito::Workspace.create(title: "Jane")
112
131
  # @api public
113
132
  # @param [Hash] attributes
114
133
  # @return [Scrivito::Workspace]
@@ -118,8 +137,8 @@ class Workspace
118
137
  self.find(workspace_json["id"])
119
138
  end
120
139
 
121
- # reloads the current workspace to reflect any changes to it that may have happened concurrently
122
- # since it was loaded
140
+ # Reloads the current workspace to reflect the changes that were made to it concurrently
141
+ # since it was loaded.
123
142
  # @api public
124
143
  def self.reload
125
144
  current.reload
@@ -130,19 +149,19 @@ class Workspace
130
149
  end
131
150
 
132
151
  def initialize(workspace_data)
133
- @workspace_data = workspace_data
152
+ update_data(workspace_data)
153
+ @id = data.id
134
154
  end
135
155
 
136
- # Reloads this workspace to reflect any changes to it that may have happened concurrently since
137
- # it was loaded
156
+ # Reloads this workspace to reflect the changes that were made to it concurrently since
157
+ # it was loaded.
138
158
  # @api public
139
159
  def reload
140
- @workspace_data = CmsBackend.instance.find_workspace_data_by_id(self.id)
160
+ update_data(method(:fetch_workspace_data))
161
+ end
141
162
 
142
- # Clear all cached instance variables.
143
- @base_revision = nil
144
- @memberships = nil
145
- @revision = nil
163
+ def eager_reload
164
+ update_data(fetch_workspace_data)
146
165
  end
147
166
 
148
167
  def api_request(verb, path, payload = nil)
@@ -155,7 +174,7 @@ class Workspace
155
174
  CmsRestApi.task_unaware_request(verb, "#{backend_url}#{path}", payload)
156
175
  end
157
176
 
158
- # Updates this workspace's attributes
177
+ # Updates the attributes of this workspace.
159
178
  # @api public
160
179
  # @param [Hash] attributes
161
180
  # @return [Scrivito::Workspace]
@@ -165,14 +184,14 @@ class Workspace
165
184
  reload
166
185
  end
167
186
 
168
- # Destroy this workspace
187
+ # Destroy this workspace.
169
188
  # @api public
170
189
  def destroy
171
190
  reset_workspace_if_current
172
191
  CmsRestApi.delete(backend_url)
173
192
  end
174
193
 
175
- # Publish the changes of this workspace
194
+ # Publish the changes that were made to this workspace.
176
195
  # @api public
177
196
  def publish
178
197
  CmsRestApi.put("#{backend_url}/publish", {})
@@ -182,42 +201,47 @@ class Workspace
182
201
  reset_workspace_if_current
183
202
  end
184
203
 
185
- # Rebases the current workspace on the published content
204
+ # Rebases the current workspace from the published content in order to integrate the changes
205
+ # that were published in the meantime.
186
206
  # @api public
187
207
  def rebase
188
208
  CmsRestApi.put("#{backend_url}/rebase", {})
189
209
  reload
190
210
  end
191
211
 
192
- # Returns the id of the workspace
212
+ # Returns the id of the workspace.
193
213
  # @api public
194
214
  # @return [String]
195
215
  def id
196
- @workspace_data.id
216
+ @id
197
217
  end
198
218
 
199
219
  def revision_id
200
- @workspace_data.revision_id
220
+ data.revision_id
201
221
  end
202
222
 
203
- # Returns the title of the workspace or an empty +String+
223
+ # Returns the title of the workspace if present. Otherwise, and for the published content,
224
+ # an empty +String+ is returned.
204
225
  # @api public
205
226
  # @return [String]
206
227
  def title
207
228
  return '' if published?
208
- @workspace_data.title || ''
229
+ data.title || ''
209
230
  end
210
231
 
211
232
  # @api public
212
- # Returns the members of this workspace and their roles
213
- #
233
+ # Returns the memberships (users and their roles) of this workspace.
214
234
  # @return [MembershipCollection]
215
235
  def memberships
216
236
  @memberships ||= MembershipCollection.new(self)
217
237
  end
218
238
 
219
239
  def data
220
- @workspace_data
240
+ if @workspace_data.respond_to?(:call)
241
+ @workspace_data = @workspace_data.call
242
+ else
243
+ @workspace_data
244
+ end
221
245
  end
222
246
 
223
247
  def published?
@@ -265,7 +289,7 @@ class Workspace
265
289
  raise ScrivitoError, 'published workspace is not modifiable' if published?
266
290
  end
267
291
 
268
- # {ObjCollection} for this working copy
292
+ # Returns an {ObjCollection} of this working copy for accessing its CMS objects.
269
293
  # @api public
270
294
  # @return {ObjCollection}
271
295
  def objs
@@ -294,6 +318,19 @@ class Workspace
294
318
 
295
319
  private
296
320
 
321
+ def update_data(new_data)
322
+ @workspace_data = new_data
323
+
324
+ # Clear all cached instance variables.
325
+ @base_revision = nil
326
+ @memberships = nil
327
+ @revision = nil
328
+ end
329
+
330
+ def fetch_workspace_data
331
+ CmsBackend.instance.find_workspace_data_by_id(id)
332
+ end
333
+
297
334
  def backend_url
298
335
  "/workspaces/#{id}"
299
336
  end
@@ -305,6 +342,27 @@ class Workspace
305
342
  Workspace.current = Workspace.published
306
343
  end
307
344
  end
345
+
346
+ class << self
347
+ private
348
+
349
+ def from_workspace_data(id, data)
350
+ unless data
351
+ raise ResourceNotFound, "Could not find #{self} with id #{id}"
352
+ end
353
+
354
+ cache[id] = Workspace.new(data)
355
+ end
356
+
357
+ def warn_backend_not_available(error_message)
358
+ message = <<-EOS
359
+ Couldn't connect to backend to fetch published workspace.
360
+ #{error_message}
361
+ Serving from cache.
362
+ EOS
363
+ Rails.logger.warn(message)
364
+ end
365
+ end
308
366
  end
309
367
 
310
368
  end
@@ -7,8 +7,15 @@ class WorkspaceSelectionMiddleware
7
7
 
8
8
  def call(env)
9
9
  Workspace.current = proc do
10
- env[EditingContextMiddleware::ENVKEY].visible_workspace
10
+ editing_context = env[EditingContextMiddleware::ENVKEY]
11
+
12
+ if editing_context.authenticated_editor?
13
+ editing_context.visible_workspace
14
+ else
15
+ Workspace.published_with_fallback
16
+ end
11
17
  end
18
+
12
19
  @app.call(env)
13
20
  end
14
21
 
data/lib/scrivito_sdk.rb CHANGED
@@ -4,7 +4,7 @@ require "scrivito/errors"
4
4
  module Scrivito
5
5
  #
6
6
  # Configures the Scrivito SDK.
7
- # The configuration keys +tenant+ and +api_key+ _must_ be provided.
7
+ # The +tenant+ and +api_key+ configuration keys _must_ be provided.
8
8
  #
9
9
  # @example
10
10
  # Scrivito.configure do |config|
@@ -19,23 +19,23 @@ module Scrivito
19
19
  end
20
20
 
21
21
  #
22
- # Configures which models Scrivito assumes as pages and widgets.
22
+ # Configures which models Scrivito regards as pages and widgets.
23
23
  #
24
24
  # @api public
25
25
  #
26
26
  # In order to display a page class selection dialog and a widget class selection dialog, Scrivito
27
- # needs to know which page models and widget models are available. That models can be defined in
27
+ # needs to know which page models and widget models are available. These models can be defined in
28
28
  # the Rails application itself or in 3rd-party gems.
29
29
  #
30
- # Scrivito will automatically assume all the classes descending from {Scrivito::BasicObj}, whose
31
- # class names are ending with +Page+ are pages (e.g. +MyPage+, +HomePage+, +BlogPostPage+ etc.).
32
- # It will also automatically assume all the classes descending from {Scrivito::BasicWidget}, whose
33
- # class names are ending with +Widget+ are widgets (e.g. +TextWidget+, +ImageWdidget+ etc.).
30
+ # Scrivito assumes that all the classes descending from {Scrivito::BasicObj}, whose
31
+ # class names end with +Page+ are pages (e.g. +MyPage+, +HomePage+, +BlogPostPage+ etc.).
32
+ # It also assumes that all the classes descending from {Scrivito::BasicWidget}, whose
33
+ # class names end with +Widget+ are widgets (e.g. +TextWidget+, +ImageWdidget+ etc.).
34
34
  #
35
- # Scrivito will recursively scan for such models in all directories from
35
+ # Scrivito recursively scans for such models in all directories from
36
36
  # {Scrivito::ModelLibrary#paths Scrivito.models.paths}, which is an array of strings.
37
- # It by default includes the directory +app/models+ of the Rails application. For example it will
38
- # find following page and widget models:
37
+ # By default, Scrivito includes the +app/models+ directory of the Rails application when searching
38
+ # for models. It will, for example, find the following page and widget models:
39
39
  #
40
40
  # +app/models/my_page.rb+
41
41
  #
@@ -49,10 +49,10 @@ module Scrivito
49
49
  #
50
50
  # +app/models/my_namespace/my_other_namespace/my_other_special_widget.rb+
51
51
  #
52
- # Also {Scrivito::ModelLibrary#paths Scrivito.models.paths} will include all directories ending
53
- # with +app/models+ of any available Rails engine, as long as that directory is included in the
54
- # autoload paths of Rails (which is the default). For example it will find following page and
55
- # widget models in an engine:
52
+ # Also, {Scrivito::ModelLibrary#paths Scrivito.models.paths} includes all +app/models+
53
+ # directories of any available Rails engine, provided that these directories are included in the
54
+ # autoload paths of Rails (which is the default). For example, it will find the following page
55
+ # and widget models in an engine:
56
56
  #
57
57
  # +/../some_engine/app/models/my_page.rb+
58
58
  #
@@ -67,23 +67,23 @@ module Scrivito
67
67
  # +/../some_engine/app/models/my_namespace/my_other_namespace/my_other_special_widget.rb+
68
68
  #
69
69
  # You can add custom directories to scan for models and register single page and widget models
70
- # with {Scrivito::ModelLibrary#define Scrivito.models.define} (see examples below).
70
+ # using {Scrivito::ModelLibrary#define Scrivito.models.define} (see examples below).
71
71
  #
72
72
  # The loaded pages can be inspected with {Scrivito::ModelLibrary#pages Scrivito.models.pages},
73
- # which will return a {Scrivito::ClassCollection} containing all available pages.
73
+ # which will return a {Scrivito::ClassCollection} containing the available pages.
74
74
  # The loaded widgets can be inspected with {Scrivito::ModelLibrary#widgets Scrivito.models.widgets},
75
- # which will return a {Scrivito::ClassCollection} containing all available widgets.
75
+ # which will return a {Scrivito::ClassCollection} containing the available widgets.
76
76
  #
77
- # The scan results are cached. If +Rails.application.config.cache_classes+ is +false+, then the
78
- # cache will be cleared on every request. Otherwise the cache will be kept between the requests.
79
- # You can clear the cache with {Scrivito::ModelLibrary#clear_cache Scrivito.models.clear_cache}.
77
+ # The scan results are cached. If +Rails.application.config.cache_classes+ is +false+, the
78
+ # cache is cleared on every request. Otherwise, the cache is kept between the requests.
79
+ # You can clear the cache using {Scrivito::ModelLibrary#clear_cache Scrivito.models.clear_cache}.
80
80
  #
81
- # @example Register a custom path
81
+ # @example Register a custom path:
82
82
  # Scrivito.models.define do
83
83
  # paths << Rails.root + 'lib/special_models'
84
84
  # end
85
85
  #
86
- # @example Register pages and widgets with inconvenient names
86
+ # @example Register pages and widgets with unusual names:
87
87
  # Scrivito.models.define do
88
88
  # page 'MyCrazyPageModel'
89
89
  # page 'MyOtherCrazyPageModel1', 'MyOtherCrazyPageModel2'
@@ -92,7 +92,7 @@ module Scrivito
92
92
  # widget 'MyOtherCrazyWidgetModel1', 'MyOtherCrazyWidgetModel2'
93
93
  # end
94
94
  #
95
- # @example Iterate over available pages
95
+ # @example Iterate over the available pages:
96
96
  # Scrivito.models.pages.each do |page_class|
97
97
  # puts page_class.name
98
98
  # end
@@ -100,7 +100,7 @@ module Scrivito
100
100
  # #=> "MyOtherPage"
101
101
  # # ...
102
102
  #
103
- # @example Iterate over available widgets
103
+ # @example Iterate over the available widgets:
104
104
  # Scrivito.models.widgets.each do |widget_class|
105
105
  # puts widget_class.name
106
106
  # end