Module: Spree::ThemeHelper

Defined in:
app/helpers/spree/theme_helper.rb

Instance Method Summary collapse

Instance Method Details

#block_attributes(block, allowed_styles: :all) ⇒ Hash

Returns the block HTML attributes it automatically adds data attributes for page builder

Parameters:

  • block (Spree::PageBlock)

    the block

Returns:

  • (Hash)

    the block attributes



189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'app/helpers/spree/theme_helper.rb', line 189

def block_attributes(block, allowed_styles: :all)
  has_width_desktop = block.respond_to?(:preferred_width_desktop) && block.preferred_width_desktop.present? ? "width-desktop='true'" : nil

  attributes = {
    data: {
      editor_id: "block-#{block.id}",
      editor_name: block.display_name,
      editor_parent_id: "section-#{block.section_id}",
      editor_link: spree.respond_to?(:edit_admin_page_section_block_path) ? spree.edit_admin_page_section_block_path(block.section, block) : nil
    },
    id: "block-#{block.id}",
    class: "block-#{block.class.name.demodulize.underscore.dasherize}",
    style: block_styles(block, allowed_styles: allowed_styles),
    width_desktop: has_width_desktop
  }.compact_blank

  tag.attributes(attributes)
end

#block_background_color_style(block) ⇒ String

Returns the block background color style

Parameters:

  • block (Spree::PageBlock)

    the block

Returns:

  • (String)

    the block background color style



304
305
306
307
308
# File 'app/helpers/spree/theme_helper.rb', line 304

def block_background_color_style(block)
  return nil unless block.respond_to?(:preferred_background_color) && block.preferred_background_color.present?

  "background-color: #{block.preferred_background_color};"
end

#block_css_classes(block) ⇒ String

Returns the block CSS classes

Parameters:

  • block (Spree::PageBlock)

    the block

Returns:

  • (String)

    the block CSS classes



314
315
316
317
318
# File 'app/helpers/spree/theme_helper.rb', line 314

def block_css_classes(block)
  classes = []
  classes << "justify-#{block.preferred_justify}" if block.respond_to?(:preferred_justify) && block.preferred_justify.present?
  classes.join(',')
end

#block_styles(block, allowed_styles: :all) ⇒ String

Returns the block inline CSS styles

Parameters:

  • block (Spree::PageBlock)

    the block

  • allowed_styles (Symbol) (defaults to: :all)

    the allowed styles, if not provided, all styles will be returned

Returns:

  • (String)

    the block inline CSS styles



255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
# File 'app/helpers/spree/theme_helper.rb', line 255

def block_styles(block, allowed_styles: :all)
  styles = {}

  styles['text-align'] = block.preferred_text_alignment if block.respond_to?(:preferred_text_alignment) && block.preferred_text_alignment.present?
  styles['width'] = "#{block.preferred_width_desktop}%" if block.respond_to?(:preferred_width_desktop) && block.preferred_width_desktop.present?
  if block.respond_to?(:preferred_container_alignment)
    styles['margin'] = case block.preferred_container_alignment
                       when 'center'
                         '0 auto'
                       when 'right'
                         '0 0 0 auto'
                       else
                         '0 auto 0 0'
                       end
  end
  styles['color'] = if block.respond_to?(:preferred_text_color) && block.preferred_text_color.present?
                      block.preferred_text_color
                    else
                      'var(--section-color)'
                    end

  styles['padding-top'] = "#{block.preferred_top_padding}px" if block.respond_to?(:preferred_top_padding) && block.preferred_top_padding.present?
  if block.respond_to?(:preferred_bottom_padding) && block.preferred_bottom_padding.present?
    styles['padding-bottom'] = "#{block.preferred_bottom_padding}px"
  end
  styles['text-transform'] = :uppercase if theme_setting('headings_uppercase') && block.type == 'heading'
  styles['background-color'] = if block.respond_to?(:preferred_background_color) && block.preferred_background_color.present?
                                 block.preferred_background_color
                               else
                                 'var(--section-background)'
                               end

  if block.respond_to?(:preferred_button_background_color) && block.preferred_button_background_color.present?
    styles['--button-background-color'] = block.preferred_button_background_color
  end
  if block.respond_to?(:preferred_button_text_color) && block.preferred_button_text_color.present?
    styles['--button-text-color'] = block.preferred_button_text_color
  end

  styles = styles.compact_blank
  styles = styles.slice(*allowed_styles) if allowed_styles != :all

  styles.map { |k, v| "#{k}: #{v}" }.join(';')
end

#current_header_logoActiveStorage::Attachment

