scrivito_sdk 0.66.0 → 0.70.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/scrivito/blobs_controller.rb +5 -0
- data/app/controllers/scrivito/objs_controller.rb +2 -1
- data/app/controllers/scrivito/ui_controller.rb +33 -3
- data/app/helpers/scrivito_helper.rb +14 -20
- data/app/views/scrivito/objs/update.json.jbuilder +1 -1
- data/app/views/scrivito/ui/index.html.erb +1 -1
- data/app/views/scrivito/webservice/_workspace.json.jbuilder +2 -1
- data/config/ca-bundle.crt +1 -1
- data/config/precedence_routes.rb +3 -2
- data/lib/assets/javascripts/scrivito.js +46 -0
- data/lib/assets/javascripts/scrivito_ui.js +931 -501
- data/lib/assets/stylesheets/scrivito.css +1 -0
- data/lib/assets/stylesheets/scrivito_ui.css +1 -1
- data/lib/generators/scrivito/install/templates/app/views/page/index.html.erb +3 -3
- data/lib/generators/scrivito/page/page_generator.rb +3 -0
- data/lib/generators/scrivito/page/templates/model.erb +3 -0
- data/lib/generators/scrivito/widget/templates/model.erb +3 -0
- data/lib/generators/scrivito/widget/widget_generator.rb +3 -0
- data/lib/scrivito/attribute_content.rb +93 -60
- data/lib/scrivito/attribute_definition.rb +3 -3
- data/lib/scrivito/attribute_serializer.rb +2 -2
- data/lib/scrivito/backend/obj_data_cache.rb +22 -9
- data/lib/scrivito/basic_obj.rb +238 -130
- data/lib/scrivito/basic_widget.rb +32 -20
- data/lib/scrivito/binary.rb +74 -45
- data/lib/scrivito/binary_routing.rb +52 -0
- data/lib/scrivito/cache_middleware.rb +0 -5
- data/lib/scrivito/client_attribute_serializer.rb +134 -0
- data/lib/scrivito/cms_backend.rb +51 -33
- data/lib/scrivito/cms_data_cache.rb +1 -0
- data/lib/scrivito/cms_dispatch_controller.rb +1 -1
- data/lib/scrivito/cms_env.rb +1 -11
- data/lib/scrivito/cms_field_tag.rb +10 -7
- data/lib/scrivito/cms_rest_api/rate_limit.rb +5 -5
- data/lib/scrivito/cms_rest_api/request_timer.rb +27 -0
- data/lib/scrivito/cms_rest_api/widget_extractor.rb +8 -6
- data/lib/scrivito/cms_rest_api.rb +107 -54
- data/lib/scrivito/cms_routing.rb +13 -25
- data/lib/scrivito/configuration.rb +5 -2
- data/lib/scrivito/controller_actions.rb +68 -7
- data/lib/scrivito/controller_runtime.rb +8 -0
- data/lib/scrivito/date_attribute.rb +8 -0
- data/lib/scrivito/errors.rb +6 -3
- data/lib/scrivito/generator_helper.rb +13 -0
- data/lib/scrivito/image_tag.rb +24 -30
- data/lib/scrivito/layout_tags.rb +12 -6
- data/lib/scrivito/link.rb +46 -30
- data/lib/scrivito/log_subscriber.rb +15 -0
- data/lib/scrivito/membership.rb +3 -3
- data/lib/scrivito/membership_collection.rb +10 -10
- data/lib/scrivito/meta_data_collection.rb +22 -0
- data/lib/scrivito/model_library.rb +7 -1
- data/lib/scrivito/obj_collection.rb +18 -16
- data/lib/scrivito/obj_params_parser.rb +1 -1
- data/lib/scrivito/obj_search_enumerator.rb +35 -35
- data/lib/scrivito/page_config.rb +55 -0
- data/lib/scrivito/request_homepage.rb +23 -0
- data/lib/scrivito/routing_helper.rb +8 -8
- data/lib/scrivito/sdk_engine.rb +2 -3
- data/lib/scrivito/ui_config.rb +85 -0
- data/lib/scrivito/user.rb +30 -23
- data/lib/scrivito/user_definition.rb +48 -47
- data/lib/scrivito/widget_tag.rb +11 -0
- data/lib/scrivito/workspace.rb +93 -35
- data/lib/scrivito/workspace_selection_middleware.rb +8 -1
- data/lib/scrivito_sdk.rb +24 -24
- metadata +24 -33
- data/lib/assets/javascripts/scrivito_sdk.js +0 -57
- data/lib/assets/stylesheets/scrivito_sdk.css +0 -1
- data/lib/scrivito/client_config.rb +0 -113
- data/lib/scrivito/editing_context_helper.rb +0 -19
- data/lib/scrivito/named_link.rb +0 -39
@@ -20,10 +20,11 @@ module ControllerActions
|
|
20
20
|
:show_widget,
|
21
21
|
:widget_details,
|
22
22
|
:page_details,
|
23
|
-
:resource_details,
|
24
23
|
]
|
25
24
|
|
26
25
|
before_filter :load_object
|
26
|
+
|
27
|
+
helper_method :scrivito_in_editable_view?
|
27
28
|
end
|
28
29
|
|
29
30
|
#
|
@@ -60,11 +61,70 @@ module ControllerActions
|
|
60
61
|
render 'scrivito/page_details', layout: 'scrivito_dialog'
|
61
62
|
end
|
62
63
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
64
|
+
# How to handle widget errors in +production+.
|
65
|
+
#
|
66
|
+
# When an exception is raised from within a widget, the entire page is not available.
|
67
|
+
# Often, this is the case in production if the developer has forgotten to handle specific
|
68
|
+
# content scenarios such as empty date attributes, missing titles, unmanaged enum values, etc.
|
69
|
+
# but also for simple coding mistakes during development.
|
70
|
+
#
|
71
|
+
# Override this method to prevent the entire page from being unavailable due to widget errors.
|
72
|
+
#
|
73
|
+
# The overridden method allows to:
|
74
|
+
# * catch a widget error and replace it with an HTML placeholder.
|
75
|
+
# * report a widget error to an external service like Honeybadger or Airbrake.
|
76
|
+
#
|
77
|
+
# This method is _not_ called if Rails is in the +development+ or +test+ environment.
|
78
|
+
# In those environments, all widget errors are just raised.
|
79
|
+
#
|
80
|
+
# By default, this method just reraises the given error.
|
81
|
+
#
|
82
|
+
# @param widget [Scrivito::BasicWidget] the flawed widget
|
83
|
+
# @param error [StandardError] the error that occurred
|
84
|
+
# @raise [StandardError] if this method is not overridden, the +error+ passed to it is reraised.
|
85
|
+
#
|
86
|
+
# @example Notify external service about widget error and render an HTML placeholder:
|
87
|
+
# def on_scrivito_widget_error(widget, error)
|
88
|
+
# # Report error to external service (e.g. Honeybadger or Airbrake):
|
89
|
+
# Honeybadger.notify(error)
|
90
|
+
# notify_airbrake(error)
|
91
|
+
#
|
92
|
+
# # Replace corrupted widget output with a placeholder:
|
93
|
+
# message = "Rendering #{widget.description_for_editor} failed with #{error.message}"
|
94
|
+
# return "<!--#{message}-->".html_safe if Rails.env.production?
|
95
|
+
# "<p>#{message}</p>".html_safe
|
96
|
+
# end
|
97
|
+
# @api public
|
98
|
+
def on_scrivito_widget_error(widget, error)
|
99
|
+
raise error
|
100
|
+
end
|
101
|
+
|
102
|
+
#
|
103
|
+
# Returns whether the GUI is in the +editable+ view.
|
104
|
+
#
|
105
|
+
# +scrivito_in_editable_view?+ is also a helper method.
|
106
|
+
#
|
107
|
+
# @api public
|
108
|
+
# @return +true+ if the current visitor is an authenticated editor, the selected workspace is
|
109
|
+
# editable and the display mode is +editing+.
|
110
|
+
# @return +false+ otherwise.
|
111
|
+
#
|
112
|
+
def scrivito_in_editable_view?
|
113
|
+
editing_context.editable_display_mode?
|
114
|
+
end
|
115
|
+
|
116
|
+
#
|
117
|
+
# Returns the current user.
|
118
|
+
#
|
119
|
+
# +scrivito_user+ is also a helper method.
|
120
|
+
#
|
121
|
+
# @api public
|
122
|
+
# @return [Scrivito::User] if the {Scrivito::Configuration.editing_auth} callback returns an
|
123
|
+
# instance of {Scrivito::User}.
|
124
|
+
# @return +nil+ otherwise.
|
125
|
+
#
|
126
|
+
def scrivito_user
|
127
|
+
editing_context.editor
|
68
128
|
end
|
69
129
|
|
70
130
|
module ClassMethods
|
@@ -126,7 +186,8 @@ module ControllerActions
|
|
126
186
|
# @api public
|
127
187
|
#
|
128
188
|
def deliver_file
|
129
|
-
if
|
189
|
+
if binary = @obj.binary
|
190
|
+
url = BinaryRouting.new(request, scrivito_engine).resolved_binary_obj_url(@obj, binary)
|
130
191
|
redirect_to CmsRouting.match_protocol(url, request)
|
131
192
|
else
|
132
193
|
render text: 'Empty Blob', status: 404
|
@@ -9,6 +9,14 @@ protected
|
|
9
9
|
|
10
10
|
attr_internal :scrivito_runtime
|
11
11
|
|
12
|
+
def process_action(action, *args)
|
13
|
+
# We also need to reset the runtime before each action
|
14
|
+
# because of queries in middleware or in cases we are streaming
|
15
|
+
# and it won't be cleaned up by the method below.
|
16
|
+
reset_scrivito_runtime
|
17
|
+
super
|
18
|
+
end
|
19
|
+
|
12
20
|
def cleanup_view_runtime
|
13
21
|
self.scrivito_runtime = reset_scrivito_runtime
|
14
22
|
|
@@ -12,6 +12,14 @@ module Scrivito
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
+
def self.parse_iso8601(iso8601_date_time)
|
16
|
+
return unless iso8601_date_time
|
17
|
+
|
18
|
+
DateTime.iso8601(iso8601_date_time).in_time_zone
|
19
|
+
rescue ArgumentError
|
20
|
+
raise "The value is not a valid ISO 8601 date time: #{iso8601_date_time.inspect}"
|
21
|
+
end
|
22
|
+
|
15
23
|
def self.serialize(attribute_value)
|
16
24
|
attribute_value = case attribute_value
|
17
25
|
when Date then attribute_value.to_time
|
data/lib/scrivito/errors.rb
CHANGED
@@ -17,7 +17,7 @@ end
|
|
17
17
|
class InternalError < ScrivitoError
|
18
18
|
end
|
19
19
|
|
20
|
-
# @api
|
20
|
+
# @api public
|
21
21
|
class TransformationError < ScrivitoError
|
22
22
|
attr_reader :code
|
23
23
|
|
@@ -27,12 +27,15 @@ class TransformationError < ScrivitoError
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
# @api
|
30
|
+
# @api public
|
31
31
|
class TransformationSourceError < TransformationError
|
32
32
|
end
|
33
33
|
|
34
|
-
# @api
|
34
|
+
# @api public
|
35
35
|
class TransformationDefinitionError < TransformationError
|
36
36
|
end
|
37
37
|
|
38
|
+
class TransferModificationsError < ScrivitoError
|
39
|
+
end
|
40
|
+
|
38
41
|
end # module Scrivito
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Scrivito
|
2
|
+
module GeneratorHelper
|
3
|
+
class << self
|
4
|
+
def attribute_definition(arg)
|
5
|
+
if %w(enum multienum).include?(arg.type.to_s)
|
6
|
+
"attribute :#{arg.name}, :#{arg.type}, values: []"
|
7
|
+
else
|
8
|
+
"attribute :#{arg.name}, :#{arg.type}"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/scrivito/image_tag.rb
CHANGED
@@ -1,51 +1,45 @@
|
|
1
1
|
module Scrivito
|
2
2
|
|
3
3
|
class ImageTag < Struct.new(:view_context)
|
4
|
-
def options(
|
4
|
+
def options(obj_or_widget, attribute_name, tag_options, editing_options)
|
5
5
|
tag_options.reverse_merge(
|
6
|
-
src: src(
|
7
|
-
alt: alt(
|
6
|
+
src: src(obj_or_widget, attribute_name, editing_options),
|
7
|
+
alt: alt(obj_or_widget, attribute_name)
|
8
8
|
)
|
9
9
|
end
|
10
10
|
|
11
11
|
private
|
12
12
|
|
13
|
-
def src(
|
14
|
-
path(
|
13
|
+
def src(obj_or_widget, attribute_name, editing_options)
|
14
|
+
path(obj_or_widget, attribute_name, editing_options) ||
|
15
15
|
editing_options[:placeholder] ||
|
16
16
|
view_context.image_path('scrivito/image_placeholder.png')
|
17
17
|
end
|
18
18
|
|
19
|
-
def alt(
|
20
|
-
case target =
|
21
|
-
when Binary then
|
19
|
+
def alt(obj_or_widget, attribute_name)
|
20
|
+
case target = obj_or_widget[attribute_name]
|
21
|
+
when Binary then obj_or_widget.try(:alt_description)
|
22
22
|
when Enumerable then target.first.try(:alt_description)
|
23
23
|
else target.try(:alt_description)
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
def path(
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
link.internal? ? link.obj : link
|
44
|
-
end
|
45
|
-
|
46
|
-
def linklist_target(linklist)
|
47
|
-
if linklist.any?
|
48
|
-
link_target(linklist.first)
|
27
|
+
def path(obj_or_widget, attribute_name, editing_options)
|
28
|
+
attribute_value = obj_or_widget[attribute_name]
|
29
|
+
return if attribute_value.blank?
|
30
|
+
|
31
|
+
image_options = editing_options.slice(:transform)
|
32
|
+
|
33
|
+
if attribute_value.is_a?(Binary)
|
34
|
+
if obj_or_widget.is_a?(Widget)
|
35
|
+
raise ScrivitoError, 'scrivito_image_tag does not accept widgets with binary attributes'
|
36
|
+
end
|
37
|
+
BinaryRouting.new(request, scrivito_engine)
|
38
|
+
.binary_obj_url(obj_or_widget, attribute_value, image_options)
|
39
|
+
else
|
40
|
+
path = CmsRouting.new(request, main_app, scrivito_engine, image_options)
|
41
|
+
.path_or_url(attribute_value, :path)
|
42
|
+
path unless path == CmsRouting::LINK_TO_EMPTY_BLOB
|
49
43
|
end
|
50
44
|
end
|
51
45
|
|
data/lib/scrivito/layout_tags.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
module Scrivito
|
2
2
|
|
3
3
|
class LayoutTags < Struct.new(:view)
|
4
|
-
def
|
4
|
+
def page_config(obj)
|
5
5
|
if view.scrivito_user
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
page_config = PageConfig.new(
|
7
|
+
obj: obj,
|
8
|
+
editing_context: editing_context,
|
9
|
+
lookup_context: view.lookup_context,
|
10
10
|
).to_json
|
11
|
-
view.content_tag(:div, '', 'data-scrivito-private-config' =>
|
11
|
+
view.content_tag(:div, '', 'data-scrivito-private-page-config' => page_config)
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
@@ -21,6 +21,12 @@ class LayoutTags < Struct.new(:view)
|
|
21
21
|
content << "; Version #{GemInfo.version}" if view.scrivito_user
|
22
22
|
view.tag(:meta, name: 'generator', content: content)
|
23
23
|
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def editing_context
|
28
|
+
EditingContextMiddleware.from_request(view.request)
|
29
|
+
end
|
24
30
|
end
|
25
31
|
|
26
32
|
end
|
data/lib/scrivito/link.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
require 'active_model/naming'
|
2
2
|
|
3
3
|
module Scrivito
|
4
|
-
# This class provides an
|
5
|
-
# To format a link for rendering
|
4
|
+
# This class provides an interface for handling CMS links.
|
5
|
+
# To format a link for rendering on an HTML page, use the +scrivito_path+ or +scrivito_url+ methods.
|
6
6
|
# @api public
|
7
7
|
class Link
|
8
8
|
|
9
9
|
extend ActiveModel::Naming
|
10
10
|
|
11
|
-
# Parses a
|
11
|
+
# Parses a URL and returns a {Link} object. Determines internal URLs based on the given
|
12
12
|
# +hostname+ and +port+.
|
13
13
|
# @api public
|
14
14
|
# @param [String] url
|
@@ -18,7 +18,9 @@ module Scrivito
|
|
18
18
|
LinkParser.new(host, port).parse(url)
|
19
19
|
end
|
20
20
|
|
21
|
-
# Create a new link
|
21
|
+
# Create a new link object.
|
22
|
+
# @example Set the 'current_campaign' link of an object:
|
23
|
+
# obj.update(current_campaign: Scrivito::Link.new(obj: Obj.find('55dd1ce50ecc41c8')))
|
22
24
|
# @api public
|
23
25
|
# @param [Hash] link_data
|
24
26
|
# @option link_data [String] url
|
@@ -31,57 +33,56 @@ module Scrivito
|
|
31
33
|
@link_data = link_data.with_indifferent_access
|
32
34
|
end
|
33
35
|
|
34
|
-
# The
|
35
|
-
# Warning: Do not output the
|
36
|
-
# Normally you want to use the +scrivito_path+ or +scrivito_url+ methods to format a link.
|
36
|
+
# The external URL of the link. Only available for external links.
|
37
|
+
# Warning: Do not output the URL directly unless you know what you are doing.
|
38
|
+
# Normally, you want to use the +scrivito_path+ or +scrivito_url+ methods to format a link.
|
37
39
|
# @api public
|
38
40
|
def url
|
39
41
|
@link_data[:url]
|
40
42
|
end
|
41
43
|
|
42
|
-
# Set the
|
44
|
+
# Set the external URL of the link. This causes the link to become an external link.
|
43
45
|
# @api public
|
44
46
|
# @param value [String] the url of the link
|
45
47
|
def url=(value)
|
46
48
|
@link_data[:url] = value
|
47
49
|
end
|
48
50
|
|
49
|
-
# Returns the {BasicObj Obj} this link
|
51
|
+
# Returns the {BasicObj Obj} this link references. May be +nil+ if the
|
50
52
|
# link is external.
|
51
53
|
# @api public
|
52
54
|
def obj
|
53
55
|
@link_data[:obj]
|
54
56
|
end
|
55
57
|
|
56
|
-
# Set the {BasicObj Obj} this link
|
57
|
-
# link is external.
|
58
|
+
# Set the {BasicObj Obj} this link should reference.
|
58
59
|
# @api public
|
59
|
-
# @param value [Obj] the obj this link should
|
60
|
+
# @param value [Obj] the obj this link should point to
|
60
61
|
def obj=(value)
|
61
62
|
@link_data[:obj] = value
|
62
63
|
end
|
63
64
|
|
64
|
-
#
|
65
|
+
# Returns the title of the link.
|
65
66
|
# @api public
|
66
67
|
def title
|
67
68
|
@link_data[:title]
|
68
69
|
end
|
69
70
|
|
70
|
-
# Set the link
|
71
|
+
# Set the link title.
|
71
72
|
# @api public
|
72
|
-
# @param value [String] the link
|
73
|
+
# @param value [String] the title of the link
|
73
74
|
def title=(value)
|
74
75
|
@link_data[:title] = value
|
75
76
|
end
|
76
77
|
|
77
|
-
# Returns the
|
78
|
+
# Returns the query string of the link as in "index.html?query_string".
|
78
79
|
# See RFC3986 for details (http://www.ietf.org/rfc/rfc3986.txt).
|
79
80
|
# @api public
|
80
81
|
def query
|
81
82
|
@link_data[:query]
|
82
83
|
end
|
83
84
|
|
84
|
-
# Set the
|
85
|
+
# Set the query string of the link as in "index.html?query_string".
|
85
86
|
# See RFC3986 for details (http://www.ietf.org/rfc/rfc3986.txt).
|
86
87
|
# @api public
|
87
88
|
# @param value [String] the query string of the link
|
@@ -89,31 +90,39 @@ module Scrivito
|
|
89
90
|
@link_data[:query] = value
|
90
91
|
end
|
91
92
|
|
92
|
-
# Returns the link
|
93
|
+
# Returns the anchor of the link as in "index.html#anchor".
|
93
94
|
# See RFC3986 for details (http://www.ietf.org/rfc/rfc3986.txt).
|
94
95
|
# @api public
|
95
96
|
def fragment
|
96
97
|
@link_data[:fragment]
|
97
98
|
end
|
98
99
|
|
99
|
-
# Set the link
|
100
|
+
# Set the anchor of the link as in "index.html#anchor".
|
100
101
|
# See RFC3986 for details (http://www.ietf.org/rfc/rfc3986.txt).
|
101
102
|
# @api public
|
102
|
-
# @param value [String] the anchor or
|
103
|
+
# @param value [String] the anchor or fragment of the link
|
103
104
|
def fragment=(value)
|
104
105
|
@link_data[:fragment] = value
|
105
106
|
end
|
106
107
|
|
108
|
+
# Returns the link target. "target" refers to the equally-named HTML attribute,
|
109
|
+
# not the link destination.
|
110
|
+
# @api public
|
107
111
|
def target
|
108
112
|
@link_data[:target]
|
109
113
|
end
|
110
114
|
|
115
|
+
# Set the link target. "target" refers to the equally-named HTML attribute,
|
116
|
+
# not the link destination.
|
117
|
+
# @api public
|
118
|
+
# @param value [String] the target of the link
|
111
119
|
def target=(value)
|
112
120
|
@link_data[:target] = value
|
113
121
|
end
|
114
122
|
|
115
|
-
# Returns the file extension (e.g. zip, pdf) of
|
116
|
-
#
|
123
|
+
# Returns the file extension (e.g. zip, pdf) of the (internal or external) destination
|
124
|
+
# of this link.
|
125
|
+
# Returns an empty string if the file extension cannot be determined.
|
117
126
|
# @api public
|
118
127
|
def file_extension
|
119
128
|
if internal?
|
@@ -124,9 +133,8 @@ module Scrivito
|
|
124
133
|
end
|
125
134
|
end
|
126
135
|
|
127
|
-
# Returns the title of this Link if it is set.
|
128
|
-
#
|
129
|
-
# or the URL for external Links.
|
136
|
+
# Returns the title of this Link if it is set. If not, the +display_title+ of the destination
|
137
|
+
# object is returned for internal links, or the +url+ for external links.
|
130
138
|
# @api public
|
131
139
|
def display_title
|
132
140
|
dt = title
|
@@ -135,10 +143,10 @@ module Scrivito
|
|
135
143
|
dt
|
136
144
|
end
|
137
145
|
|
138
|
-
# The alt description of a +Link
|
146
|
+
# The alt description of a +Link+, used by {ScrivitoHelper#scrivito_image_tag}.
|
139
147
|
#
|
140
|
-
# By default this method returns the +title+ of this +Link+.
|
141
|
-
# If +title+ is nil and this +Link+ references an {BasicObj Obj}
|
148
|
+
# By default, this method returns the +title+ of this +Link+.
|
149
|
+
# If +title+ is +nil+ and this +Link+ references an {BasicObj Obj}, the
|
142
150
|
# +alt_description+ of that {BasicObj Obj} is used.
|
143
151
|
#
|
144
152
|
# @api public
|
@@ -147,13 +155,13 @@ module Scrivito
|
|
147
155
|
obj.alt_description if internal?
|
148
156
|
end
|
149
157
|
|
150
|
-
# Returns true this Link
|
158
|
+
# Returns true if this Link points to a CMS object.
|
151
159
|
# @api public
|
152
160
|
def internal?
|
153
161
|
url.nil?
|
154
162
|
end
|
155
163
|
|
156
|
-
# Returns true if this Link
|
164
|
+
# Returns true if this Link points to an external location.
|
157
165
|
# @api public
|
158
166
|
def external?
|
159
167
|
!internal?
|
@@ -190,12 +198,20 @@ module Scrivito
|
|
190
198
|
params[:title] = title if title
|
191
199
|
params[:query] = query if query
|
192
200
|
params[:fragment] = fragment if fragment
|
201
|
+
params[:target] = target if target
|
193
202
|
else
|
194
203
|
params[:url] = url
|
195
204
|
params[:title] = title if title
|
205
|
+
params[:target] = target if target
|
196
206
|
end
|
197
207
|
|
198
208
|
params
|
199
209
|
end
|
210
|
+
|
211
|
+
def ==(other)
|
212
|
+
return false unless other.is_a?(Link)
|
213
|
+
|
214
|
+
to_cms_api_linklist_params == other.to_cms_api_linklist_params
|
215
|
+
end
|
200
216
|
end
|
201
217
|
end
|
@@ -21,6 +21,21 @@ module Scrivito
|
|
21
21
|
debug " #{name} #{event.payload[:index]} #{event.payload[:keys].inspect}"
|
22
22
|
end
|
23
23
|
|
24
|
+
def backend_request(event)
|
25
|
+
self.class.runtime += event.duration
|
26
|
+
return unless logger.debug?
|
27
|
+
|
28
|
+
duration = '(%.1fms)' % [event.duration]
|
29
|
+
|
30
|
+
param = event.payload[:params]
|
31
|
+
param_text = " #{param}" if param
|
32
|
+
|
33
|
+
verb_text = event.payload[:verb].upcase
|
34
|
+
path_text = event.payload[:path]
|
35
|
+
|
36
|
+
debug " Scrivito #{verb_text} #{path_text}#{param_text} #{duration}"
|
37
|
+
end
|
38
|
+
|
24
39
|
def logger
|
25
40
|
Rails.logger
|
26
41
|
end
|
data/lib/scrivito/membership.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Scrivito
|
2
2
|
|
3
3
|
# @api public
|
4
|
-
# Represents a Membership of a {User} in a {Workspace}
|
4
|
+
# Represents a Membership of a {User} in a {Workspace}.
|
5
5
|
class Membership
|
6
6
|
|
7
7
|
# @api public
|
@@ -15,7 +15,7 @@ module Scrivito
|
|
15
15
|
#
|
16
16
|
# @note Currently the only available role is "owner".
|
17
17
|
#
|
18
|
-
# @return [String] the name of role
|
18
|
+
# @return [String] the name of the role
|
19
19
|
attr_reader :role
|
20
20
|
|
21
21
|
def initialize(user_id, data)
|
@@ -28,7 +28,7 @@ module Scrivito
|
|
28
28
|
# @api public
|
29
29
|
# @return The value returned by the proc set in {Configuration.find_user}.
|
30
30
|
# @return An unknown user if no proc is set in {Configuration.find_user} or the proc returns a
|
31
|
-
# falsy value. The unknown user will have the id of the original user and no
|
31
|
+
# falsy value. The unknown user will have the id of the original user and no capabilities.
|
32
32
|
# @see Scrivito::Configuration.find_user
|
33
33
|
def user
|
34
34
|
User.find(user_id) || User.unknown_user(user_id)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Scrivito
|
2
2
|
# @api public
|
3
3
|
# The MembershipCollection includes all members of a given {Workspace}.
|
4
|
-
# You can access it using {Workspace#memberships} method.
|
4
|
+
# You can access it using the {Workspace#memberships} method.
|
5
5
|
class MembershipCollection
|
6
6
|
extend Forwardable
|
7
7
|
include Enumerable
|
@@ -11,28 +11,28 @@ module Scrivito
|
|
11
11
|
# @api public
|
12
12
|
# @!method each
|
13
13
|
# Iterate over all {Membership Memberships} of a specific {Workspace}. Allows
|
14
|
-
# you to use all methods defined by
|
14
|
+
# you to use all the methods defined by Ruby's Enumerable module.
|
15
15
|
#
|
16
16
|
# @yield [Membership]
|
17
17
|
#
|
18
|
-
# @return [Enumerator] if no block is given an Enumerator is returned
|
18
|
+
# @return [Enumerator] if no block is given, an Enumerator is returned
|
19
19
|
#
|
20
20
|
# @example
|
21
|
-
# # Obtain all owners of a workspace
|
21
|
+
# # Obtain all owners of a workspace.
|
22
22
|
# my_workspace.memberships.select do |membership|
|
23
23
|
# membership.role == "owner"
|
24
24
|
# end
|
25
25
|
#
|
26
|
-
# # Get an array of all the members' user_ids
|
26
|
+
# # Get an array of all the members' user_ids.
|
27
27
|
# my_workspace.memberships.map { |membership| membership.user_id }
|
28
28
|
#
|
29
|
-
# # Or use it directly to iterate over all items
|
29
|
+
# # Or use it directly to iterate over all items.
|
30
30
|
# my_workspace.memberships.each do |membership|
|
31
31
|
# puts "User #{membership.user_id} has the role #{membership.role}"
|
32
32
|
# end
|
33
33
|
#
|
34
|
-
# @note For a complete list of
|
35
|
-
# documentation of the Enumerable module
|
34
|
+
# @note For a complete list of the provided methods, please refer to the
|
35
|
+
# documentation of the Enumerable module.
|
36
36
|
def_delegator :memberships, :each
|
37
37
|
|
38
38
|
def initialize(workspace)
|
@@ -40,7 +40,7 @@ module Scrivito
|
|
40
40
|
end
|
41
41
|
|
42
42
|
# @api public
|
43
|
-
#
|
43
|
+
# Returns a hash where the keys are +user_id+s and the values are Membership instances.
|
44
44
|
# @return [Hash<String, Membership>]
|
45
45
|
def to_h
|
46
46
|
memberships.inject(HashWithIndifferentAccess.new) do |hash, membership|
|
@@ -50,7 +50,7 @@ module Scrivito
|
|
50
50
|
end
|
51
51
|
|
52
52
|
# @api public
|
53
|
-
# Returns the membership
|
53
|
+
# Returns the membership of a user or nil.
|
54
54
|
#
|
55
55
|
# @param [User, String] id_or_user
|
56
56
|
# @return [Membership, nil]
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Scrivito
|
2
|
+
#
|
3
|
+
# This class represents a collection of meta data attributes.
|
4
|
+
#
|
5
|
+
# @api beta
|
6
|
+
#
|
7
|
+
class MetaDataCollection
|
8
|
+
def initialize(attributes)
|
9
|
+
@attributes = ActiveSupport::HashWithIndifferentAccess.new(attributes)
|
10
|
+
end
|
11
|
+
|
12
|
+
#
|
13
|
+
# Find value of a meta data attribute.
|
14
|
+
#
|
15
|
+
# @api beta
|
16
|
+
# @param name [Symbol, String] the name of the meta data attribute.
|
17
|
+
# @return [String, Array, Fixnum, Date, nil] meta data attribute value if found or +nil+ otherwise.
|
18
|
+
def [](name)
|
19
|
+
@attributes[name]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -77,11 +77,17 @@ class ModelLibrary
|
|
77
77
|
end
|
78
78
|
|
79
79
|
def load_models_from_path(type, path, base_class)
|
80
|
-
|
80
|
+
candidates_from_path(type, path).map do |file_path|
|
81
81
|
load_model(file_path.gsub(path, '').gsub('.rb', '').classify, base_class)
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
85
|
+
def candidates_from_path(type, path)
|
86
|
+
result = Dir["#{path}/**/*_#{type}.rb"]
|
87
|
+
result += Dir["#{path}/**/page.rb"] if type == 'page'
|
88
|
+
result
|
89
|
+
end
|
90
|
+
|
85
91
|
def load_model(class_name, base_class)
|
86
92
|
model_class = class_name.constantize
|
87
93
|
model_class if model_class.ancestors.include?(base_class)
|