scrivito_sdk 1.0.0 → 1.1.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 (77) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -0
  3. data/README.md +1 -1
  4. data/app/controllers/scrivito/legacy_redirect_controller.rb +11 -0
  5. data/app/controllers/scrivito/objs_controller.rb +15 -5
  6. data/app/controllers/scrivito/webservice_controller.rb +4 -3
  7. data/app/controllers/scrivito/workspaces_controller.rb +24 -29
  8. data/app/helpers/scrivito_helper.rb +82 -37
  9. data/app/views/scrivito/objs/binary_no_cache.json.jbuilder +1 -0
  10. data/app/views/scrivito/objs/search.json.jbuilder +5 -5
  11. data/app/views/scrivito/webservice/error.json.jbuilder +2 -2
  12. data/config/ca-bundle.crt +1 -1
  13. data/config/precedence_routes.rb +51 -48
  14. data/config/routes.rb +1 -14
  15. data/lib/assets/javascripts/scrivito_ui.js +2447 -266
  16. data/lib/assets/stylesheets/scrivito.css +1 -1
  17. data/lib/assets/stylesheets/scrivito_ui.css +1 -1
  18. data/lib/generators/scrivito/install/install_generator.rb +12 -0
  19. data/lib/generators/scrivito/install/templates/config/initializers/scrivito.rb +3 -0
  20. data/lib/scrivito/attribute_definition.rb +13 -1
  21. data/lib/scrivito/attribute_deserializer.rb +4 -4
  22. data/lib/scrivito/attribute_value_renderer.rb +79 -0
  23. data/lib/scrivito/backend/obj_data_cache.rb +15 -15
  24. data/lib/scrivito/backend/obj_data_from_rest.rb +1 -21
  25. data/lib/scrivito/backend/obj_query.rb +2 -2
  26. data/lib/scrivito/basic_obj.rb +17 -6
  27. data/lib/scrivito/binary.rb +13 -5
  28. data/lib/scrivito/cache/chainable.rb +10 -5
  29. data/lib/scrivito/cache/file_store.rb +4 -0
  30. data/lib/scrivito/cache/ram_store.rb +4 -0
  31. data/lib/scrivito/child_list_tag.rb +16 -14
  32. data/lib/scrivito/client_error.rb +10 -0
  33. data/lib/scrivito/cms_backend.rb +66 -291
  34. data/lib/scrivito/cms_data_cache.rb +7 -9
  35. data/lib/scrivito/cms_dispatch_controller.rb +1 -10
  36. data/lib/scrivito/cms_field_tag.rb +2 -1
  37. data/lib/scrivito/cms_rest_api.rb +2 -0
  38. data/lib/scrivito/cms_routing.rb +26 -22
  39. data/lib/scrivito/configuration.rb +38 -0
  40. data/lib/scrivito/connection_manager.rb +69 -0
  41. data/lib/scrivito/controller_actions.rb +2 -2
  42. data/lib/scrivito/controller_helper.rb +2 -2
  43. data/lib/scrivito/date_attribute.rb +4 -1
  44. data/lib/scrivito/deprecation.rb +5 -4
  45. data/lib/scrivito/editing_context.rb +2 -2
  46. data/lib/scrivito/errors.rb +17 -0
  47. data/lib/scrivito/image_tag.rb +2 -2
  48. data/lib/scrivito/link_parser.rb +10 -5
  49. data/lib/scrivito/meta_data_collection.rb +11 -0
  50. data/lib/scrivito/obj_collection.rb +1 -1
  51. data/lib/scrivito/obj_facet_value.rb +19 -7
  52. data/lib/scrivito/obj_params_parser.rb +43 -14
  53. data/lib/scrivito/obj_search_builder.rb +1 -2
  54. data/lib/scrivito/obj_search_enumerator/batch.rb +22 -0
  55. data/lib/scrivito/obj_search_enumerator/batch_iterator.rb +36 -0
  56. data/lib/scrivito/obj_search_enumerator/query_executor.rb +35 -0
  57. data/lib/scrivito/obj_search_enumerator.rb +218 -93
  58. data/lib/scrivito/obj_update_params_parser.rb +1 -0
  59. data/lib/scrivito/preset_routes.rb +25 -0
  60. data/lib/scrivito/revision.rb +13 -11
  61. data/lib/scrivito/route.rb +62 -0
  62. data/lib/scrivito/routing_extensions.rb +92 -0
  63. data/lib/scrivito/sdk_engine.rb +4 -0
  64. data/lib/scrivito/task.rb +77 -0
  65. data/lib/scrivito/type_computer.rb +3 -3
  66. data/lib/scrivito/ui_config.rb +4 -0
  67. data/lib/scrivito/user.rb +24 -18
  68. data/lib/scrivito/workspace/publish_checker.rb +2 -3
  69. data/lib/scrivito/workspace.rb +38 -6
  70. data/lib/scrivito/workspace_data.rb +0 -14
  71. metadata +14 -10
  72. data/lib/scrivito/content_service.rb +0 -121
  73. data/lib/scrivito/content_state.rb +0 -109
  74. data/lib/scrivito/content_state_caching.rb +0 -47
  75. data/lib/scrivito/content_state_visitor.rb +0 -19
  76. data/lib/scrivito/obj_data_from_service.rb +0 -63
  77. data/lib/scrivito/workspace_data_from_service.rb +0 -43
