scrivito_sdk 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.yardopts +5 -0
- data/README +6 -0
- data/app/controllers/cms_controller.rb +7 -0
- data/app/controllers/scrivito/blobs_controller.rb +10 -0
- data/app/controllers/scrivito/default_cms_controller.rb +61 -0
- data/app/controllers/scrivito/objs_controller.rb +200 -0
- data/app/controllers/scrivito/tasks_controller.rb +11 -0
- data/app/controllers/scrivito/webservice_controller.rb +36 -0
- data/app/controllers/scrivito/workspaces_controller.rb +41 -0
- data/app/helpers/cms_helper.rb +7 -0
- data/app/helpers/cms_routing_helper.rb +7 -0
- data/app/helpers/scrivito/cms_asset_helper.rb +103 -0
- data/app/helpers/scrivito/cms_tag_helper.rb +231 -0
- data/app/helpers/scrivito/default_cms_helper.rb +21 -0
- data/app/helpers/scrivito/default_cms_routing_helper.rb +130 -0
- data/app/helpers/scrivito/display_helper.rb +71 -0
- data/app/helpers/scrivito/editing_helper.rb +26 -0
- data/app/helpers/scrivito/layout_helper.rb +28 -0
- data/app/models/named_link.rb +2 -0
- data/app/views/cms/_index.html.erb +7 -0
- data/app/views/cms/index.html.erb +1 -0
- data/app/views/scrivito/_editing_javascript.html.erb +7 -0
- data/app/views/scrivito/default_cms/show_widget.html.erb +1 -0
- data/app/views/scrivito/objs/copy_widget.html.erb +1 -0
- data/app/views/scrivito/objs/create_widget.html.erb +1 -0
- data/app/views/scrivito/widget_thumbnail.html.erb +9 -0
- data/config/ca-bundle.crt +3509 -0
- data/config/cms_routes.rb +17 -0
- data/config/locales/de.scrivito.errors.yml +7 -0
- data/config/locales/de.scrivito.lib.yml +6 -0
- data/config/locales/de.scrivito.models.yml +6 -0
- data/config/locales/en.scrivito.errors.yml +7 -0
- data/config/locales/en.scrivito.lib.yml +6 -0
- data/config/locales/en.scrivito.models.yml +6 -0
- data/config/routes.rb +37 -0
- data/lib/assets/images/180x120.gif +0 -0
- data/lib/assets/images/scrivito/image_placeholder.png +0 -0
- data/lib/assets/javascripts/scrivito_editing.js +14642 -0
- data/lib/assets/stylesheets/scrivito.css +180 -0
- data/lib/assets/stylesheets/scrivito_editing.css +2213 -0
- data/lib/generators/cms/migration/USAGE +9 -0
- data/lib/generators/cms/migration/migration_generator.rb +21 -0
- data/lib/generators/cms/migration/templates/migration.erb +10 -0
- data/lib/obj.rb +3 -0
- data/lib/scrivito/access_denied.rb +6 -0
- data/lib/scrivito/attribute_content.rb +194 -0
- data/lib/scrivito/backend_error.rb +4 -0
- data/lib/scrivito/basic_obj.rb +840 -0
- data/lib/scrivito/basic_widget.rb +238 -0
- data/lib/scrivito/blob.rb +48 -0
- data/lib/scrivito/cache.rb +41 -0
- data/lib/scrivito/cache_garbage_collector.rb +83 -0
- data/lib/scrivito/cache_middleware.rb +17 -0
- data/lib/scrivito/client_config.rb +62 -0
- data/lib/scrivito/client_error.rb +12 -0
- data/lib/scrivito/cms_accessible.rb +30 -0
- data/lib/scrivito/cms_backend.rb +238 -0
- data/lib/scrivito/cms_cache_storage.rb +51 -0
- data/lib/scrivito/cms_dispatch_controller.rb +46 -0
- data/lib/scrivito/cms_env.rb +63 -0
- data/lib/scrivito/cms_field_tag.rb +112 -0
- data/lib/scrivito/cms_rest_api.rb +151 -0
- data/lib/scrivito/cms_rest_api/attribute_serializer.rb +98 -0
- data/lib/scrivito/cms_rest_api/blob_uploader.rb +18 -0
- data/lib/scrivito/cms_rest_api/widget_extractor.rb +42 -0
- data/lib/scrivito/cms_test_request.rb +23 -0
- data/lib/scrivito/communication_error.rb +17 -0
- data/lib/scrivito/comparison.rb +67 -0
- data/lib/scrivito/configuration.rb +221 -0
- data/lib/scrivito/connection_manager.rb +100 -0
- data/lib/scrivito/content_conversion.rb +43 -0
- data/lib/scrivito/content_service.rb +118 -0
- data/lib/scrivito/content_state.rb +109 -0
- data/lib/scrivito/content_state_caching.rb +47 -0
- data/lib/scrivito/content_state_visitor.rb +19 -0
- data/lib/scrivito/controller_runtime.rb +35 -0
- data/lib/scrivito/date_attribute.rb +16 -0
- data/lib/scrivito/deprecation.rb +21 -0
- data/lib/scrivito/diff.rb +110 -0
- data/lib/scrivito/editing_context.rb +106 -0
- data/lib/scrivito/editing_context_middleware.rb +60 -0
- data/lib/scrivito/engine.rb +65 -0
- data/lib/scrivito/errors.rb +11 -0
- data/lib/scrivito/html_string.rb +18 -0
- data/lib/scrivito/link.rb +187 -0
- data/lib/scrivito/link_parser.rb +81 -0
- data/lib/scrivito/log_subscriber.rb +29 -0
- data/lib/scrivito/migration.rb +2 -0
- data/lib/scrivito/migrations.rb +12 -0
- data/lib/scrivito/migrations/cms_backend.rb +94 -0
- data/lib/scrivito/migrations/installer.rb +45 -0
- data/lib/scrivito/migrations/migration.rb +93 -0
- data/lib/scrivito/migrations/migration_dsl.rb +143 -0
- data/lib/scrivito/migrations/migration_store.rb +23 -0
- data/lib/scrivito/migrations/migrator.rb +135 -0
- data/lib/scrivito/migrations/workspace_lock.rb +39 -0
- data/lib/scrivito/model_identity.rb +13 -0
- data/lib/scrivito/modification.rb +8 -0
- data/lib/scrivito/named_link.rb +75 -0
- data/lib/scrivito/network_error.rb +11 -0
- data/lib/scrivito/obj_data.rb +140 -0
- data/lib/scrivito/obj_data_from_hash.rb +31 -0
- data/lib/scrivito/obj_data_from_service.rb +84 -0
- data/lib/scrivito/obj_params_parser.rb +61 -0
- data/lib/scrivito/obj_search_builder.rb +62 -0
- data/lib/scrivito/obj_search_enumerator.rb +374 -0
- data/lib/scrivito/rate_limit_exceeded.rb +5 -0
- data/lib/scrivito/revision.rb +9 -0
- data/lib/scrivito/string_tagging.rb +18 -0
- data/lib/scrivito/text_link.rb +52 -0
- data/lib/scrivito/text_link_conversion.rb +52 -0
- data/lib/scrivito/type_computer.rb +34 -0
- data/lib/scrivito/widget_field_params.rb +61 -0
- data/lib/scrivito/widget_garbage_collection.rb +97 -0
- data/lib/scrivito/workspace.rb +222 -0
- data/lib/scrivito/workspace_data_from_service.rb +80 -0
- data/lib/scrivito/workspace_selection_middleware.rb +23 -0
- data/lib/scrivito_sdk.rb +19 -0
- data/lib/tasks/cache.rake +12 -0
- data/lib/tasks/migration.rake +35 -0
- data/lib/widget.rb +3 -0
- metadata +291 -0
@@ -0,0 +1,238 @@
|
|
1
|
+
module Scrivito
|
2
|
+
|
3
|
+
# The CMS widget class
|
4
|
+
# @api public
|
5
|
+
class BasicWidget
|
6
|
+
include AttributeContent
|
7
|
+
|
8
|
+
def self.type_computer
|
9
|
+
@_type_computer ||= TypeComputer.new(Scrivito::BasicWidget, ::Widget)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.reset_type_computer!
|
13
|
+
@_type_computer = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_accessor :container, :container_field_name
|
17
|
+
|
18
|
+
attr_writer :obj, :id
|
19
|
+
|
20
|
+
attr_reader :attributes_to_be_saved
|
21
|
+
|
22
|
+
delegate :widget_from_pool, to: :obj
|
23
|
+
|
24
|
+
# Create a new Widget.
|
25
|
+
# The new Widget must be stored inside a container (i.e. an Obj or another Widget)
|
26
|
+
# before it can be used.
|
27
|
+
#
|
28
|
+
# See {BasicObj.create Obj.create} for a detailed overview of how to set attributes.
|
29
|
+
# @api public
|
30
|
+
# @param [Hash] attributes
|
31
|
+
#
|
32
|
+
# @example Create a widget using a subclass
|
33
|
+
# # you can create widgets by explicitly providing the attribute `_obj_class`
|
34
|
+
# new_widget = Widget.new(_obj_class: "MyWidget")
|
35
|
+
# # but it is better to simply use the constructor of a subclass
|
36
|
+
# new_widget = MyWidget.new
|
37
|
+
#
|
38
|
+
# @example Create a widget and store it inside an Obj
|
39
|
+
# # create the widget
|
40
|
+
# new_widget = Widget.new(_obj_class: "MyWidget")
|
41
|
+
# # store it inside an obj
|
42
|
+
# my_obj(my_widget_field: [new_widget])
|
43
|
+
#
|
44
|
+
def initialize(attributes = {})
|
45
|
+
@attributes_to_be_saved = self.class.with_default_obj_class(attributes)
|
46
|
+
end
|
47
|
+
|
48
|
+
def revision
|
49
|
+
obj.revision
|
50
|
+
end
|
51
|
+
|
52
|
+
# Update the attributes of this Widget
|
53
|
+
#
|
54
|
+
# See {BasicObj.create Obj.create} for a detailed overview of how to set attributes
|
55
|
+
# @api public
|
56
|
+
# @param [Hash] attributes
|
57
|
+
def update(attributes)
|
58
|
+
widget_hash = CmsRestApi::WidgetExtractor.call(attributes, obj)
|
59
|
+
widget_pool = CmsRestApi::AttributeSerializer.generate_widget_pool_changes(widget_hash)
|
60
|
+
.merge(id => CmsRestApi::AttributeSerializer.convert(attributes))
|
61
|
+
|
62
|
+
obj_attributes = {'_widget_pool' => widget_pool}
|
63
|
+
|
64
|
+
widget_gc = WidgetGarbageCollection.new(obj, {self => attributes}.merge(widget_hash))
|
65
|
+
widget_gc.widgets_to_delete.each { |widget| widget_pool[widget.id] = nil }
|
66
|
+
|
67
|
+
CmsRestApi.put("workspaces/#{Workspace.current.id}/objs/#{obj.id}", obj: obj_attributes)
|
68
|
+
|
69
|
+
CmsRestApi::WidgetExtractor.notify_persisted_widgets(self.obj, widget_hash)
|
70
|
+
|
71
|
+
Workspace.reload
|
72
|
+
|
73
|
+
reload
|
74
|
+
end
|
75
|
+
|
76
|
+
# Destroys the {BasicWidget Widget} in the current {Workspace}
|
77
|
+
# @api public
|
78
|
+
def destroy
|
79
|
+
new_widget_list = container[container_field_name] - [self]
|
80
|
+
container.update(container_field_name => new_widget_list)
|
81
|
+
end
|
82
|
+
|
83
|
+
def id
|
84
|
+
if @id
|
85
|
+
@id
|
86
|
+
else
|
87
|
+
raise_not_persisted_errror
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def persisted?
|
92
|
+
@attributes_to_be_saved.nil?
|
93
|
+
end
|
94
|
+
|
95
|
+
def obj_class_name
|
96
|
+
data_from_cms.value_of('_obj_class')
|
97
|
+
end
|
98
|
+
|
99
|
+
def obj_class
|
100
|
+
raise ScrivitoError, "BasicWidget#obj_class is no longer available"+
|
101
|
+
", please use BasicWidget#obj_class_name instead."
|
102
|
+
end
|
103
|
+
|
104
|
+
def ==(other)
|
105
|
+
other.respond_to?(:obj) && obj == other.obj && other.respond_to?(:id) && id == other.id
|
106
|
+
end
|
107
|
+
|
108
|
+
def eql?(other)
|
109
|
+
self == other
|
110
|
+
end
|
111
|
+
|
112
|
+
# Reverts content changes of this widget. Widget attributes of this widget are not effected.
|
113
|
+
# After calling this method it's as if this widget has been never modified in the current working copy.
|
114
|
+
# This method does not work with +new+ or +deleted+ widgets.
|
115
|
+
# This method also does also not work for the +published+ workspace or the +rtc+ working copy.
|
116
|
+
def revert
|
117
|
+
Workspace.current.assert_revertable
|
118
|
+
|
119
|
+
case modification
|
120
|
+
when Modification::UNMODIFIED
|
121
|
+
# do nothing
|
122
|
+
when Modification::EDITED
|
123
|
+
previous_obj_content =
|
124
|
+
CmsRestApi.get("revisions/#{Workspace.current.base_revision_id}/objs/#{obj.id}")
|
125
|
+
previous_widget_content = previous_obj_content["_widget_pool"]["#{id}"]
|
126
|
+
previous_widget_content.delete_if do |attribute_name, _|
|
127
|
+
type_of_attribute(attribute_name) == "widget"
|
128
|
+
end
|
129
|
+
CmsRestApi.put("workspaces/#{Workspace.current.id}/objs/#{obj.id}",
|
130
|
+
{ obj: {_widget_pool: {id => previous_widget_content}} })
|
131
|
+
else
|
132
|
+
raise ScrivitoError, "cannot revert changes, since widget is #{modification}."
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def in_revision(revision)
|
137
|
+
obj_in_revision = obj.in_revision(revision)
|
138
|
+
obj_in_revision && obj_in_revision.widget_from_pool(id)
|
139
|
+
end
|
140
|
+
|
141
|
+
def new?(revision=Workspace.current.base_revision)
|
142
|
+
obj.new?(revision) || cms_data_for_revision(revision).nil?
|
143
|
+
end
|
144
|
+
|
145
|
+
def deleted?(revision=Workspace.current.base_revision)
|
146
|
+
obj.deleted?(revision)
|
147
|
+
end
|
148
|
+
|
149
|
+
def modification(revision=Workspace.current.base_revision)
|
150
|
+
if deleted?(revision)
|
151
|
+
Modification::DELETED
|
152
|
+
elsif new?(revision)
|
153
|
+
Modification::NEW
|
154
|
+
else
|
155
|
+
if data_from_cms == cms_data_for_revision(revision)
|
156
|
+
Modification::UNMODIFIED
|
157
|
+
else
|
158
|
+
Modification::EDITED
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def hash
|
164
|
+
if @obj && @id
|
165
|
+
(id + obj.id).hash
|
166
|
+
else
|
167
|
+
super
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
# returns the entity ({BasicObj} or {BasicWidget}) that references this widget
|
172
|
+
# @api public
|
173
|
+
def container
|
174
|
+
@container || cache_container_and_field_name_for_widget.first
|
175
|
+
end
|
176
|
+
|
177
|
+
# returns the name of the widget field that references this widget
|
178
|
+
# @api public
|
179
|
+
def container_field_name
|
180
|
+
@container_field_name || cache_container_and_field_name_for_widget.second
|
181
|
+
end
|
182
|
+
|
183
|
+
def inspect
|
184
|
+
if @id
|
185
|
+
if @obj
|
186
|
+
"<#{self.class} id=\"#{id}\" obj.id=\"#{obj.id}\">"
|
187
|
+
else
|
188
|
+
"<#{self.class} id=\"#{id}\">"
|
189
|
+
end
|
190
|
+
else
|
191
|
+
"<#{self.class}>"
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
def obj
|
196
|
+
if @obj
|
197
|
+
@obj
|
198
|
+
else
|
199
|
+
raise_not_persisted_errror
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def forget_unsaved_attribtues
|
204
|
+
@attributes_to_be_saved = nil
|
205
|
+
reload
|
206
|
+
end
|
207
|
+
|
208
|
+
def reload
|
209
|
+
obj.reload
|
210
|
+
|
211
|
+
update_proc = -> { obj.widget_data_from_pool(id) }
|
212
|
+
update_data(update_proc)
|
213
|
+
end
|
214
|
+
|
215
|
+
private
|
216
|
+
|
217
|
+
def data_from_cms
|
218
|
+
if persisted?
|
219
|
+
super
|
220
|
+
else
|
221
|
+
raise_not_persisted_errror
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
def raise_not_persisted_errror
|
226
|
+
raise ScrivitoError.new('Can not access a new widget before it has been saved')
|
227
|
+
end
|
228
|
+
|
229
|
+
def cms_data_for_revision(revision)
|
230
|
+
obj.widget_data_for_revision(id, revision)
|
231
|
+
end
|
232
|
+
|
233
|
+
def cache_container_and_field_name_for_widget
|
234
|
+
@cache_container_and_field_name_for_widget ||= obj.container_and_field_name_for_widget(id)
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Scrivito
|
2
|
+
|
3
|
+
# TODO Caching:
|
4
|
+
# unlimited urls: ewig
|
5
|
+
# limited urls: zeitlimit - x (x fuer mindestverwendbarkeitszeit)
|
6
|
+
class Blob
|
7
|
+
|
8
|
+
class << self
|
9
|
+
|
10
|
+
def configure(config)
|
11
|
+
end
|
12
|
+
|
13
|
+
def find(id)
|
14
|
+
new(id)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_reader :id
|
20
|
+
|
21
|
+
def initialize(id)
|
22
|
+
@id = id
|
23
|
+
end
|
24
|
+
|
25
|
+
def url
|
26
|
+
raw_data["url"]
|
27
|
+
end
|
28
|
+
|
29
|
+
def content_type
|
30
|
+
meta_data[:content_type]
|
31
|
+
end
|
32
|
+
|
33
|
+
def length
|
34
|
+
meta_data[:content_length].to_i
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def raw_data
|
40
|
+
@raw_data ||= CmsBackend.instance.find_blob_data_by_id(id)
|
41
|
+
end
|
42
|
+
|
43
|
+
def meta_data
|
44
|
+
@meta_data ||= RestClient.head(raw_data["meta_url"]).headers
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Scrivito
|
2
|
+
|
3
|
+
class Cache
|
4
|
+
attr_reader :cache_prefix, :fallback_backend
|
5
|
+
|
6
|
+
def initialize(options = {})
|
7
|
+
@fallback_backend, @cache_prefix = options[:fallback_backend], options[:cache_prefix]
|
8
|
+
@cache = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def read(key)
|
12
|
+
value = @cache[key]
|
13
|
+
if !value && @fallback_backend
|
14
|
+
value = @fallback_backend.read(cache_key_for_fallback_backend(key))
|
15
|
+
@cache[key] = value
|
16
|
+
end
|
17
|
+
value
|
18
|
+
end
|
19
|
+
|
20
|
+
def write(key, value, options={})
|
21
|
+
@fallback_backend.write(cache_key_for_fallback_backend(key), value, options) if @fallback_backend
|
22
|
+
@cache[key] = value
|
23
|
+
end
|
24
|
+
|
25
|
+
def fetch(key, &block)
|
26
|
+
read(key) || block.call.tap { |value| write(key, value) }
|
27
|
+
end
|
28
|
+
|
29
|
+
def clear
|
30
|
+
@cache = {}
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def cache_key_for_fallback_backend(key)
|
36
|
+
@cache_prefix ? "#{@cache_prefix}/#{key}" : key
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end # module Scrivito
|
41
|
+
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module Scrivito
|
2
|
+
# The CacheGarbageCollector allows to remove old cache files from the Scrivito cache
|
3
|
+
# storage path. By default, a maximum of +DEFAULT_MAX_FILE_INODES+ file inodes that were accessed
|
4
|
+
# lately are kept in the cache directory. All other files and empty directories are removed. Log
|
5
|
+
# output is written to the Rails environment log file.
|
6
|
+
#
|
7
|
+
# @example Running the garbage collector with default settings
|
8
|
+
#
|
9
|
+
# bundle exec rake scrivito:cache:gc
|
10
|
+
#
|
11
|
+
# @example Changing the maximum number of file inodes
|
12
|
+
#
|
13
|
+
# bundle exec rake scrivito:cache:gc MAX_FILE_INODES=5000
|
14
|
+
class CacheGarbageCollector
|
15
|
+
DEFAULT_MAX_FILE_INODES = 100000
|
16
|
+
|
17
|
+
attr_accessor :max_file_inodes
|
18
|
+
|
19
|
+
def initialize(max_file_inodes = nil)
|
20
|
+
@max_file_inodes = (max_file_inodes || DEFAULT_MAX_FILE_INODES).to_i
|
21
|
+
end
|
22
|
+
|
23
|
+
def run_gc
|
24
|
+
announce "Cap number of cache file inodes at #{max_file_inodes} in #{cache_path}."
|
25
|
+
|
26
|
+
directories = []
|
27
|
+
file_inode_count = 0
|
28
|
+
delta_disk_space = 0
|
29
|
+
delta_count = 0
|
30
|
+
|
31
|
+
cache_entries.each do |cache_entry|
|
32
|
+
begin
|
33
|
+
stat = File.stat(cache_entry)
|
34
|
+
|
35
|
+
if stat.file?
|
36
|
+
file_inode_count += 1
|
37
|
+
next if file_inode_count <= max_file_inodes
|
38
|
+
|
39
|
+
File.delete(cache_entry)
|
40
|
+
|
41
|
+
delta_disk_space += stat.size
|
42
|
+
delta_count += 1
|
43
|
+
elsif stat.directory?
|
44
|
+
directories << cache_entry
|
45
|
+
end
|
46
|
+
rescue Errno::ENOENT
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
directories.sort.reverse_each do |dirname|
|
51
|
+
begin
|
52
|
+
Dir.rmdir(dirname)
|
53
|
+
delta_count += 1
|
54
|
+
rescue Errno::ENOTEMPTY, Errno::ENOENT
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
announce "Done. Removed #{delta_count} entries. Saved at least #{delta_disk_space} Bytes."
|
59
|
+
end
|
60
|
+
|
61
|
+
def cache_path
|
62
|
+
CmsCacheStorage.backend_cache.cache_path
|
63
|
+
end
|
64
|
+
|
65
|
+
def cache_entries
|
66
|
+
Dir["#{cache_path}/**/*"].sort_by do |file|
|
67
|
+
begin
|
68
|
+
-File.atime(file).to_i
|
69
|
+
rescue Errno::ENOENT
|
70
|
+
# If such file or directory does not exist, sort it as if the last
|
71
|
+
# access time is very long ago.
|
72
|
+
0
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def announce(message)
|
78
|
+
message = "[#{Time.now.iso8601}] #{message}"
|
79
|
+
|
80
|
+
Rails.logger.info(message)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Scrivito
|
2
|
+
|
3
|
+
class CacheMiddleware
|
4
|
+
def initialize(app)
|
5
|
+
@app = app
|
6
|
+
end
|
7
|
+
|
8
|
+
def call(env)
|
9
|
+
CmsBackend.instance.begin_caching
|
10
|
+
@app.call(env)
|
11
|
+
ensure
|
12
|
+
CmsBackend.instance.end_caching
|
13
|
+
Workspace.cache.clear
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end # module Scrivito
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Scrivito
|
2
|
+
|
3
|
+
class ClientConfig < Struct.new(:obj, :editing_context, :lookup_context)
|
4
|
+
def to_json
|
5
|
+
config = {}
|
6
|
+
config[:editing_context] = editing_context_config
|
7
|
+
config[:i18n] = i18n_config
|
8
|
+
config[:obj] = obj_config
|
9
|
+
config.to_json
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def editing_context_config
|
15
|
+
{
|
16
|
+
display_mode: editing_context.display_mode,
|
17
|
+
|
18
|
+
selected_workspace: {
|
19
|
+
id: editing_context.selected_workspace.id,
|
20
|
+
title: editing_context.selected_workspace.title
|
21
|
+
},
|
22
|
+
|
23
|
+
visible_workspace: {
|
24
|
+
id: editing_context.visible_workspace.id,
|
25
|
+
title: editing_context.visible_workspace.title
|
26
|
+
}
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
def i18n_config
|
31
|
+
{locale: I18n.locale}
|
32
|
+
end
|
33
|
+
|
34
|
+
def obj_config
|
35
|
+
if obj
|
36
|
+
{current_page: {
|
37
|
+
id: obj.id,
|
38
|
+
obj_class_name: obj.obj_class_name,
|
39
|
+
has_children: obj.children.any?,
|
40
|
+
has_conflict: obj.has_conflict?,
|
41
|
+
has_details_view: obj_has_details_view?,
|
42
|
+
modification: obj_modification,
|
43
|
+
}}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def obj_has_details_view?
|
48
|
+
lookup_context.find(obj.details_view_path).present?
|
49
|
+
rescue ActionView::MissingTemplate
|
50
|
+
false
|
51
|
+
end
|
52
|
+
|
53
|
+
def obj_modification
|
54
|
+
if editing_context.comparison.active?
|
55
|
+
editing_context.comparison.modification(obj)
|
56
|
+
else
|
57
|
+
obj.modification
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|