Returns the logo set in the ‘Spree::PageSections::Header` section

Returns:

  • (ActiveStorage::Attachment)

    the logo



59
60
61
# File 'app/helpers/spree/theme_helper.rb', line 59

def 
  @current_header_logo ||= current_theme_or_preview.sections.find_by(type: 'Spree::PageSections::Header')&.
end

#current_pageSpree::Page

Returns the current page, if not found it will fallback to the homepage

Returns:

  • (Spree::Page)

    the current page



6
7
8
# File 'app/helpers/spree/theme_helper.rb', line 6

def current_page
  @current_page ||= current_theme.pages.find_by(type: 'Spree::Pages::Homepage')
end

#current_page_or_previewSpree::Page

Returns the current page or page preview, preview takes priority

Returns:

  • (Spree::Page)

    the current page or page preview



45
46
47
# File 'app/helpers/spree/theme_helper.rb', line 45

def current_page_or_preview
  @current_page_or_preview ||= current_page_preview || current_page
end

#current_page_previewSpree::PagePreview

Returns the current page preview

Returns:

  • (Spree::PagePreview)

    the current page preview



36
37
38
39
40
# File 'app/helpers/spree/theme_helper.rb', line 36

def current_page_preview
  return if params[:page_preview_id].blank?

  @current_page_preview ||= current_page.previews.find_by(id: params[:page_preview_id])
end

#current_themeSpree::Theme

Returns the current theme, if not found it will fallback to the default theme If ‘theme_id` is provided in the params, it will return the theme with the given id

Returns:

  • (Spree::Theme)

    the current theme



14
15
16
17
18
19
20
21
22
# File 'app/helpers/spree/theme_helper.rb', line 14

def current_theme
  @current_theme ||= if params[:theme_id].present?
                       current_store.themes.find_by(id: params[:theme_id])
                     else
                       current_store.default_theme || current_store.themes.first
                     end
ensure
  @current_theme ||= current_store.themes.first
end

#current_theme_or_previewSpree::Theme

Returns the current theme or theme preview, preview takes priority

Returns:

  • (Spree::Theme)

    the current theme or theme preview



52
53
54
# File 'app/helpers/spree/theme_helper.rb', line 52

def current_theme_or_preview
  @current_theme_or_preview ||= current_theme_preview || current_theme
end

#current_theme_previewSpree::ThemePreview

Returns the current theme preview

Returns:

  • (Spree::ThemePreview)

    the current theme preview



27
28
29
30
31
# File 'app/helpers/spree/theme_helper.rb', line 27

def current_theme_preview
  return if params[:theme_preview_id].blank?

  @current_theme_preview ||= current_theme.previews.find_by(id: params[:theme_preview_id])
end

#hex_color_to_rgb(hex) ⇒ String

Parameters:

  • hex (String)

    the hex color

Returns:

  • (String)

    the rgb color



117
118
119
120
121
122
# File 'app/helpers/spree/theme_helper.rb', line 117