@@ -1,51 +1,4 @@
1
- require 'addressable/uri'
2
-
3
1
  module Scrivito
4
-
5
- class ContentServiceObjQueries
6
- def initialize(queries)
7
- @queries = queries
8
- @open_queries = queries.dup
9
- @results = {}
10
- end
11
-
12
- def open_queries
13
- @open_queries[0..99]
14
- end
15
-
16
- def handle_response(response)
17
- objs = {}
18
- response["objs"].each do |obj|
19
- objs[obj["_id"].first] = obj
20
- end
21
-
22
- queries_to_delete = []
23
- response["results"].each_with_index do |response, i|
24
- query = @open_queries[i]
25
- if response["continuation_handle"]
26
- query[:continuation_handle] = response["continuation_handle"]
27
- else
28
- queries_to_delete << i
29
- end
30
- result = (@results[query.__id__] ||= [])
31
- response["refs"].each do |obj_ref|
32
- id = obj_ref["id"]
33
- # TODO fetch missing ObjData from Service
34
- result << (objs[id] or raise "Data for Obj with id #{id} missing!")
35
- end
36
- end
37
- queries_to_delete.reverse_each {|i| @open_queries.delete_at(i) }
38
- end
39
-
40
- def results
41
- @queries.map {|query| @results[query.__id__] || [] }
42
- end
43
-
44
- def finished?
45
- open_queries.empty?
46
- end
47
- end
48
-
49
2
  class CmsBackend
50
3
  VALID_INDEX_NAMES = %w[id path ppath permalink].freeze
51
4
 
@@ -55,12 +8,9 @@ module Scrivito
55
8
  end
56
9
  end
57
10
 
58
- attr_accessor :die_content_service
59
-
60
11
  def initialize
61
12
  @query_counter = 0
62
13
  @caching = true
63
- @die_content_service = true
64
14
  end
65
15
 
66
16
  def begin_caching
@@ -68,12 +18,12 @@ module Scrivito
68
18
  end
69
19
 
70
20
  def end_caching
71
- CmsDataCache.cache.clear
21
+ CmsDataCache.clear_request_cache
72
22
  @caching = false
73
23
  end
74
24
 
75
25
  def clear_cache
76
- CmsDataCache.cache.clear
26
+ CmsDataCache.clear_request_cache
77
27
  end
78
28
 
79
29
  def caching?
@@ -90,125 +40,76 @@ module Scrivito
90
40
  end
91
41
 
92
42
  def find_workspace_data_from_cache(id)
