scrivito_sdk 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +5 -0
  3. data/README +6 -0
  4. data/app/controllers/cms_controller.rb +7 -0
  5. data/app/controllers/scrivito/blobs_controller.rb +10 -0
  6. data/app/controllers/scrivito/default_cms_controller.rb +61 -0
  7. data/app/controllers/scrivito/objs_controller.rb +200 -0
  8. data/app/controllers/scrivito/tasks_controller.rb +11 -0
  9. data/app/controllers/scrivito/webservice_controller.rb +36 -0
  10. data/app/controllers/scrivito/workspaces_controller.rb +41 -0
  11. data/app/helpers/cms_helper.rb +7 -0
  12. data/app/helpers/cms_routing_helper.rb +7 -0
  13. data/app/helpers/scrivito/cms_asset_helper.rb +103 -0
  14. data/app/helpers/scrivito/cms_tag_helper.rb +231 -0
  15. data/app/helpers/scrivito/default_cms_helper.rb +21 -0
  16. data/app/helpers/scrivito/default_cms_routing_helper.rb +130 -0
  17. data/app/helpers/scrivito/display_helper.rb +71 -0
  18. data/app/helpers/scrivito/editing_helper.rb +26 -0
  19. data/app/helpers/scrivito/layout_helper.rb +28 -0
  20. data/app/models/named_link.rb +2 -0
  21. data/app/views/cms/_index.html.erb +7 -0
  22. data/app/views/cms/index.html.erb +1 -0
  23. data/app/views/scrivito/_editing_javascript.html.erb +7 -0
  24. data/app/views/scrivito/default_cms/show_widget.html.erb +1 -0
  25. data/app/views/scrivito/objs/copy_widget.html.erb +1 -0
  26. data/app/views/scrivito/objs/create_widget.html.erb +1 -0
  27. data/app/views/scrivito/widget_thumbnail.html.erb +9 -0
  28. data/config/ca-bundle.crt +3509 -0
  29. data/config/cms_routes.rb +17 -0
  30. data/config/locales/de.scrivito.errors.yml +7 -0
  31. data/config/locales/de.scrivito.lib.yml +6 -0
  32. data/config/locales/de.scrivito.models.yml +6 -0
  33. data/config/locales/en.scrivito.errors.yml +7 -0
  34. data/config/locales/en.scrivito.lib.yml +6 -0
  35. data/config/locales/en.scrivito.models.yml +6 -0
  36. data/config/routes.rb +37 -0
  37. data/lib/assets/images/180x120.gif +0 -0
  38. data/lib/assets/images/scrivito/image_placeholder.png +0 -0
  39. data/lib/assets/javascripts/scrivito_editing.js +14642 -0
  40. data/lib/assets/stylesheets/scrivito.css +180 -0
  41. data/lib/assets/stylesheets/scrivito_editing.css +2213 -0
  42. data/lib/generators/cms/migration/USAGE +9 -0
  43. data/lib/generators/cms/migration/migration_generator.rb +21 -0
  44. data/lib/generators/cms/migration/templates/migration.erb +10 -0
  45. data/lib/obj.rb +3 -0
  46. data/lib/scrivito/access_denied.rb +6 -0
  47. data/lib/scrivito/attribute_content.rb +194 -0
  48. data/lib/scrivito/backend_error.rb +4 -0
  49. data/lib/scrivito/basic_obj.rb +840 -0
  50. data/lib/scrivito/basic_widget.rb +238 -0
  51. data/lib/scrivito/blob.rb +48 -0
  52. data/lib/scrivito/cache.rb +41 -0
  53. data/lib/scrivito/cache_garbage_collector.rb +83 -0
  54. data/lib/scrivito/cache_middleware.rb +17 -0
  55. data/lib/scrivito/client_config.rb +62 -0
  56. data/lib/scrivito/client_error.rb +12 -0
  57. data/lib/scrivito/cms_accessible.rb +30 -0
  58. data/lib/scrivito/cms_backend.rb +238 -0
  59. data/lib/scrivito/cms_cache_storage.rb +51 -0
  60. data/lib/scrivito/cms_dispatch_controller.rb +46 -0
  61. data/lib/scrivito/cms_env.rb +63 -0
  62. data/lib/scrivito/cms_field_tag.rb +112 -0
  63. data/lib/scrivito/cms_rest_api.rb +151 -0
  64. data/lib/scrivito/cms_rest_api/attribute_serializer.rb +98 -0
  65. data/lib/scrivito/cms_rest_api/blob_uploader.rb +18 -0
  66. data/lib/scrivito/cms_rest_api/widget_extractor.rb +42 -0
  67. data/lib/scrivito/cms_test_request.rb +23 -0
  68. data/lib/scrivito/communication_error.rb +17 -0
  69. data/lib/scrivito/comparison.rb +67 -0
  70. data/lib/scrivito/configuration.rb +221 -0
  71. data/lib/scrivito/connection_manager.rb +100 -0
  72. data/lib/scrivito/content_conversion.rb +43 -0
  73. data/lib/scrivito/content_service.rb +118 -0
  74. data/lib/scrivito/content_state.rb +109 -0
  75. data/lib/scrivito/content_state_caching.rb +47 -0
  76. data/lib/scrivito/content_state_visitor.rb +19 -0
  77. data/lib/scrivito/controller_runtime.rb +35 -0
  78. data/lib/scrivito/date_attribute.rb +16 -0
  79. data/lib/scrivito/deprecation.rb +21 -0
  80. data/lib/scrivito/diff.rb +110 -0
  81. data/lib/scrivito/editing_context.rb +106 -0
  82. data/lib/scrivito/editing_context_middleware.rb +60 -0
  83. data/lib/scrivito/engine.rb +65 -0
  84. data/lib/scrivito/errors.rb +11 -0
  85. data/lib/scrivito/html_string.rb +18 -0
  86. data/lib/scrivito/link.rb +187 -0
  87. data/lib/scrivito/link_parser.rb +81 -0
  88. data/lib/scrivito/log_subscriber.rb +29 -0
  89. data/lib/scrivito/migration.rb +2 -0
  90. data/lib/scrivito/migrations.rb +12 -0
  91. data/lib/scrivito/migrations/cms_backend.rb +94 -0
  92. data/lib/scrivito/migrations/installer.rb +45 -0
  93. data/lib/scrivito/migrations/migration.rb +93 -0
  94. data/lib/scrivito/migrations/migration_dsl.rb +143 -0
  95. data/lib/scrivito/migrations/migration_store.rb +23 -0
  96. data/lib/scrivito/migrations/migrator.rb +135 -0
  97. data/lib/scrivito/migrations/workspace_lock.rb +39 -0
  98. data/lib/scrivito/model_identity.rb +13 -0
  99. data/lib/scrivito/modification.rb +8 -0
  100. data/lib/scrivito/named_link.rb +75 -0
  101. data/lib/scrivito/network_error.rb +11 -0
  102. data/lib/scrivito/obj_data.rb +140 -0
  103. data/lib/scrivito/obj_data_from_hash.rb +31 -0
  104. data/lib/scrivito/obj_data_from_service.rb +84 -0
  105. data/lib/scrivito/obj_params_parser.rb +61 -0
  106. data/lib/scrivito/obj_search_builder.rb +62 -0
  107. data/lib/scrivito/obj_search_enumerator.rb +374 -0
  108. data/lib/scrivito/rate_limit_exceeded.rb +5 -0
  109. data/lib/scrivito/revision.rb +9 -0
  110. data/lib/scrivito/string_tagging.rb +18 -0
  111. data/lib/scrivito/text_link.rb +52 -0
  112. data/lib/scrivito/text_link_conversion.rb +52 -0
  113. data/lib/scrivito/type_computer.rb +34 -0
  114. data/lib/scrivito/widget_field_params.rb +61 -0
  115. data/lib/scrivito/widget_garbage_collection.rb +97 -0
  116. data/lib/scrivito/workspace.rb +222 -0
  117. data/lib/scrivito/workspace_data_from_service.rb +80 -0
  118. data/lib/scrivito/workspace_selection_middleware.rb +23 -0
  119. data/lib/scrivito_sdk.rb +19 -0
  120. data/lib/tasks/cache.rake +12 -0
  121. data/lib/tasks/migration.rake +35 -0
  122. data/lib/widget.rb +3 -0
  123. metadata +291 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 24c7dcabf5aef63eb33bcdd0a13f588c3be4c524