def hex_color_to_rgb(hex)
  return unless hex.present?

  rgb = hex[0..6].match(/^#(..)(..)(..)$/).captures.map(&:hex)
  "rgb(#{rgb.join(', ')})"
end

#hex_color_to_rgba(hex) ⇒ String

Converts a hex color to rgba

Parameters:

  • hex (String)

    the hex color

Returns:

  • (String)

    the rgba color



128
129
130
131
132
133
134
# File 'app/helpers/spree/theme_helper.rb', line 128

def hex_color_to_rgba(hex)
  return unless hex.present?

  *rgb, alpha = hex.match(/^#(..)(..)(..)(..)?$/).captures.map { |hex_pair| hex_pair&.hex }
  opacity = (alpha || 255) / 255.0
  "rgba(#{rgb.join(', ')}, #{opacity.round(2)})"
end

Returns the link HTML attributes it automatically adds data attributes for page builder

Parameters:

  • link (Spree::PageLink)

    the link

Returns:

  • (Hash)

    the link attributes



213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
# File 'app/helpers/spree/theme_helper.rb', line 213

def link_attributes(link, as_html: true)
  parent_type = case link.parent_type
                when 'Spree::PageSection'
                  :section
                when 'Spree::PageBlock'
                  :block
                else
                  return ''
                end

  attributes = if spree.respond_to?(:admin) && spree.respond_to?(:edit_admin_page_link_path) && spree.respond_to?(:edit_admin_page_section_block_path)
               {
                  data: {
                    editor_id: "link-#{link.id}",
                    editor_name: link.label,
                    editor_parent_id: "#{parent_type}-#{link.parent_id}",
                    editor_link: case parent_type
                                when :section
                                  spree.edit_admin_page_link_path(link, page_section_id: link.parent_id)
                                when :block
                                  spree.edit_admin_page_link_path(link, block_id: link.parent_id)
                                end
                  },
                  id: "link-#{link.id}",
                  class: "link-#{link.class.name.demodulize.underscore.dasherize}"
                }
              else
               {}
              end

  if as_html
    tag.attributes(attributes)
  else
    attributes
  end
end

#page_builder_enabled?Boolean

Returns whether the page builder is enabled It checks if there is a theme preview or page preview and if the ‘page_builder` param is set to `true`

Returns:

  • (Boolean)

    whether the page builder is enabled



67
68
69
# File 'app/helpers/spree/theme_helper.rb', line 67

def page_builder_enabled?
  @page_builder_enabled ||= (current_theme_preview.present? || current_page_preview.present?) && params[:page_builder] == 'true'
end

#section_heading_styles(section) ⇒ String

Returns the section heading inline CSS styles

Parameters:

  • section (Spree::PageSection)

    the section

Returns:

  • (String)

    the section heading inline CSS styles



172
173
174
175
176
177
178
179
180
181
182
# File 'app/helpers/spree/theme_helper.rb', line 172

def section_heading_styles(section)
  styles = {}

  styles['text-transform'] = :uppercase if theme_setting('headings_uppercase')
  if section.respond_to?(:preferred_heading_bottom_padding) && section.preferred_heading_bottom_padding.present?
    styles['padding-bottom'] =
      "#{section.preferred_heading_bottom_padding}px"
  end

  styles.compact_blank.map { |k, v| "#{k}: #{v}" }.join(';')
end

#section_styles(section) ⇒ String

Returns the section inline CSS styles

Parameters:

  • section (Spree::PageSection)

    the section

Returns:

  • (String)

    the section inline CSS styles



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'app/helpers/spree/theme_helper.rb', line 140

def section_styles(section)
  styles = {}

  bg_color = section.preferred_background_color.presence || theme_setting('background_color')
  styles['background-color'] = bg_color
  styles['--section-background'] = bg_color
  text_color = section.preferred_text_color.presence || theme_setting('text_color')
  styles['color'] = text_color
  styles['--section-color'] = text_color
  styles['border-color'] = section.preferred_border_color.presence || theme_setting('border_color')
  styles['padding-top'] = "#{section.preferred_top_padding.presence}px"
  styles['padding-bottom'] = "#{section.preferred_bottom_padding.presence}px"
  styles['border-top-width'] = "#{section.preferred_top_border_width.presence}px"
  border_bottom_width = "#{section.preferred_bottom_border_width.presence}px"
  styles['border-bottom-width'] = border_bottom_width
  styles['--section--border-bottom-width'] = border_bottom_width

  if section.respond_to?(:preferred_button_text_color) && section.preferred_button_text_color.present?
    styles['--button-text-color'] = section.preferred_button_text_color
  end

  if section.respond_to?(:preferred_button_background_color) && section.preferred_button_background_color.present?
    styles['--button-background-color'] = section.preferred_button_background_color
  end

  styles.map { |k, v| "#{k}: #{v}" }.join(';')
end

#theme_layout_sectionsHash

Returns the theme layout sections, eg. header, footer, etc.

Returns:

  • (Hash)

    the theme layout sections



74
75
76
77
78
79
80
81
82
83
84
85
# File 'app/helpers/spree/theme_helper.rb', line 74

def theme_layout_sections
  @theme_layout_sections ||= current_theme_or_preview.sections.includes(:links, { asset_attachment: :blob },
                                                                        { blocks: [:rich_text_text, :links] }).all.each_with_object({}) do |section, hash|
    hash[section.type.to_s.demodulize.underscore] = section
  end
rescue StandardError => e
  raise e unless Rails.env.production?

  Rails.error.report(e, context: { theme_id: current_theme_or_preview.id }, source: 'spree.storefront')

  {}
end

#theme_setting(name) ⇒ String

Returns the theme setting for the given name if preview is present, it will return the preview setting, otherwise it will return the theme setting

Parameters:

  • name (String)

    the name of the theme setting

Returns:

  • (String)

    the theme setting



92
93
94
95
96
97
98
# File 'app/helpers/spree/theme_helper.rb', line 92

def theme_setting(name)
  if current_theme_preview.present?
    current_theme_preview.preferences.with_indifferent_access[name]
  elsif current_theme.present?
    current_theme.preferences.with_indifferent_access[name]
  end
end

#theme_setting_rgb_components(name) ⇒ String

This helper allows us to specify opacity in Tailwind’s color palette

Parameters:

  • name (String)

    the name of the theme setting

Returns:

  • (String)

    the theme setting



104
105
106
107
108
109
110
# File 'app/helpers/spree/theme_helper.rb', line 104

def theme_setting_rgb_components(name)
  hex_color = theme_setting(name)
  return unless hex_color.present?

  rgb = hex_color[0..6].match(/^#(..)(..)(..)$/).captures.map(&:hex)
  rgb.join(', ')
end