93
- if die_content_service
94
- cached_workspace_state = CmsDataCache.read_workspace_state(id)
95
- cached_data_tag = cached_workspace_state.try(:second)
96
- cached_content_state_id = cached_workspace_state.try(:first)
97
-
98
- if cached_data_tag && cached_content_state_id
99
- if raw_workspace_data = fetch_cached_data_by_tag(cached_data_tag)
100
- build_workspace_data(raw_workspace_data, cached_content_state_id)
101
- end
43
+ cached_workspace_state = CmsDataCache.read_workspace_state(id)
44
+ cached_data_tag = cached_workspace_state.try(:second)
45
+ cached_content_state_id = cached_workspace_state.try(:first)
46
+
47
+ if cached_data_tag && cached_content_state_id
48
+ if raw_workspace_data = fetch_cached_data_by_tag(cached_data_tag)
49
+ build_workspace_data(raw_workspace_data, cached_content_state_id)
102
50
  end
103
- else
104
- WorkspaceDataFromService.find_from_cache(id)
105
51
  end
106
52
  end
107
53
 
108
54
  def find_workspace_data_by_id(id, timeout=nil)
109
55
  options = timeout ? {timeout: timeout} : {}
110
56
 
111
- if die_content_service
112
- begin
113
- cached_workspace_state = CmsDataCache.read_workspace_state(id)
57
+ cached_workspace_state = CmsDataCache.read_workspace_state(id)
114
58
 
115
- cached_csid = cached_workspace_state.try(:first)
116
- cached_workspace_data_tag = cached_workspace_state.try(:second)
59
+ cached_csid = cached_workspace_state.try(:first)
60
+ cached_workspace_data_tag = cached_workspace_state.try(:second)
117
61
 
118
- changes = CmsRestApi.get("/workspaces/#{id}/changes", {from: cached_csid}, options)
62
+ changes = CmsRestApi.get("/workspaces/#{id}/changes", {from: cached_csid}, options)
119
63
 
120
- update_obj_cache(id, cached_csid, changes)
64
+ update_obj_cache(id, cached_csid, changes)
121
65
 
122
- raw_workspace_data, workspace_data_tag = update_workspace_cache(
123
- id, cached_workspace_data_tag, changes["workspace"], options)
124
-
125
- current_csid = changes["current"]
126
- current_workspace_state = [current_csid, workspace_data_tag]
127
-
128
- if current_workspace_state != cached_workspace_state
129
- CmsDataCache.write_workspace_state(id, current_workspace_state)
130
- end
66
+ raw_workspace_data, workspace_data_tag = update_workspace_cache(
67
+ id, cached_workspace_data_tag, changes["workspace"], options)
131
68
 
132
- return build_workspace_data(raw_workspace_data, current_csid)
69
+ current_csid = changes["current"]
70
+ current_workspace_state = [current_csid, workspace_data_tag]
133
71
 
134
- rescue Scrivito::ClientError => client_error
135
- if client_error.http_code == 404
136
- return nil
137
- else
138
- raise
139
- end
140
- end
72
+ if current_workspace_state != cached_workspace_state
73
+ CmsDataCache.write_workspace_state(id, current_workspace_state)
141
74
  end
142
75
 
143
- workspace_data_from_cache = find_workspace_data_from_cache(id)
144
- from_content_state_id = workspace_data_from_cache.try(:content_state_id)
145
-
146
- request_params = {:workspace_id => id}
147
- request_params[:content_state_id] = from_content_state_id if from_content_state_id
148
-
149
- raw_data = ContentService.query('workspaces/query', request_params, options)
150
-
151
- if raw_workspace_data = raw_data['workspace']
152
- workspace_data = WorkspaceDataFromService.new(raw_workspace_data)
153
- if from_content_state_id != workspace_data.content_state_id
154
- workspace_data.store_in_cache_and_create_content_state
155
- end
156
- workspace_data
76
+ build_workspace_data(raw_workspace_data, current_csid)
77
+ rescue Scrivito::ClientError => client_error
78
+ if client_error.http_code == 404
79
+ nil
80
+ else
81
+ raise
157
82
  end