4
+ data.tar.gz: 1461028fb468bed23183f63921081cb0560d213c
5
+ SHA512:
6
+ metadata.gz: 0251875fb48fdabcd26e4d0cef5e743218e8f4606c47cbc778a7d0bf02a83e278c3b3aafbc6ec647830c8b0c99e22abe32f6b8b6b2c01d794864596485317027
7
+ data.tar.gz: ebfe1320eaf24a181166a5d40620e31580ec4249795150da9a86ee2c4e6eb918e4fc3f6b58820254a25657cc56f34930d51d33c9cc1aa1502795024a52c0fea9
data/.yardopts ADDED
@@ -0,0 +1,5 @@
1
+ --hide-void-return
2
+ --protected
3
+ --private
4
+ --non-transitive-tag api
5
+ --api public
data/README ADDED
@@ -0,0 +1,6 @@
1
+ = Scrivito SDK
2
+
3
+ The Scrivito SDK makes CMS objects maintained by means of the cloud-based Scrivito CMS available to your Rails application.
4
+ It offers easy-to-use functionality for rendering CMS content, doing searches, etc.
5
+
6
+ For more information about Scrivito, please visit {http://scrivito.com/}.
@@ -0,0 +1,7 @@
1
+ # This controller inherits all of its behavior from
2
+ # {Scrivito::DefaultCmsController}.
3
+ #
4
+ # {CmsController} is referenced by the Scrivito routes.
5
+ # @api public
6
+ class CmsController < Scrivito::DefaultCmsController
7
+ end
@@ -0,0 +1,10 @@
1
+ module Scrivito
2
+
3
+ class BlobsController < WebserviceController
4
+ def upload_permission
5
+ permission = CmsRestApi.task_unaware_request(:get, 'blobs/upload_permission')
6
+ render json: permission
7
+ end
8
+ end
9
+
10
+ end
@@ -0,0 +1,61 @@
1
+ module Scrivito
2
+
3
+ # This controller provides some default includes ({CmsAccessible}),
4
+ # before filters (+load_object+, among others), and actions to simplify
5
+ # CMS object handling. It should never be used directly, but only as a
6
+ # super class to {CmsController}.
7
+ # @api public
8
+ class DefaultCmsController < ApplicationController
9
+ include CmsAccessible
10
+
11
+ before_filter :load_object
12
+ before_filter :authorize_editor, only: [:show_widget, :widget_details]
13
+
14
+ # Default Action. Delivers files directly if {BasicObj#binary?}.
15
+ # Otherwise the view is rendered.
16
+ # @api public
17
+ def index
18
+ deliver_file if @obj.binary?
19
+ end
20
+
21
+ def show_widget
22
+ widget = load_widget
23
+ render layout: false, locals: {widget: widget}
24
+ end
25
+
26
+ def widget_details
27
+ widget = load_widget
28
+ template_path = "#{widget.obj_class_name.underscore}/details"
29
+ render template_path, layout: false, locals: {widget: widget}
30
+ end
31
+
32
+ # This method indicates if this controller should be used automatically when an Obj is
33
+ # requested via the Scrivito's standard routes. It returns true by default.
34
+ #
35
+ # Overwrite it to return false if you do want your controller to be excluded from Obj dispatching.
36
+ #
37
+ # You may also implement a method with the name {use_for_obj_dispatch?} in controllers not
38
+ # descending from {DefaultCmsController} to include them in Obj dispatching.
39
+ #
40
+ # @see Obj#controller_name
41
+ # @api public
42
+ def self.use_for_obj_dispatch?
43
+ true
44
+ end
45
+
46
+ private
47
+
48
+ def authorize_editor
49
+ head(:forbidden) unless editing_context.authenticated_editor?
50
+ end
51
+
52
+ def editing_context
53
+ request.env[EditingContextMiddleware::ENVKEY] || EditingContext.new
54
+ end
55
+
56
+ def load_widget
57
+ @obj.widget_from_pool(params[:widget_id])
58
+ end
59
+ end
60
+
61
+ end
@@ -0,0 +1,200 @@
1
+ module Scrivito
2
+
3
+ class ObjsController < WebserviceController
4
+ before_filter :ensure_identical_selected_and_visible_workspace, only: [:create, :update, :copy,
5
+ :duplicate, :page_class_selection, :create_widget, :widget_class_selection, :copy_widget]
6
+
7
+ def create
8
+ created_obj = task_unaware_request(:post,
9
+ "workspaces/#{Workspace.current.id}/objs",
10
+ {obj: obj_params}
11
+ )
12
+ render json: created_obj
13
+ end
14
+
15
+ def details
16
+ load_object
17
+ render json: {markup: render_to_string(@obj.details_view_path, layout: false)}
18
+ end
19
+
20
+ def update
21
+ load_object
22
+ changed_obj = task_unaware_request(:put,
23
+ "workspaces/#{Workspace.current.id}/objs/#{params[:id]}",
24
+ {obj: obj_params}
25
+ )
26
+ render json: changed_obj
27
+ end
28
+
29
+ def destroy
30
+ in_selected_workspace { load_object.destroy }
31
+ render_empty_json
32
+ end
33
+
34
+ def revert
35
+ in_selected_workspace { load_object.revert }
36
+ render_empty_json
37
+ end
38
+
39
+ def restore
40
+ in_selected_workspace { Obj.restore(params[:id]) }
41
+ render_empty_json
42
+ end
43
+
44
+ def mark_resolved
45
+ in_selected_workspace { load_object.mark_resolved }
46
+ render_empty_json
47
+ end
48
+
49
+ def copy
50
+ render json: copy_obj(get_obj_attributes(params[:id]), params[:parent_path])
51
+ end
52
+
53
+ def duplicate
54
+ attributes = get_obj_attributes(params[:id])
55
+
56
+ render json: copy_obj(attributes, parent_path(attributes['_path']))
57
+ end
58
+
59
+ def page_class_selection
60
+ valid_page_classes = Obj.valid_page_classes_beneath(params[:parent_path]) ||
61
+ Obj.descendants
62
+ valid_page_classes.map!(&:to_s)
63
+
64
+ page_class_names = valid_page_classes.map do |page_class_name|
65
+ begin
66
+ markup = render_to_string("#{page_class_name.underscore}/thumbnail")
67
+ {name: page_class_name, markup: markup}
68
+ rescue ActionView::MissingTemplate
69
+ end
70
+ end
71
+
72
+ render json: page_class_names.compact
73
+ end
74
+
75
+ def widget_class_selection
76
+ load_object
77
+ valid_widget_classes = @obj.valid_widget_classes_for(params[:field_name]) ||
78
+ Widget.descendants
79
+ valid_widget_classes.map!(&:to_s)
80
+
81
+ widgets_classes = valid_widget_classes.map do |widget_class_name|
82
+ template_path = "#{widget_class_name.underscore}/thumbnail"
83
+ markup = begin
84
+ render_to_string(template_path, layout: false)
85
+ rescue ActionView::MissingTemplate
86
+ render_to_string('scrivito/widget_thumbnail', layout: false,
87
+ locals: {widget_class_name: widget_class_name, template_path: template_path})
88
+ end
89
+ {name: widget_class_name, markup: markup}
90
+ end
91
+
92
+ render json: widgets_classes
93
+ end
94
+
95
+ def create_widget
96
+ load_object
97
+ widget_pool_id = BasicObj.generate_widget_pool_id
98
+
99
+ task_unaware_request(:put, "workspaces/#{Workspace.current.id}/objs/#{params[:id]}",
100
+ {obj: {_widget_pool: {widget_pool_id => {_obj_class: params[:obj_class]}}}})
101
+
102
+ Workspace.reload
103
+ @obj.reload
104
+
105
+ @widget = @obj.widget_from_pool(widget_pool_id)
106
+
107
+ render json: {markup: render_to_string(layout: false)}
108
+ end
109
+
110
+ def copy_widget
111
+ load_object
112
+ new_widget_id = @obj.copy_widget_from(params[:src_obj_id], params[:src_widget_id])
113
+
114
+ Workspace.reload
115
+ @obj.reload
116
+
117
+ @widget = @obj.widget_from_pool(new_widget_id)
118
+
119
+ render json: {markup: render_to_string(layout: false)}
120
+ end
121
+
122
+ def search
123
+ in_selected_workspace do
124
+ query = MultiJson.decode(params[:query]).with_indifferent_access
125
+ search_builder = ObjSearchBuilder.new(query)
126
+ enumerator = search_builder.build
127
+
128
+ if params[:query_action] == 'size'
129
+ result = { total: enumerator.size }
130
+ else
131
+ batch = enumerator.load_batch
132
+
133
+ result = {
134
+ total: enumerator.size,
135
+ hits: batch
136
+ }
137
+ end
138
+
139
+ render json: result
140
+ end
141
+ rescue ObjSearchEnumerator::UnregisteredObjFormat => e
142
+ render json: { error: e.message }, status: :not_found
143
+ end
144
+
145
+ private
146
+
147
+ def load_object
148
+ @obj = Obj.find(params[:id])
149
+ end
150
+
151
+ def ensure_identical_selected_and_visible_workspace
152
+ if editing_context.selected_workspace != editing_context.visible_workspace
153
+ raise ScrivitoError, "selected and visible workspace are not identical"
154
+ end
155
+ end
156
+
157
+ def obj_params
158
+ @obj_params ||= ObjParamsParser.new(request.host, request.port).parse(@obj, params[:obj])
159
+ end
160
+
161
+ def copy_obj(attributes, target_path=nil)
162
+ copied_attributes = attributes.except!('id', '_id', '_permalink')
163
+ copied_attributes['_path'] = "#{target_path}/#{SecureRandom.hex(6)}"
164
+
165
+ task_unaware_request(:post, "workspaces/#{Workspace.current.id}/objs", obj: copied_attributes)
166
+ end
167
+
168
+ def get_obj_attributes(id)
169
+ task_unaware_request(:get, "workspaces/#{Workspace.current.id}/objs/#{id}")
170
+ end
171
+
172
+ def parent_path(path)
173
+ path.split('/')[0..-2].join('/')
174
+ end
175
+
176
+ def current_page
177
+ Obj.find(params[:current_page_id]) if params[:current_page_id].present?
178
+ end
179
+ helper_method :current_page
180
+
181
+ delegate :task_unaware_request, to: CmsRestApi
182
+
183
+ private
184
+
185
+ def editing_context
186
+ request.env[EditingContextMiddleware::ENVKEY] || EditingContext.new
187
+ end
188
+
189
+ def in_selected_workspace
190
+ editing_context.selected_workspace.as_current do
191
+ yield
192
+ end
193
+ end
194
+
195
+ def render_empty_json
196
+ render json: {}
197
+ end
198
+ end
199
+
200
+ end
@@ -0,0 +1,11 @@
1
+ module Scrivito
2
+
3
+ class TasksController < WebserviceController
4
+
5
+ def show
6
+ render json: CmsRestApi.task_unaware_request(:get, "tasks/#{params[:id]}")
7
+ end
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,36 @@
1
+ module Scrivito
2
+
3
+ class WebserviceController < ActionController::Base
4
+ rescue_from ClientError do |exception|
5
+ render json: {error: exception.message}, status: exception.http_code
6
+ end
7
+
8
+ before_filter :merge_correctly_parsed_json_params
9
+ before_filter :authorize
10
+
11
+ private
12
+
13
+ def authorize
14
+ unless allow_access?
15
+ render text: 'Forbidden', status: 403
16
+ end
17
+ end
18
+
19
+ # If +true+, allow access to ObjsController, else deny access.
20
+ # See {Scrivito::Configuration.editing_auth} for details.
21
+ # @return [Bool]
22
+ def allow_access?
23
+ Configuration.editing_auth_callback.call(request.env)
24
+ end
25
+
26
+ # Workaround for https://github.com/rails/rails/issues/8832
27
+ def merge_correctly_parsed_json_params
28
+ if request.format.json?
29
+ body = request.body.read
30
+ request.body.rewind
31
+ params.merge!(ActiveSupport::JSON.decode(body)) if body.present?
32
+ end
33
+ end
34
+ end
35
+
36
+ end
@@ -0,0 +1,41 @@
1
+ module Scrivito
2
+
3
+ class WorkspacesController < WebserviceController
4
+ def index
5
+ render json: CmsRestApi.task_unaware_request(:get, 'workspaces')
6
+ end
7
+
8
+ def create
9
+ render json: CmsRestApi.task_unaware_request(:post, 'workspaces', {
10
+ workspace: workspace_params,
11
+ })
12
+ end
13
+
14
+ def update
15
+ render json: CmsRestApi.task_unaware_request(:put, "workspaces/#{params[:id]}", {
16
+ workspace: workspace_params,
17
+ })
18
+ end
19
+
20
+ def destroy
21
+ render json: CmsRestApi.task_unaware_request(:delete, "workspaces/#{params[:id]}")
22
+ end
23
+
24
+ def publish
25
+ render json: CmsRestApi.task_unaware_request(:put, "workspaces/#{params[:id]}/publish", {})
26
+ end
27
+
28
+ def rebase
29
+ render json: CmsRestApi.task_unaware_request(:put, "workspaces/#{params[:id]}/rebase", {})
30
+ end
31
+
32
+ private
33
+
34
+ def workspace_params
35
+ raise "Required parameter 'workspace' is missing." unless params[:workspace].present?
36
+ raise "Parameter 'workspace' is not a hash." unless params[:workspace].is_a?(Hash)
37
+ params[:workspace]
38
+ end
39
+ end
40
+
41
+ end
@@ -0,0 +1,7 @@
1
+ # {CmsHelper} is a wrapper around {Scrivito::DefaultCmsHelper}.
2
+ # It can be replaced in your application in order to add or
3
+ # modify helpers.
4
+ # @api public
5
+ module CmsHelper
6
+ include Scrivito::DefaultCmsHelper
7
+ end
@@ -0,0 +1,7 @@
1
+ # {CmsRoutingHelper} is a wrapper around {Scrivito::DefaultCmsRoutingHelper}.
2
+ # It can be replaced in your application in order to add or
3
+ # modify helpers.
4
+ # @api public
5
+ module CmsRoutingHelper
6
+ include Scrivito::DefaultCmsRoutingHelper
7
+ end
@@ -0,0 +1,103 @@
1
+ module Scrivito
2
+
3
+ # This module contains helpers that can be used to reference images and other assets stored in the CMS.
4
+ #
5
+ # @api public
6
+ module CmsAssetHelper
7
+
8
+ # Calculates an HTML image tag for an image stored in the CMS.
9
+ #
10
+ # @note There are two different signatures of this method: the first one generates an HTML image tag with no
11
+ # inplace editing possible, the second one generated an HTML image tag for inplace editing.
12
+ #
13
+ # @overload cms_image_tag target, tag_options={}
14
+ # @note If you do not specify an HTML +alt+ attribute, the helper method will use +target+'s +display_title+.
15
+ # Calculates HTML image tag (no inplace editing possible).
16
+ #
17
+ # @param [Obj, Link] target Target containing image stored in CMS.
18
+ # @param [Hash] tag_options Additional HTML attributes for the tag.
19
+ #
20
+ # @example
21
+ # cms_image_tag @target
22
+ # cms_image_tag @target, alt: 'Interesting picture', class: 'my_image'
23
+ #
24
+ # @overload cms_image_tag obj, linklist, tag_options={}, editing_options={}
25
+ # @note If you do not specify an HTML +alt+ attribute, the helper method will use +display_title+ of the target object.
26
+ # Calculates HTML image tag for inplace editing.
27
+ #
28
+ # @param [Obj] obj Obj with an attribute of type +LinkList+.
29
+ # @param [String, Symbol] linklist Name of +LinkList+ attribute, which contains the image.
30
+ # @param [Hash] tag_options Additional HTML attributes for the tag.
31
+ #
32
+ # @param [Hash] editing_options Additional options for inplace editing.
33
+ # @option editing_options [String] :placeholder ('/assets/scrivito/image_placeholder.png') URL or path to image to be displayed if target is missing.
34
+ #
35
+ # @example
36
+ # cms_image_tag @obj, :my_linklist
37
+ # cms_image_tag @obj, :my_linklist, alt: 'Interesting picture', class: 'my_image'
38
+ # cms_image_tag @obj, :my_linklist, {}, placeholder: image_path('my_placeholder.png')
39
+ # cms_image_tag @obj, :my_linklist, {class: 'my_image'}, placeholder: 'http://placehold.it/350x150'
40
+ #
41
+ # @return [String] HTML image tag
42
+ # @api public
43
+ def cms_image_tag(*args)
44
+ if args.second.nil? || args.second.is_a?(Hash)
45
+ # Backwards compatibility.
46
+ target = args.first
47
+
48
+ tag_options = args.second || {}
49
+ tag_options.symbolize_keys!
50
+ tag_options[:src] = cms_path(target)
51
+ tag_options[:alt] ||= display_title(target)
52
+
53
+ tag('img', tag_options)
54
+ else
55
+ obj = args.first
56
+ field_name = args.second
57
+ tag_options = args.third || {}
58
+ editing_options = args.fourth || {}
59
+
60
+ cms_tag('img', obj, field_name, cms_image_tag_options(obj, field_name,
61
+ tag_options.symbolize_keys, editing_options.symbolize_keys))
62
+ end
63
+
64
+ end
65
+
66
+ private
67
+
68
+ def cms_image_tag_options(obj, field_name, tag_options, editing_options)
69
+ tag_options.reverse_merge(src: cms_image_tag_src(obj, field_name, editing_options),
70
+ alt: cms_image_tag_alt(obj, field_name))
71
+ end
72
+
73
+ def cms_image_tag_src(obj, field_name, editing_options)
74
+ cms_image_tag_path(obj, field_name) || editing_options[:placeholder] ||
75
+ image_path('scrivito/image_placeholder.png')
76
+ end
77
+
78
+ def cms_image_tag_alt(obj, field_name)
79
+ display_title(obj[field_name])
80
+ end
81
+
82
+ def cms_image_tag_path(obj, field_name)
83
+ field_type = obj.type_of_attribute(field_name)
84
+ field_value = obj[field_name]
85
+
86
+ case field_type
87
+ when 'reference' then field_value && cms_path(field_value)
88
+ when 'linklist'
89
+ path = cms_path(field_value)
90
+ path == DefaultCmsRoutingHelper::LINK_TO_EMPTY_LINKLIST ? nil : path
91
+ end
92
+ end
93
+
94
+ def display_title(target)
95
+ if target.respond_to?(:display_title)
96
+ return target.display_title
97
+ elsif target.respond_to?(:first) && target.first.respond_to?(:display_title)
98
+ return target.first.display_title
99
+ end
100
+ end
101
+
102
+ end
103
+ end