infopark_fiona_connector 6.9.4 → 6.10.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +7 -0
  2. data/app/assets/images/admin/minus.gif +0 -0
  3. data/app/assets/images/bg80.png +0 -0
  4. data/app/assets/images/edit.png +0 -0
  5. data/app/assets/images/icons/mm_generic.png +0 -0
  6. data/app/assets/images/icons/mm_menu.png +0 -0
  7. data/app/assets/javascripts/editmarker.js +240 -0
  8. data/app/assets/javascripts/infopark_rails_connector.js.erb +0 -0
  9. data/app/assets/stylesheets/editmarker.css +70 -0
  10. data/app/assets/stylesheets/infopark_rails_connector.css.erb +0 -0
  11. data/app/controllers/cms_controller.rb +7 -0
  12. data/app/controllers/rails_connector/default_cms_controller.rb +43 -0
  13. data/app/helpers/cms_helper.rb +7 -0
  14. data/app/helpers/cms_routing_helper.rb +7 -0
  15. data/app/helpers/rails_connector/cms_asset_helper.rb +2 -1
  16. data/app/helpers/rails_connector/default_cms_helper.rb +23 -0
  17. data/app/helpers/rails_connector/default_cms_routing_helper.rb +120 -0
  18. data/app/helpers/rails_connector/layout_helper.rb +29 -0
  19. data/app/helpers/rails_connector/marker_helper.rb +1 -3
  20. data/app/helpers/rails_connector/table_of_contents_helper.rb +22 -0
  21. data/app/models/named_link.rb +2 -0
  22. data/app/views/cms/_index.html.erb +7 -0
  23. data/app/views/cms/index.html.erb +1 -0
  24. data/app/views/errors/403_forbidden.html.erb +3 -0
  25. data/app/views/errors/410_gone.html.erb +7 -0
  26. data/config/cms_routes.rb +17 -0
  27. data/config/locales/de.rails_connector.errors.yml +11 -0
  28. data/config/locales/de.rails_connector.lib.yml +6 -0
  29. data/config/locales/de.rails_connector.views.yml +9 -0
  30. data/config/locales/en.rails_connector.errors.yml +10 -0
  31. data/config/locales/en.rails_connector.lib.yml +6 -0
  32. data/config/locales/en.rails_connector.views.yml +9 -0
  33. data/lib/gem_dependencies.rb +67 -0
  34. data/lib/infopark_fiona_connector.rb +22 -0
  35. data/lib/obj.rb +3 -0
  36. data/lib/rails_connector/authenticable.rb +30 -0
  37. data/lib/rails_connector/basic_obj.rb +2 -2
  38. data/lib/rails_connector/blob.rb +2 -4
  39. data/lib/rails_connector/blob_mysql.rb +1 -1
  40. data/lib/rails_connector/blob_oracle.rb +1 -1
  41. data/lib/rails_connector/cms_accessible.rb +114 -0
  42. data/lib/rails_connector/cms_dispatch_controller.rb +46 -0
  43. data/lib/rails_connector/cms_env.rb +68 -0
  44. data/lib/rails_connector/cms_test_request.rb +23 -0
  45. data/lib/rails_connector/core_extensions.rb +1 -0
  46. data/lib/rails_connector/core_extensions/time.rb +18 -0
  47. data/lib/rails_connector/engine.rb +64 -0
  48. data/lib/rails_connector/html_string.rb +19 -0
  49. data/lib/rails_connector/link_list.rb +32 -0
  50. data/lib/rails_connector/link_resolvable.rb +9 -0
  51. data/lib/rails_connector/markdown_string.rb +19 -0
  52. data/lib/rails_connector/named_link.rb +1 -1
  53. data/lib/rails_connector/string_tagging.rb +29 -0
  54. data/lib/version.rb +7 -0
  55. metadata +155 -35
  56. data/README +0 -5
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ddab05f9afaf1ac1c000b4b6370a2a794b98db7e
4
+ data.tar.gz: 0748acba4d1558e4d46a6df79119807312452799
5
+ SHA512:
6
+ metadata.gz: 4d60a31b3d4709d8e9eacb2c9eafec5618b100e32e87de91845c1152c66968d47451593029637bdd6b46316e739817623f1b061d5dad764f7e3b621b12b527f7
7
+ data.tar.gz: 7f8a61863b2885eb53ab5ac5ba65a130e0fdc204d8986a73c1f8bad9532bd18bbac1ca6a95a3231ed1da8c930b8f3a8ef3f4da0a1d15bc59d1d7a7098606a9e8
@@ -0,0 +1,240 @@
1
+ var inline_editing = (function() {
2
+
3
+ /********************************************************************************************/
4
+ /* Global vars */
5
+ var prevElement = false;
6
+ var actionMarkerVisible = true;
7
+ var actionMarkerArray;
8
+ var rememberBackgroundColor;
9
+ var rememberZoom;
10
+ var editMarkerDefinitions;
11
+ var parentWindow = parent;
12
+
13
+ /********************************************************************************************/
14
+ /* Global Functions */
15
+
16
+ var findInfoFromClassName = function(element, regexp) {
17
+ var info;
18
+ var matches = (jQuery(element).attr("class") || "").match(regexp);
19
+ if (matches && matches.length > 1) {
20
+ return matches[1];
21
+ }
22
+ };
23
+
24
+ /****************************************/
25
+ /* Hilfsfunktionen für die Hervorhebung */
26
+
27
+ var stashStyle = function(element)
28
+ {
29
+ var nps_style_stash = {};
30
+ jQuery.each(['backgroundColor', 'zoom', 'color'], function(i, property) {
31
+ nps_style_stash[property] = element.css(property);
32
+ });
33
+ element.data('nps_style_stash', nps_style_stash);
34
+ };
35
+
36
+ var highlight = function(element)
37
+ {
38
+ // setting the zoom works around incomplete redraws on ie6
39
+ element.css({
40
+ backgroundColor: '#ffffaa',
41
+ zoom: 1,
42
+ color: '#000000'
43
+ });
44
+ };
45
+
46
+ var unstashStyle = function(element)
47
+ {
48
+ if (element.data('nps_style_stash')) {
49
+ element.css(element.data('nps_style_stash'));
50
+ element.removeData('nps_style_stash');
51
+ }
52
+ };
53
+
54
+ /********************************************************************************************/
55
+ /* Marker Definitions */
56
+
57
+ /********************************************************************************************/
58
+ /* Marker Permission Checking */
59
+
60
+ var that = {
61
+ setParentWindow: function(new_parent) {
62
+ parentWindow = new_parent;
63
+ },
64
+
65
+ attachMarkerMenu: function(marker_menu_target){
66
+ var id = findInfoFromClassName(marker_menu_target, /nps_marker_menu_target_([0-9]+)/);
67
+ var marker_menu = jQuery("#nps_marker_menu_"+id);
68
+ if (marker_menu.length) {
69
+ var definition = that.findMarkerDefinitionForElement(marker_menu);
70
+ var target_pos = marker_menu_target.offset();
71
+ var parent_pos = marker_menu.offsetParent().offset();
72
+
73
+ marker_menu.css({
74
+ position: 'absolute',
75
+ left: target_pos.left + definition.offset_left - parent_pos.left,
76
+ top: target_pos.top + definition.offset_top - parent_pos.top
77
+ });
78
+
79
+ jQuery(marker_menu).unbind('mouseenter');
80
+ jQuery(marker_menu).mouseenter(function(){
81
+ stashStyle(marker_menu_target);
82
+ highlight(marker_menu_target);
83
+ });
84
+ jQuery(marker_menu).unbind('mouseleave');
85
+ jQuery(marker_menu).mouseleave(function(){
86
+ unstashStyle(marker_menu_target);
87
+ });
88
+ }
89
+ },
90
+
91
+ initMarkerMenus: function() {
92
+ var visible = false;
93
+ jQuery('.nps_marker_menu_button').click(function() {
94
+ if (visible) {
95
+ jQuery(this).next().slideUp(200);
96
+ visible = false;
97
+ } else {
98
+ jQuery(this).next().slideDown(200);
99
+ visible = true;
100
+ }
101
+ return false;
102
+ });
103
+ },
104
+
105
+ attachMarkerMenus: function() {
106
+ jQuery('.nps_marker_menu_target').each(function() {
107
+ that.attachMarkerMenu(jQuery(this));
108
+ });
109
+ },
110
+
111
+ initActionMarker: function() {
112
+ jQuery('.nps_action_marker').each(function(ignore, marker_element) {
113
+ if (!that.hasRequiredPermissionsForMarkerElement(marker_element)) {
114
+ jQuery(marker_element).hide();
115
+ }
116
+ });
117
+ },
118
+
119
+ bindEditMarkerEvents: function(marker, target){
120
+ marker.unbind();
121
+ marker.mouseenter(function() {
122
+ target.find("*").each(function() { stashStyle(jQuery(this)); });
123
+ target.find("*").each(function() { highlight(jQuery(this)); });
124
+ stashStyle(target);
125
+ highlight(target);
126
+ });
127
+ marker.mouseleave(function() {
128
+ target.find("*").each(function() { unstashStyle(jQuery(this)); });
129
+ unstashStyle(target);
130
+ });
131
+ marker.click(function() { return that.startEditing(this); });
132
+ },
133
+
134
+ initEditMarker: function() {
135
+ // add functions and behaviour to all edit marker elements
136
+ jQuery(".nps_edit_marker").each(function(i, marker) {
137
+ marker = jQuery(marker);
138
+ if (that.hasRequiredPermissionsForMarkerElement(marker)) {
139
+ var id = findInfoFromClassName(marker, /nps_marker_id_([0-9]+)/);
140
+ var target = jQuery("#nps_marker_id_" + id);
141
+ if (target.length) {
142
+ var pos = target.offset();
143
+ var parent_pos = marker.offsetParent().offset();
144
+ that.bindEditMarkerEvents(marker, target);
145
+ marker.css({
146
+ left: pos.left - parent_pos.left,
147
+ top: pos.top - parent_pos.top,
148
+ position: "absolute",
149
+ display: "inline"
150
+ });
151
+ } else {
152
+ marker.hide();
153
+ }
154
+ }
155
+ else {
156
+ marker.hide();
157
+ }
158
+ });
159
+ },
160
+
161
+ openEditDialog: function(obj_id, attribute, context_id, size, target) {
162
+ // pass control to Fiona GUI
163
+ parentWindow.openEditDialog(obj_id, attribute, context_id, size, target);
164
+ },
165
+
166
+ initMarker: function() {
167
+ that.initEditMarker();
168
+ that.initActionMarker();
169
+ that.initMarkerMenus();
170
+ that.attachMarkerMenus();
171
+ },
172
+
173
+ init: function() {
174
+ jQuery(document).ready(that.initMarker);
175
+ jQuery(window).load(that.initMarker);
176
+ jQuery(window).resize(that.initMarker);
177
+ },
178
+
179
+ storeMarkerDefinitions: function(definitions) {
180
+ editMarkerDefinitions = editMarkerDefinitions || {};
181
+ jQuery.extend(editMarkerDefinitions, definitions);
182
+ },
183
+
184
+ markerDefinition: function(id) {
185
+ return editMarkerDefinitions[id];
186
+ },
187
+
188
+ findMarkerDefinitionForElement: function(element) {
189
+ return that.markerDefinition(findInfoFromClassName(element, /nps_marker_id_([0-9]+)/));
190
+ },
191
+
192
+ currentUserHasGlobalPermission: function(perm) {
193
+ if (parentWindow.currentUserIsMemberOf) {
194
+ return parentWindow.currentUserHasGlobalPermission(perm);
195
+ }
196
+ else {
197
+ return true;
198
+ }
199
+ },
200
+
201
+ currentUserIsMemberOf: function(groups) {
202
+ if (parentWindow.currentUserIsMemberOf) {
203
+ return parentWindow.currentUserIsMemberOf(groups);
204
+ }
205
+ else {
206
+ return true;
207
+ }
208
+ },
209
+
210
+ hasRequiredPermissionsForMarkerElement: function(element) {
211
+ if (that.currentUserHasGlobalPermission("permissionGlobalRoot")) { return true; }
212
+
213
+ var definition = that.findMarkerDefinitionForElement(element);
214
+ var member_in_group = 0;
215
+ jQuery.each(definition.memberships, function() {
216
+ if (that.currentUserIsMemberOf(this)) {
217
+ member_in_group += 1;
218
+ return true;
219
+ }
220
+ return false;
221
+ });
222
+ return member_in_group === definition.memberships.length;
223
+ },
224
+
225
+ startEditing: function(element) {
226
+ var definition = that.findMarkerDefinitionForElement(element);
227
+
228
+ // pass control to Fiona GUI
229
+ that.openEditDialog(
230
+ definition.obj_id, definition.attribute, definition.context_id,
231
+ definition.size, definition.target
232
+ );
233
+ return false;
234
+ }
235
+
236
+ };
237
+
238
+ return that;
239
+
240
+ }());
@@ -0,0 +1,70 @@
1
+ @charset "UTF-8";
2
+
3
+ /*** Edit Marker ***/
4
+ a.nps_edit_marker {
5
+ -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
6
+ filter: alpha(opacity=50);
7
+ }
8
+ a.nps_edit_marker:hover,a.nps_edit_marker:active {
9
+ -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
10
+ filter: alpha(opacity=100);
11
+ }
12
+
13
+ a.nps_edit_marker {
14
+ background-color: transparent;
15
+ display:none;
16
+ background:url(edit.png) 0 0 no-repeat;
17
+ min-width:16px;
18
+ min-height:16px;
19
+ z-index: 1000;
20
+ position:absolute;
21
+ opacity:0.3;
22
+ }
23
+ a.nps_edit_marker:hover,a.nps_edit_marker:active {opacity:1;}
24
+
25
+ /*** Marker Menu ***/
26
+ .nps_marker_menu {
27
+ position:absolute;
28
+ z-index:10000;
29
+ display:block;
30
+ /*** IE 6-7 braucht leider eine Breitenangabe***/
31
+ width:200px;
32
+ }
33
+
34
+
35
+ /*** Marker Menu Transparenz IE 6 ***/
36
+ * html .nps_marker_menu div.core { filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='bg80.png', sizingMethod='scale');}
37
+
38
+ /*** Marker Menu Button Transparenz IE ***/
39
+ a.nps_marker_menu_button {
40
+ -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
41
+ filter: alpha(opacity=50);
42
+ }
43
+ a.nps_marker_menu_button:hover,a.nps_marker_menu_button:active {
44
+ -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
45
+ filter: alpha(opacity=100);
46
+ }
47
+
48
+ a.nps_marker_menu_button {display: block; text-align:left;text-indent:-1000em; width: 100%; height: 16px; background: transparent url(icons/mm_menu.png) 0 0 no-repeat;opacity:0.3;}
49
+ a.nps_marker_menu_button:hover,a.nps_marker_menu_button:active {opacity:1;}
50
+
51
+ .nps_marker_menu div.b1,
52
+ .nps_marker_menu div.b2,
53
+ .nps_marker_menu div.b3,
54
+ .nps_marker_menu div.b4 { background:url(bg80.png) 0 0 repeat; display:block;padding:0;overflow:hidden;font-size:1px;}
55
+ .nps_marker_menu div.b1 { margin:0pt 5px; height:1px;}
56
+ .nps_marker_menu div.b2 { margin:0pt 3px; height:1px;}
57
+ .nps_marker_menu div.b3 { margin:0pt 2px; height:1px;}
58
+ .nps_marker_menu div.b4 { margin:0pt 1px; height:2px;}
59
+
60
+ .nps_marker_menu_content div.core {background:url(bg80.png) 0 0 repeat; text-align:left;color:#fff;}
61
+ .nps_marker_menu_content div.core p{padding:0 5px; text-align:left;color:#fff;}
62
+
63
+ .nps_marker_menu ul { display:block; margin:0; padding:0;}
64
+ .nps_marker_menu ul li {padding:3px 1px; margin:0; line-height: 20px; list-style-type:none; list-style-image:none;}
65
+ .nps_marker_menu ul li a {display:block; color:#fff; font-weight:bold;}
66
+ .nps_marker_menu ul li a:hover,
67
+ .nps_marker_menu ul li a:active { background-color: #777; text-decoration:none; color:#fff; }
68
+ .nps_marker_menu ul li a:focus { text-decoration:none; color:#fff; }
69
+
70
+ .nps_marker_menu ul li a span {padding: 0 6px 0 30px;display: block; text-align: left; background: transparent url(icons/mm_generic.png) 7px 2px no-repeat;}
@@ -0,0 +1,7 @@
1
+ # This controller inherits all of its behavior from
2
+ # {RailsConnector::DefaultCmsController}.
3
+ #
4
+ # {CmsController} is referenced by the Rails Connector routes.
5
+ # @api public
6
+ class CmsController < RailsConnector::DefaultCmsController
7
+ end
@@ -0,0 +1,43 @@
1
+ module RailsConnector
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
+ before_filter :load_object
11
+ before_filter :ensure_object_is_active
12
+ before_filter :ensure_object_is_permitted
13
+ before_filter :set_google_expire_header
14
+
15
+ # Default Action. Delivers files directly if their mime type is not text/html
16
+ # @api public
17
+ def index
18
+ deliver_file if @obj.mime_type != "text/html"
19
+ end
20
+
21
+ # Toggles edit markers. The current status is stored in the session.
22
+ # @api public
23
+ def toggle_editmarkers
24
+ session[:hide_editmarkers] = !session[:hide_editmarkers]
25
+ redirect_to cms_id_url(@obj)
26
+ end
27
+
28
+ # This method indicates if this controller should be used automatically when an Obj is
29
+ # requested via the Rails Connector's standard routes. It returns true by default.
30
+ #
31
+ # Overwrite it to return false if you do want your controller to be excluded from Obj dispatching.
32
+ #
33
+ # You may also implement a method with the name {use_for_obj_dispatch?} in controllers not
34
+ # descending from {DefaultCmsController} to include them in Obj dispatching.
35
+ #
36
+ # @see Obj#controller_name
37
+ # @api public
38
+ def self.use_for_obj_dispatch?
39
+ true
40
+ end
41
+ end
42
+
43
+ end
@@ -0,0 +1,7 @@
1
+ # {CmsHelper} is a wrapper around {RailsConnector::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 RailsConnector::DefaultCmsHelper
7
+ end
@@ -0,0 +1,7 @@
1
+ # {CmsRoutingHelper} is a wrapper around {RailsConnector::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 RailsConnector::DefaultCmsRoutingHelper
7
+ end
@@ -7,6 +7,7 @@ module RailsConnector
7
7
  # If your application does not use any asset hosts, the helper will generate regular (=non asset host) pathes.
8
8
  # @api public
9
9
  module CmsAssetHelper
10
+ include ActionView::Helpers::AssetUrlHelper
10
11
 
11
12
  # Returns an html image tag for an image stored in the CMS.
12
13
  #
@@ -37,7 +38,7 @@ module RailsConnector
37
38
  def cms_asset_path(target)
38
39
  regular_path = cms_path(target)
39
40
  return regular_path if regular_path.first == "#"
40
- asset_paths.compute_public_path(regular_path, nil)
41
+ asset_path(regular_path)
41
42
  end
42
43
 
43
44
  private
@@ -0,0 +1,23 @@
1
+ module RailsConnector
2
+
3
+ # This is a wrapper module for the default set of Rails Connector helper modules.
4
+ #
5
+ # To make autoloading from +CmsController+ work, this module must be wrapped
6
+ # by a module named +CmsHelper+:
7
+ #
8
+ # module CmsHelper
9
+ # include RailsConnector::DefaultCmsHelper
10
+ # end
11
+ # @api public
12
+ module DefaultCmsHelper
13
+ include DisplayHelper
14
+ include MarkerHelper
15
+ include CmsAssetHelper
16
+ include RailsConnector::CmsAssetHelper
17
+ include RailsConnector::TableOfContentsHelper
18
+ include RailsConnector::EditingHelper
19
+ include RailsConnector::LayoutHelper
20
+ include RailsConnector::CmsTagHelper
21
+ end
22
+
23
+ end
@@ -0,0 +1,120 @@
1
+ module RailsConnector
2
+
3
+ # @api public
4
+ module DefaultCmsRoutingHelper
5
+ # Returns the path for +target+ using the +CmsController+ routes.
6
+ # +target+ can be an +Obj+ or a +Link+ or a +LinkList+.
7
+ # If +target+ is a +Linklist+, it must be non-empty. The first +Link+ from the +LinkList+ will be used.
8
+ # +options+ are optional and include url settings such as path parameters or protocol.
9
+ # @return [String]
10
+ # @api public
11
+ def cms_path(target, options = {})
12
+ cms_path_or_url(target, "path", options)
13
+ end
14
+
15
+ # Returns the absolute URL for target using the +CmsController+ routes.
16
+ # +target+ can be an +Obj+ or a +Link+ or a +LinkList+.
17
+ # If +target+ is a +Linklist+, it must be non-empty. The first +Link+ from the +LinkList+ will be used.
18
+ # +options+ are optional and include url settings such as path parameters or protocol.
19
+ # @return [String]
20
+ # @api public
21
+ def cms_url(target, options = {})
22
+ cms_path_or_url(target, "url", options)
23
+ end
24
+
25
+ LINK_TO_UNREACHABLE = "#__target_object_not_reachable"
26
+ LINK_TO_EMPTY_LINKLIST = "#__empty_linklist"
27
+
28
+ def cms_path_or_url(target, path_or_url, options = {})
29
+ if target.is_a?(Link)
30
+ cms_path_or_url_for_links(target, path_or_url, options)
31
+ elsif target.is_a?(Obj)
32
+ cms_path_or_url_for_objs(target, path_or_url, options)
33
+ elsif target.respond_to?(:first)
34
+ if target.first.is_a?(Link)
35
+ cms_path_or_url_for_links(target.first, path_or_url, options)
36
+ else
37
+ return LINK_TO_EMPTY_LINKLIST
38
+ end
39
+ else
40
+ raise "cms_path or cms_url was called with an instance of #{target.class}. "+
41
+ "It must only be called with an Obj or a Link or a non-empty LinkList."
42
+ end
43
+ end
44
+
45
+ def cms_path_or_url_for_links(link, path_or_url, options = {})
46
+ return LINK_TO_UNREACHABLE if link.internal? && link.destination_object.nil?
47
+ url = basic_url_or_path_for_link(link, path_or_url, options)
48
+ url = append_search(url, link) if options.empty?
49
+
50
+ append_fragment(url, link)
51
+ end
52
+
53
+ def cms_path_or_url_for_objs(obj, path_or_url, options = {})
54
+ permalink = obj.permalink
55
+ ignore_body_data_url = options.delete(:ignore_body_data_url)
56
+ if permalink && !Configuration.editor_interface_enabled?
57
+ __send__("cms_permalink_#{path_or_url}", options.merge(:permalink => permalink))
58
+ elsif obj.homepage? && !Configuration.editor_interface_enabled?
59
+ __send__("root_#{path_or_url}", options)
60
+ else
61
+ if obj.body_data_url && !ignore_body_data_url
62
+ enforce_protocol_from_request(obj.body_data_url)
63
+ elsif obj.binary? && !obj.file_extension.blank?
64
+ __send__("cms_id_#{path_or_url}",
65
+ options.merge(:id => obj.id, :slug => obj.slug.presence, :format => obj.file_extension))
66
+ else
67
+ routing_options = options.merge(:id => obj.id, :slug => obj.slug.presence)
68
+ __send__("cms_id_#{path_or_url}", routing_options)
69
+ end
70
+ end
71
+ end
72
+
73
+ private
74
+
75
+ def basic_url_or_path_for_link(link, path_or_url, options = {})
76
+ if link.internal?
77
+ __send__("cms_#{path_or_url}", link.destination_object, options)
78
+ else
79
+ if link.external_prefix?
80
+ url = remove_external_prefix(link.url)
81
+ else
82
+ url = link.url
83
+ end
84
+
85
+ options.delete(:ignore_body_data_url)
86
+ url = merge_options(url, options) if options.any?
87
+ url
88
+ end
89
+ end
90
+
91
+ def remove_external_prefix(link)
92
+ link.gsub(/external:/, "").strip
93
+ end
94
+
95
+ def append_search(url, link)
96
+ url += "?#{link.search}" unless link.search.blank?
97
+ url
98
+ end
99
+
100
+ def append_fragment(url, link)
101
+ url += "##{link.fragment}" unless link.fragment.blank?
102
+ url
103
+ end
104
+
105
+ def merge_options(url, options)
106
+ parsed_url = URI.parse(url)
107
+
108
+ search = Rack::Utils.parse_query(parsed_url.query)
109
+ merged_search = search.merge(options.stringify_keys)
110
+ parsed_url.query = merged_search.to_query
111
+
112
+ parsed_url.to_s
113
+ end
114
+
115
+ def enforce_protocol_from_request(url)
116
+ request.ssl? && !url.starts_with?('https') ? url.gsub(/^http/, 'https') : url
117
+ end
118
+
119
+ end
120
+ end