158
83
  end
159
84
 
160
85
  def find_obj_data_by(revision, index, keys)
161
86
  index = index.to_s
162
87
 
163
- if die_content_service
164
- obj_datas =
165
- if index == "id"
166
- obj_datas = Backend::ObjLoad.load(revision, keys)
167
- obj_datas.map { |obj_data| obj_data ? [obj_data] : [] }
168
- else
169
- index_implementation = Backend::Index.by_name(index)
170
- Backend::ObjQuery.query(revision, index_implementation, keys)
171
- end
172
-
173
- return obj_datas
174
- end
175
-
176
- assert_valid_index_name(index)
177
- raw_data = find_raw_data_from_cache_or_database_by(revision, index, keys)
178
-
179
- raw_data.map do |raw_result|
180
- raw_result.each_with_object([]) do |raw_data, result|
181
- result << ObjDataFromService.new(raw_data)
182
- end
88
+ if index == "id"
89
+ obj_datas = Backend::ObjLoad.load(revision, keys)
90
+ obj_datas.map { |obj_data| obj_data ? [obj_data] : [] }
91
+ else
92
+ index_implementation = Backend::Index.by_name(index)
93
+ Backend::ObjQuery.query(revision, index_implementation, keys)
183
94
  end
184
95
  end
185
96
 
186
- def find_blob_data(id, access, verb, transformation_definition)
187
- if blob_data = find_blob_data_from_cache(id, access, verb, transformation_definition)
97
+ def find_blob_data(id, access, verb, options = {})
98
+ if blob_data = find_blob_data_from_cache(id, access, verb, options)
188
99
  blob_data
189
100
  else
190
101
  id = normalize_blob_id(id)
191
- blob_datas = request_blob_datas_from_backend(id, transformation_definition)
192
- store_blob_datas_in_cache(id, transformation_definition, blob_datas)
102
+ blob_datas = request_blob_datas_from_backend(id, options)
103
+ store_blob_datas_in_cache(id, options, blob_datas)
193
104
  blob_datas[access][verb]
194
105
  end
195
106
  end
196
107
 
197
- def find_blob_data_from_cache(id, access, verb, transformation_definition)
198
- cache_key = blob_data_cache_key(normalize_blob_id(id), access, verb, transformation_definition)
108
+ def find_blob_data_from_cache(id, access, verb, options)
109
+ cache_key = blob_data_cache_key(normalize_blob_id(id), access, verb, options)
199
110
  CmsDataCache.cache.read(cache_key)
200
111
  end
201
112
 
202
- def find_blob_metadata(id, url)
203
- if blob_metadata = fetch_blob_metadata_from_cache(id)
204
- blob_metadata
205
- else
206
- blob_metadata = request_blob_metadata_from_s3(url)
207
- store_blob_metadata_in_cache(id, blob_metadata)
208
- blob_metadata
209
- end
210
- end
211
-
212
113
  def find_binary_meta_data(blob_id)
213
114
  blob_id = normalize_blob_id(blob_id)
214
115
  cache_key = "binary_meta_data/#{blob_id}"
@@ -224,30 +125,16 @@ module Scrivito
224
125
  def search_objs(workspace, params)
225
126
  cache_index = 'search'
226
127
  cache_key = params.to_param
128
+ cache = Backend::ObjDataCache.view_for_revision(workspace.revision)
227
129
 
228
- if die_content_service
229
- cache = Backend::ObjDataCache.view_for_revision(workspace.revision)
230
-
231
- if hit = cache.read_index(cache_index, cache_key)
232
- return hit
233
- end
234
-
235
- result = request_search_result_from_backend(workspace, params)
236
-
237
- cache.write_index_not_updatable(cache_index, cache_key, result)
238
-
239
- return result
130
+ if hit = cache.read_index(cache_index, cache_key)
131
+ return hit
240
132
  end
