Module: ApplicationHelper
- Includes:
- IconHelper, Memery, UppyUploaderHelper, UrlsHelper, Www::ImagesHelper, Www::SeoHelper
- Included in:
- ApplicationController, SimpleController, VideoPlayerComponent, Www::AddToCartButtonComponent, Www::AssociationsSliderComponent, Www::BlogProductEmbedComponent, Www::CarouselSliderComponent, Www::CustomMatsPresenter, Www::HomepageProductsComponent, Www::ProductCardComponent, Www::ProductCatalogPresenter, Www::ProductLinePresenter, Www::TowelWarmersPresenter, Www::VideoCardComponent
- Defined in:
- app/helpers/application_helper.rb
Constant Summary
Www::SeoHelper::AWARDS, Www::SeoHelper::CA_ADDRESS, Www::SeoHelper::CA_BUSINESS_HOURS, Www::SeoHelper::CA_CONTACT_POINT, Www::SeoHelper::CA_CURRENCIES, Www::SeoHelper::CA_DESCRIPTION, Www::SeoHelper::CA_FOUNDING_DATE, Www::SeoHelper::CA_GLOBAL_LOCATION_NUMBER, Www::SeoHelper::CA_LEGAL_NAME, Www::SeoHelper::CA_LOCAL_BUSINESS, Www::SeoHelper::CA_ONLINE_STORE, Www::SeoHelper::CA_RETURN_POLICY, Www::SeoHelper::CA_SALES_DEPARTMENT, Www::SeoHelper::CA_SERVICE_AREA, Www::SeoHelper::CA_URL, Www::SeoHelper::CA_VAT_ID, Www::SeoHelper::CA_WAREHOUSE_DEPARTMENT, Www::SeoHelper::CA_WAREHOUSE_HOURS, Www::SeoHelper::COMPANY_EMAIL, Www::SeoHelper::COMPANY_LOGO, Www::SeoHelper::COMPANY_NAME, Www::SeoHelper::COMPANY_SLOGAN, Www::SeoHelper::EXPERTISE, Www::SeoHelper::FAX_NUMBER, Www::SeoHelper::GS1_COMPANY_PREFIX, Www::SeoHelper::ISO6523_CODE, Www::SeoHelper::PAYMENT_METHODS, Www::SeoHelper::PHONE_NUMBER, Www::SeoHelper::PRIMARY_NAICS, Www::SeoHelper::REFUND_TYPE, Www::SeoHelper::RETURN_FEES, Www::SeoHelper::RETURN_METHOD, Www::SeoHelper::RETURN_POLICY_CATEGORY, Www::SeoHelper::SECONDARY_NAICS, Www::SeoHelper::SOCIAL_PROFILES, Www::SeoHelper::US_ADDRESS, Www::SeoHelper::US_BUSINESS_HOURS, Www::SeoHelper::US_CONTACT_POINT, Www::SeoHelper::US_CURRENCIES, Www::SeoHelper::US_DESCRIPTION, Www::SeoHelper::US_FOUNDING_DATE, Www::SeoHelper::US_GLOBAL_LOCATION_NUMBER, Www::SeoHelper::US_IMAGE, Www::SeoHelper::US_LEGAL_NAME, Www::SeoHelper::US_LOCAL_BUSINESS, Www::SeoHelper::US_ONLINE_STORE, Www::SeoHelper::US_RETURN_POLICY, Www::SeoHelper::US_SALES_DEPARTMENT, Www::SeoHelper::US_SERVICE_AREA, Www::SeoHelper::US_TAX_ID, Www::SeoHelper::US_URL, Www::SeoHelper::US_WAREHOUSE_DEPARTMENT, Www::SeoHelper::US_WAREHOUSE_HOURS
Constants included
from IconHelper
IconHelper::CUSTOM_ICON_MAP, IconHelper::CUSTOM_SVG_DIR, IconHelper::DEFAULT_FAMILY
Instance Method Summary
collapse
-
#better_number_to_currency(number, options = {}) ⇒ Object
-
#check_force_logout ⇒ Object
-
#check_or_cross(value, options = {}) ⇒ Object
Truthy = green check mark other wise red stop.
-
#check_or_times(value, _options = {}) ⇒ Object
-
#error_messages(object) ⇒ Object
-
#general_disclaimer_on_product_installation_and_local_codes ⇒ Object
-
#gridjs_from_html_table(table_id, **options) ⇒ Object
-
#gridjs_table(id, data: nil, columns: nil, **options) ⇒ Object
Grid.js helper methods for modern table functionality.
-
#is_wy_ip ⇒ Object
-
#line_break(string, compact = false) ⇒ Object
-
#parent_layout(layout) ⇒ Object
-
#pass_or_fail(result) ⇒ Object
-
#render_error_messages_list(object) ⇒ Object
-
#render_video_card(video, layout: 'card', card_style: 'default', hide_title: false, hide_description: false, display_category_badge: false, display_duration: false, show_popup: true, show_direct_link: true, styles: '') ⇒ Object
Helper method to render video cards with consistent options.
-
#resolved_auth_form_turbo_frame(turbo_frame: RESOLVED_AUTH_FRAME_UNSET) ⇒ Object
-
#return_path_or(default) ⇒ Object
Returns @return_path (set by Controllers::ReturnPathHandling) when present, otherwise falls back to the supplied default.
-
#safe_css_color(color) ⇒ Object
Validates a CSS color value against safe patterns (hex codes and named colors).
-
#set_return_path_if_present(return_path: @return_path, return_title: nil) ⇒ Object
-
#set_section_if_present ⇒ Object
-
#tab_frame_id ⇒ Object
Per-controller frame ID so cross-page links inside tabs trigger turbo:frame-missing instead of silently swapping the wrong page's tab shell.
-
#to_underscore(term) ⇒ Object
-
#track_page? ⇒ Boolean
-
#turbo_section_wrapper(id: nil, class_names: nil) ⇒ Object
Enable Turbo functionality for specific sections without affecting the entire page.
-
#turbo_tabs_request? ⇒ Boolean
-
#url_on_same_domain_as_request(path) ⇒ Object
-
#widget_index_daily_focus_index_path ⇒ Object
AppSignal #2131: legacy references used widget_index_daily_focus_index_path; the route helper from resources :daily_focus collection widget_index is widget_index_daily_focus_path.
-
#working_hours? ⇒ Boolean
-
#yes_or_no(value) ⇒ Object
-
#yes_or_no_highlighted(b, reverse_check = false) ⇒ Object
-
#yes_or_no_with_check_or_cross(b, reverse_check = false) ⇒ Object
-
#youtube_video(url) ⇒ Object
#file_uploader, #image_uploader, #large_file_uploader_s3, #lead_sketch_uploader, #rma_image_uploader, #rma_image_uploader_s3, #uppy_uploader, #video_uploader
#image_asset_tag, #image_asset_url
#add_page_schema, #canada?, #company_social_links, #ensure_context_json, #json_ld_script_tag, #local_business_schema, #online_store_id, #online_store_schema, #page_main_entity, #page_main_entity_json, #render_auto_collection_page_schema, #render_collection_page_schema, #render_local_business_schema, #render_online_store_schema, #render_page_schemas, #render_page_video_schemas, #render_webpage_schema, #render_webpage_schema_with_collections, #usa?
Methods included from UrlsHelper
#catalog_breadcrumb_links, #catalog_link, #catalog_link_for_product_line, #catalog_link_for_sku, #cms_link, #delocalized_path, #path_to_sales_product_sku, #path_to_sales_product_sku_for_product_line, #path_to_sales_product_sku_for_product_line_slug, #product_line_from_catalog_link, #protocol_neutral_url, #sanitize_external_url, #valid_external_url?
Methods included from IconHelper
#account_nav_icon, #fa_icon, #star_rating_html
Instance Method Details
#better_number_to_currency(number, options = {}) ⇒ Object
94
95
96
97
98
99
|
# File 'app/helpers/application_helper.rb', line 94
def better_number_to_currency(number, options = {})
return unless number
strip_insignificant_zeros = ((number * 100) % 100).zero? number_to_currency(number, options.merge(strip_insignificant_zeros:, precision: 2))
end
|
#check_force_logout ⇒ Object
243
244
245
246
247
248
249
|
# File 'app/helpers/application_helper.rb', line 243
def check_force_logout
return unless current_user && current_user.force_logout?
current_user.update_column(:force_logout, false)
sign_out(current_user.account)
redirect_to request.original_url and return true
end
|
#check_or_cross(value, options = {}) ⇒ Object
Truthy = green check mark other wise red stop
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
# File 'app/helpers/application_helper.rb', line 120
def check_or_cross(value, options = {})
if value.to_b
options[:title] = 'Yes'
options[:class] ||= 'text-green'
options[:style] ||= 'color:green;font-size:1.2em'
check_icon = options.delete(:check_icon) || 'check-circle'
fa_icon(check_icon, **options)
else
options[:title] = 'No'
options[:class] ||= 'text-red'
options[:style] ||= 'color:red;font-size:1.2em'
cross_icon = options.delete(:cross_icon) || 'ban'
fa_icon(cross_icon, **options)
end
end
|
#check_or_times(value, _options = {}) ⇒ Object
136
137
138
|
# File 'app/helpers/application_helper.rb', line 136
def check_or_times(value, _options = {})
check_or_cross(value, cross_icon: 'times')
end
|
#error_messages(object) ⇒ Object
185
186
187
188
189
190
191
192
|
# File 'app/helpers/application_helper.rb', line 185
def error_messages(object)
return unless object.errors.any?
content_tag :div, class: 'card bg-danger' do
content_tag(:div, "#{pluralize(object.errors.count, 'error')} prohibited this record from being saved:", class: 'card-title') +
render_error_messages_list(object)
end
end
|
#general_disclaimer_on_product_installation_and_local_codes ⇒ Object
239
240
241
|
# File 'app/helpers/application_helper.rb', line 239
def general_disclaimer_on_product_installation_and_local_codes
GENERAL_DISCLAIMER_ON_PRODUCT_INSTALLATION_AND_LOCAL_CODES
end
|
#gridjs_from_html_table(table_id, **options) ⇒ Object
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
# File 'app/helpers/application_helper.rb', line 75
def gridjs_from_html_table(table_id, **options)
config = {
search: false,
pagination: false,
sort: true,
from: "##{table_id}"
}.merge(options)
stimulus_data = {
controller: 'gridjs',
gridjs_autoload_value: true,
gridjs_config_value: config.to_json
}
content_tag(:div, data: stimulus_data, class: 'gridjs-wrapper') do
content_tag(:div, '', data: { gridjs_target: 'table' })
end
end
|
#gridjs_table(id, data: nil, columns: nil, **options) ⇒ Object
Grid.js helper methods for modern table functionality
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
# File 'app/helpers/application_helper.rb', line 53
def gridjs_table(id, data: nil, columns: nil, **options)
config = {
search: false,
pagination: false,
sort: true,
resizable: false
}.merge(options)
stimulus_data = {
controller: 'gridjs',
gridjs_autoload_value: true,
gridjs_config_value: config.to_json
}
stimulus_data[:gridjs_data_value] = data.to_json if data
stimulus_data[:gridjs_columns_value] = columns.to_json if columns
content_tag(:div, data: stimulus_data, class: 'gridjs-wrapper') do
content_tag(:div, '', data: { gridjs_target: 'table' }, id: id)
end
end
|
#is_wy_ip ⇒ Object
109
110
111
|
# File 'app/helpers/application_helper.rb', line 109
def is_wy_ip
warmlyyours_ip?
end
|
#line_break(string, compact = false) ⇒ Object
179
180
181
182
183
|
# File 'app/helpers/application_helper.rb', line 179
def line_break(string, compact = false)
res = string.to_s.strip.split(/[\n\r]/)
res = res.select { |res| res.to_s.strip.present? } if compact
res.join('<br>').html_safe
end
|
#parent_layout(layout) ⇒ Object
232
233
234
235
236
237
|
# File 'app/helpers/application_helper.rb', line 232
def parent_layout(layout)
@view_flow.set(:layout, output_buffer)
output = render(template: "layouts/#{layout}").force_encoding('UTF-8')
self.output_buffer = ActionView::OutputBuffer.new(output)
end
|
#pass_or_fail(result) ⇒ Object
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
# File 'app/helpers/application_helper.rb', line 162
def pass_or_fail(result)
return nil if result.nil?
case result
when 'pass'
color = 'green'
icon = 'check-circle'
when 'fail'
color = 'red'
icon = 'times-circle'
when 'unavailable', 'unchecked'
color = 'orange'
icon = 'exclamation-circle'
end
content_tag(:span, result.titleize) + ' ' + fa_icon(icon, style: "color:#{color};font-size:1.2em")
end
|
#render_error_messages_list(object) ⇒ Object
194
195
196
197
198
|
# File 'app/helpers/application_helper.rb', line 194
def render_error_messages_list(object)
content_tag(:ul, class: 'list-group') do
object.errors.full_messages.map { |msg| content_tag(:li, msg, class: 'list-group-item') }.join('').html_safe
end
end
|
#render_video_card(video, layout: 'card', card_style: 'default', hide_title: false, hide_description: false, display_category_badge: false, display_duration: false, show_popup: true, show_direct_link: true, styles: '') ⇒ Object
Helper method to render video cards with consistent options
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
# File 'app/helpers/application_helper.rb', line 31
def render_video_card(video, layout: 'card', card_style: 'default', hide_title: false, hide_description: false, display_category_badge: false, display_duration: false, show_popup: true, show_direct_link: true, styles: '')
return unless video
video_presenter = video.is_a?(Www::VideoPresenter) ? video : present(video, Www::VideoPresenter)
render Www::VideoCardComponent.new(
video: video_presenter,
layout: layout,
card_style: card_style,
hide_title: hide_title,
hide_description: hide_description,
display_category_badge: display_category_badge,
display_duration: display_duration,
show_popup: ,
show_direct_link: show_direct_link,
styles: styles
)
end
|
22
23
24
25
26
|
# File 'app/helpers/application_helper.rb', line 22
def resolved_auth_form_turbo_frame(turbo_frame: RESOLVED_AUTH_FRAME_UNSET)
return turbo_frame unless turbo_frame.equal?(RESOLVED_AUTH_FRAME_UNSET)
params[:turbo_target].to_s == 'navbar-account-frame' ? 'navbar-account-frame' : nil
end
|
#return_path_or(default) ⇒ Object
Returns @return_path (set by Controllers::ReturnPathHandling) when present,
otherwise falls back to the supplied default. Used in views for "Cancel"
links and similar nav-context links — does NOT perform a redirect.
203
204
205
|
# File 'app/helpers/application_helper.rb', line 203
def return_path_or(default)
@return_path || default
end
|
#safe_css_color(color) ⇒ Object
Validates a CSS color value against safe patterns (hex codes and named colors).
Returns nil for anything that could contain injection payloads.
264
265
266
267
268
269
270
271
|
# File 'app/helpers/application_helper.rb', line 264
def safe_css_color(color)
return nil if color.blank?
stripped = color.strip
return stripped if stripped.match?(/\A#[0-9a-fA-F]{3,8}\z/) || stripped.match?(/\A[a-zA-Z]{1,30}\z/)
nil
end
|
#set_return_path_if_present(return_path: @return_path, return_title: nil) ⇒ Object
207
208
209
210
211
212
|
# File 'app/helpers/application_helper.rb', line 207
def set_return_path_if_present(return_path: @return_path, return_title: nil)
capture do
concat hidden_field_tag(:return_path, return_path) if return_path.present? && url_on_same_domain_as_request(return_path)
concat hidden_field_tag(:return_title, return_title) if return_title.present?
end
end
|
#set_section_if_present ⇒ Object
224
225
226
|
# File 'app/helpers/application_helper.rb', line 224
def set_section_if_present
hidden_field_tag :section, params[:section] if params[:section].present?
end
|
#tab_frame_id ⇒ Object
Per-controller frame ID so cross-page links inside tabs trigger turbo:frame-missing
instead of silently swapping the wrong page's tab shell.
When responding to a Turbo Frame request we sometimes echo the caller's frame ID
from the header so polymorphic controllers (Activities, Communications, ...) rendered
inside a parent's tab match the parent page's frame. We only do this when the request
is genuinely scoped to that parent -- i.e. the URL carries the parent's
<resource>_id route param (e.g. /customers/:customer_id/activities).
If a request originates from inside a parent's tab frame but targets a top-level
resource (e.g. clicking a contact card inside a customer's contacts tab and landing
on /contacts/:id), we deliberately fall through to the controller-derived id so
the response does NOT contain tab-content-<parent>. That makes Turbo fire
turbo:frame-missing, which our global handler in turbo_stream_actions.js upgrades
to a _top Drive visit using the already-fetched response.
292
293
294
295
296
297
298
299
300
301
302
303
|
# File 'app/helpers/application_helper.rb', line 292
def tab_frame_id
default = "tab-content-#{controller_name}"
= request.['Turbo-Frame']
return default unless &.start_with?('tab-content-')
return if == default
parent_resource = .delete_prefix('tab-content-')
parent_id_param = "#{parent_resource.singularize}_id"
return if params[parent_id_param].present?
default
end
|
#to_underscore(term) ⇒ Object
228
229
230
|
# File 'app/helpers/application_helper.rb', line 228
def to_underscore(term)
term.tableize.singularize.tr(' ', '_')
end
|
#track_page? ⇒ Boolean
113
114
115
116
117
|
# File 'app/helpers/application_helper.rb', line 113
def track_page?
(Rails.env.production? || Rails.env.staging?) &&
(@skip_analytics.nil? or @skip_analytics == false) &&
!warmlyyours_ip?
end
|
#turbo_section_wrapper(id: nil, class_names: nil) ⇒ Object
Enable Turbo functionality for specific sections without affecting the entire page
252
253
254
255
256
257
258
259
260
|
# File 'app/helpers/application_helper.rb', line 252
def turbo_section_wrapper(id: nil, class_names: nil, &)
turbo_attrs = {}
turbo_attrs[:id] = id if id
turbo_attrs[:class] = class_names if class_names
turbo_attrs[:'data-turbo'] = 'true' if @turbo_frames_enabled
content_tag(:div, turbo_attrs, &)
end
|
#turbo_tabs_request? ⇒ Boolean
273
274
275
|
# File 'app/helpers/application_helper.rb', line 273
def turbo_tabs_request?
request.['Turbo-Frame']&.start_with?('tab-content')
end
|
#url_on_same_domain_as_request(path) ⇒ Object
214
215
216
217
218
219
220
221
222
|
# File 'app/helpers/application_helper.rb', line 214
def url_on_same_domain_as_request(path)
if path.present? and (uri = begin
URI(path)
rescue StandardError
nil
end)
(uri.host.nil? or uri.host.index(request.host).present?)
end
end
|
AppSignal #2131: legacy references used widget_index_daily_focus_index_path; the route helper
from resources :daily_focus collection widget_index is widget_index_daily_focus_path.
307
308
309
|
# File 'app/helpers/application_helper.rb', line 307
def widget_index_daily_focus_index_path(...)
widget_index_daily_focus_path(...)
end
|
#working_hours? ⇒ Boolean
105
106
107
|
# File 'app/helpers/application_helper.rb', line 105
def working_hours?
Time.current.in_working_hours?
end
|
#yes_or_no(value) ⇒ Object
140
141
142
|
# File 'app/helpers/application_helper.rb', line 140
def yes_or_no(value)
value.to_b ? 'Yes' : 'No'
end
|
#yes_or_no_highlighted(b, reverse_check = false) ⇒ Object
150
151
152
153
154
155
156
157
158
159
160
|
# File 'app/helpers/application_helper.rb', line 150
def yes_or_no_highlighted(b, reverse_check = false)
return nil if b.nil?
res = yes_or_no(b)
color = if reverse_check
res == 'Yes' ? 'red' : 'green'
else
res == 'Yes' ? 'green' : 'red'
end
content_tag(:span, res, style: "color:#{color}")
end
|
#yes_or_no_with_check_or_cross(b, reverse_check = false) ⇒ Object
144
145
146
147
148
|
# File 'app/helpers/application_helper.rb', line 144
def yes_or_no_with_check_or_cross(b, reverse_check = false)
return nil if b.nil?
yes_or_no(b) + ' ' + check_or_cross(reverse_check ? !b : b)
end
|
#youtube_video(url) ⇒ Object
101
102
103
|
# File 'app/helpers/application_helper.rb', line 101
def youtube_video(url)
render partial: 'shared/video', locals: { url: }
end
|