241
133
 
242
- content_state = workspace.revision.content_state
243
-
244
- if result = fetch_search_result_from_cache(content_state, cache_index, cache_key)
245
- result
246
- else
247
- request_search_result_from_backend(workspace, params).tap do |result|
248
- store_search_result_in_cache(content_state, cache_index, cache_key, result)
249
- end
250
- end
134
+ result = request_search_result_from_backend(workspace, params)
135
+ persistent = !result.delete('tentative')
136
+ cache.write_index_not_updatable(cache_index, cache_key, result, persistent: persistent)
137
+ result
251
138
  end
252
139
 
253
140
  def create_obj(workspace_id, attributes)
@@ -303,164 +190,52 @@ module Scrivito
303
190
  end
304
191
  end
305
192
 
306
- def fetch_search_result_from_cache(content_state, cache_index, cache_key)
307
- content_state.find_obj_data(cache_index, cache_key) if caching?
308
- end
309
-
310
193
  def request_search_result_from_backend(workspace, params)
194
+ params = params.merge(consistent_with: workspace.content_state_id)
311
195
  CmsRestApi.get("workspaces/#{workspace.id}/objs/search", params)
312
196
  end
313
197
 
314
- def store_search_result_in_cache(content_state, cache_index, cache_key, result)
315
- content_state.save_obj_data(cache_index, cache_key, result) if caching?
316
- end
317
-
318
- def request_blob_datas_from_backend(id, transformation_definition)
198
+ def request_blob_datas_from_backend(id, options)
319
199
  @query_counter += 1
320
- if transformation_definition
200
+ case
201
+ when transformation_definition = options[:transformation_definition]
321
202
  CmsRestApi.get("blobs/#{id}/transform", transformation: transformation_definition)
203
+ when options[:no_cache]
204
+ CmsRestApi.get("blobs/#{id}/no_cache")
322
205
  else
323
206
  CmsRestApi.get("blobs/#{id}")
324
207
  end
325
208
  end
326
209
 
327
- def store_blob_datas_in_cache(id, transformation_definition, blob_datas)
210
+ def store_blob_datas_in_cache(id, options, blob_datas)
328
211
  %w[public_access private_access].each do |access|
329
212
  %w[get head].each do |verb|
330
- blob_data = blob_datas[access][verb]
331
- cache_key = blob_data_cache_key(id, access, verb, transformation_definition)
332
- CmsDataCache.cache.write(cache_key, blob_data, blob_data['maxage'])
213
+ if access_blob_data = blob_datas[access]
214
+ if blob_data = access_blob_data[verb]
215
+ cache_key = blob_data_cache_key(id, access, verb, options)
216
+ CmsDataCache.cache.write(cache_key, blob_data, expires_in: blob_data['maxage'])
217
+ end
218
+ end
333
219
  end
334
220
  end
335
221
  end
336
222
 
337
- def blob_data_cache_key(id, access, verb, transformation_definition)
223
+ def blob_data_cache_key(id, access, verb, options)
338
224
  cache_key = "blob_data/#{id}/#{access}/#{verb}"
339
- cache_key << "/#{transformation_definition.to_query}" if transformation_definition
340
- cache_key
341
- end
342
-
343
- def normalize_blob_id(id)
344
- CmsRestApi.normalize_path_component(id)
345
- end
346
225
 
347
- def fetch_blob_metadata_from_cache(id)
348
- CmsDataCache.cache.read(blob_metadata_cache_key(id))
349
- end
350
-
351
- def request_blob_metadata_from_s3(url)
352
- uri = URI.parse(url)
353
- retried = false
354
- begin
355
- response = ConnectionManager.request(uri, Net::HTTP::Head.new(uri))
356
- @query_counter += 1
357
- rescue NetworkError
358
- raise if retried
359
- retried = true
360
- retry
226
+ if transformation_definition = options[:transformation_definition]
227
+ cache_key << "/#{transformation_definition.to_query}"
361
228
  end
362
229
 
363
- raise ScrivitoError, "S3 responded with #{response.code}" unless response.code == '200'
364
-
365
- {
366
- content_length: response['content-length'],
367
- content_type: response['content-type'],
368
- cache_control: response['cache-control'],
369
- }
370
- end
371
-
372
- def store_blob_metadata_in_cache(id, blob_metadata)
373
- max_age = blob_metadata.delete(:cache_control) =~ /max-age=(.*),/ && $1
374
- max_age = max_age.to_i if max_age
375
- CmsDataCache.cache.write(blob_metadata_cache_key(id), blob_metadata, max_age)
376
- end
377
-
378
- def blob_metadata_cache_key(id)
379
- "blob_metadata/#{id}"
380
- end
381
-
382
- def find_raw_data_from_cache_or_database_by(revision, index, keys)
383
- keys_from_database = []
384
- # load results from cache
385
- results_from_cache = keys.map do |key|
386
- find_raw_data_from_cache_by(revision, index, key).tap do |objs|
387
- keys_from_database << key unless objs
388
- end
230
+ if options[:no_cache]
231
+ cache_key << '/no_cache'
389
232
  end
390
233
 
391
- # load cache misses from database and store them in cache
392
- results_from_database =
393
- find_raw_data_from_database_by(revision, index, keys_from_database)
394
- keys_from_database.each_with_index do |key, key_number|
395
- store_raw_data_list_in_cache(revision, index, key, results_from_database[key_number])
396
- end
397
-
398
- # combine the results
399
- results_from_cache.map do |objs_from_cache|
400
- objs_from_cache || results_from_database.shift
401
- end
402
- end
403
-
404
- def find_raw_data_from_cache_by(revision, index, key)
405
- ContentStateCaching.find_obj_data(revision.content_state, index, key) if caching?
406
- end
407
-
408
- def find_raw_data_from_database_by(revision, index, keys)
409
- return [] if keys.blank?
410
- instrumenter = ActiveSupport::Notifications.instrumenter
411
- instrumenter.instrument(
412
- "cms_load.scrivito", :name => "Obj Load", :index => index, :keys => keys
413
- ) do
414
- @query_counter += 1
415
- queries = ContentServiceObjQueries.new(keys.map {|key| {:type => index, :param => key} })
416
- queries.handle_response(request_content_service(queries, revision)) until queries.finished?
417
- queries.results
418
- end
419
- end
420
-
421
- def request_content_service(queries, revision)
422
- ContentService.query('objs/query', content_service_request_params(queries, revision))
423
- end
424
-
425
- def content_service_request_params(queries, revision)
426
- params = {
427
- queries: queries.open_queries,
428
- revision_id: revision.id,
429
- include_deleted: true
430
- }
431
-
432
- # A base revision doesn't have a directly corresponding workspace. Instead it uses its
433
- # derivative workspace as fallback to access the contents. Thus fallback workspace of a base
434
- # revision may not be used for backend requests.
435
- params[:workspace_id] = revision.workspace.id unless revision.base?
436
-
437
- params
438
- end
439
-
440
- UNIQUE_INDICES = [:id, :path, :permalink].freeze
441
-
442
- def store_raw_data_list_in_cache(revision, index, key, raw_data_list)
443
- raw_data_list.each do |values|
444
- UNIQUE_INDICES.each do |unique_index|
445
- unique_index_values = values["_#{unique_index}"]
446
- if unique_index_values.present?
447
- store_item_in_cache(revision, unique_index, unique_index_values.first, [values])
448
- end
449
- end
450
- end
451
- unless UNIQUE_INDICES.include?(index)
452
- store_item_in_cache(revision, index, key, raw_data_list)
453
- end
454
- end
455
-
456
- def store_item_in_cache(revision, index, key, item)
457
- ContentStateCaching.store_obj_data(revision.content_state, index, key, item)
234
+ cache_key
458
235
  end
459
236
 
460
- def assert_valid_index_name(index)
461
- raise ArgumentError, "invalid index name '#{index}'" unless VALID_INDEX_NAMES.include?(index)
237
+ def normalize_blob_id(id)
238
+ CmsRestApi.normalize_path_component(id)
462
239
  end
463
-
464
240
  end
465
-
466
241
  end
@@ -21,19 +21,17 @@ module CmsDataCache
21
21
  @first_level_cache ||= Cache::FileStore.new(path: @cache_path, next_store: second_level_cache)
22
22
  end
23
23
 
24
+ def clear_request_cache
25
+ cache.clear
26
+ end
27
+
24
28
  def second_level_cache=(cache_store)
25
29
  clear_cache_chain
26
30
  @second_level_cache = cache_store
27
31
  end
28
32
 
29
33
  SCHEMA = {
30
- # CONTENT SERVICE
31
- content_state: 'content/#{content_state_id}',
32
- obj_data: 'content/#{content_state_id}/obj/#{index}/#{key}',
33
- workspace_data: 'workspace/#{workspace_id}',
34
-
35
- # REST API
36
- obj_data_rest: 'obj/#{cache_id}/#{index}/#{key}',
34
+ obj_data: 'obj/#{cache_id}/#{index}/#{key}',
37
35
  content_state_node: 'csn/#{content_state_id}',
38
36
  workspace_state: 'wrkstt/#{workspace_id}',
39
37
  tag_data: 'tagd/#{tag}'
@@ -51,11 +49,11 @@ module CmsDataCache
51
49
  END
52
50
 
53
51
  class_eval(<<-END, __FILE__, __LINE__ + 1)
54
- def write_#{name}(#{params_code}, data)
52
+ def write_#{name}(#{params_code}, data, **options)
55
53
  if data == nil
56
54
  raise InternalError, "tried to write nil into #{schema}"
57
55
  end
58
- cache.write("#{schema}", data)
56
+ cache.write("#{schema}", data, **options)
59
57
  end
60
58
  END
61
59
 
@@ -8,17 +8,8 @@ module Scrivito
8
8
  def process(action)
9
9
  CmsEnv.new(env).load
10
10
 
11
- if !obj_not_found? && action == 'legacy'
12
- if Scrivito::Configuration.legacy_routing
13
- action = 'index'
14
- else
15
- redirect_to scrivito_path(loaded_obj), status: :moved_permanently
16
- return self.response
17
- end
18
- end
19
-
20
11
  if obj_not_found? && editing_context.workspace_changed?
21
- redirect_to :scrivito_root
12
+ redirect_to "/"
22
13
  return self.response
23
14
  end
24
15
 
@@ -33,7 +33,8 @@ class CmsFieldTag < Struct.new(:view, :tag_name, :obj_or_widget, :editing_option
33
33
  end
34
34
  view.safe_join(rendered_widgets)
35
35
  else
36
- block_given? ? view.capture { yield } : view.scrivito_value(default_content)
36
+ attribute_renderer = AttributeValueRenderer.new(view)
37
+ block_given? ? view.capture { yield } : attribute_renderer.render(default_content, field_type)
37
38
  end
38
39
  end
39
40
 
@@ -1,3 +1,5 @@
1
+ require 'addressable/uri'
2
+
1
3
  module Scrivito
2
4
 
3
5
  # Provides a simple wrapper for the CMS Rest API.
@@ -1,13 +1,9 @@
1
1
  module Scrivito
2
2
 
3
- class CmsRouting < Struct.new(:request, :main_app, :scrivito_engine, :image_options)
3
+ class CmsRouting < Struct.new(:request, :context, :scrivito_engine, :image_options)
4
4
  LINK_TO_EMPTY_LINKLIST = "#__empty_linklist"
5
5
  LINK_TO_EMPTY_BLOB = "#__empty_blob"
6
6
 
7
- def self.match_protocol(url, request)
8
- request.ssl? && !url.starts_with?('https') ? url.gsub(/^http/, 'https') : url
9
- end
10
-
11
7
  def path_or_url(target, path_or_url, options = {})
12
8
  if needs_editing_context?(target)
13
9
  path_or_url_needs_editing_context(target, path_or_url, options)
@@ -26,13 +22,14 @@ class CmsRouting < Struct.new(:request, :main_app, :scrivito_engine, :image_opti
26
22
  begin
27
23
  uri = URI.parse($2)
28
24
  options.merge!(extract_query(uri))
29
- options['anchor'] = uri.fragment
25
+ options[:anchor] = uri.fragment
30
26
  rescue
31
27
  end
32
28
  end
33
29
 
34
30
  if editing_context.display_mode == 'editing'
35
- id_path_or_url_for_objs(obj, :path, options)
31
+ options[:id] = obj.id
32
+ scrivito_engine.base_id_path(options)
36
33
  else
37
34
  path_or_url(obj, :path, options)
38
35
  end
@@ -70,41 +67,48 @@ class CmsRouting < Struct.new(:request, :main_app, :scrivito_engine, :image_opti
70
67
  end
71
68
 
72
69
  def path_or_url_for_links(link, path_or_url, options)
73
- url = basic_url_or_path_for_link(link, path_or_url,
74
- Rack::Utils.parse_nested_query(link.query).merge(options))
70
+ parsed_options = Rack::Utils.parse_nested_query(link.query)
71
+ combined_options = parsed_options.symbolize_keys.merge(options)
72
+
73
+ url = basic_url_or_path_for_link(link, path_or_url, combined_options)
75
74
  url = url + "##{link.fragment}" if link.fragment.present?
76
75
  url
77
76
  end
78
77
 
79
78
  def path_or_url_for_objs(obj, path_or_url, options)
80
79
  permalink = obj.permalink
81
- if permalink
82
- main_app
83
- .public_send("scrivito_permalink_#{path_or_url}", options.merge(:permalink => permalink))
84
- elsif homepage?(obj)
85
- main_app.public_send("scrivito_root_#{path_or_url}", options)
80
+ if permalink && route_defined?(:permalink)
81
+ use_route(:permalink, path_or_url, options.merge(:permalink => permalink))
82
+ elsif homepage?(obj) && route_defined?(:homepage)
83
+ use_route(:homepage, path_or_url, options)
86
84
  elsif obj.binary?
87
85
  binary_obj_url(obj) || LINK_TO_EMPTY_BLOB
88
- else
86
+ elsif route_defined?(:slug_id)
89
87
  slug = obj.slug.present? ? obj.slug.sub(/^\//, '') : nil
90
88
  id_path_or_url_for_objs(obj, path_or_url, options.merge(slug: slug))
89
+ else
90
+ raise ScrivitoError, "The required scrivito route 'slug_id' is not defined. "\
91
+ "Please add a 'slug_id' definition to your routes.rb. See the documentation"\
92
+ " of 'scrivito_route' for further details."
91
93
  end
92
94
  end
93
95
 
94
96
  def id_path_or_url_for_objs(obj, path_or_url, options)
95
- method_name = if Scrivito::Configuration.legacy_routing
96
- "cms_legacy_id_#{path_or_url}"
97
- else
98
- "cms_id_#{path_or_url}"
99
- end
100
-
101
97
  options[:id] = obj.id
102
98
 
103
99
  # Options must have the key slug.
104
100
  # Otherwise Rails will use the slug from current request params.
105
101
  options[:slug] ||= nil
106
102
 
107
- main_app.public_send(method_name, options)
103
+ use_route(:slug_id, path_or_url, options)
104
+ end
105
+
106
+ def route_defined?(name)
107
+ Route.defined?(context._routes, name)
108
+ end
109
+
110
+ def use_route(name, path_or_url, options)
111
+ Route.find(context._routes, name).generate(context, path_or_url, options)
108
112
  end
109
113
 
110
114
  def homepage?(obj)