Class: Dugway::Theme

Inherits:
Object
  • Object
show all
Defined in:
lib/dugway/theme.rb

Constant Summary collapse

REQUIRED_FILES =
%w( cart.html contact.html home.html layout.html maintenance.html product.html products.html screenshot.jpg settings.json theme.css theme.js )
THEME_COLOR_ATTRIBUTE_MAPPINGS =
YAML.load_file(
  File.join(__dir__, 'config', 'theme_color_attribute_mappings.yml')
).freeze
VALID_SECTIONS =
%w(global_navigation homepage product_page general messaging social translations).freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(overridden_customization = {}) ⇒ Theme

Returns a new instance of Theme.



18
19
20
21
22
# File 'lib/dugway/theme.rb', line 18

def initialize(overridden_customization={})
  @overridden_customization = overridden_customization.stringify_keys
  @errors = []
  @warnings = []
end

Instance Attribute Details

#errorsObject (readonly)

Returns the value of attribute errors.



16
17
18
# File 'lib/dugway/theme.rb', line 16

def errors
  @errors
end

#warningsObject (readonly)

Returns the value of attribute warnings.



16
17
18
# File 'lib/dugway/theme.rb', line 16

def warnings
  @warnings
end

Instance Method Details

#build_file(name) ⇒ Object



81
82
83
84
# File 'lib/dugway/theme.rb', line 81

def build_file(name)
  @building = true
  file_content(name)
end

#customizationObject



48
49
50
51
52
53
54
55
56
# File 'lib/dugway/theme.rb', line 48

def customization
  Hash.new.tap do |customization|
    %w( fonts colors options images image_sets features).each do |type|
      customization.update(customization_for_type(type))
    end

    customization.update(@overridden_customization)
  end
end

#featuresObject



44
45
46
# File 'lib/dugway/theme.rb', line 44

def features
  customization_for_type('features')
end

#file_content(name) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/dugway/theme.rb', line 66

def file_content(name)
  case name
  when 'theme.js'
    if @building
      Terser.new.compile(sprockets[name].to_s)
    else
      sprockets[name].to_s
    end
  when 'theme.css'
    sprockets[name].to_s
  else
    read_source_file(name)
  end
end

#filesObject



86
87
88
# File 'lib/dugway/theme.rb', line 86

def files
  REQUIRED_FILES + image_files + font_files
end

#font_filesObject



96
97
98
99
100
# File 'lib/dugway/theme.rb', line 96

def font_files
  Dir.glob(File.join(source_dir, 'fonts', '**', '*.{eot,ttf,otf,woff,svg}')).map do |i|
    i.gsub(source_dir, '')[1..-1]
  end
end

#fontsObject



32
33
34
# File 'lib/dugway/theme.rb', line 32

def fonts
  customization_for_type('fonts')
end

#image_filesObject



90
91
92
93
94
# File 'lib/dugway/theme.rb', line 90

def image_files
  Dir.glob(File.join(source_dir, 'images', '**', '*.{png,jpg,jpeg,gif,ico,svg}')).map do |i|
    i.gsub(source_dir, '')[1..-1]
  end
end

#image_setsObject



40
41
42
# File 'lib/dugway/theme.rb', line 40

def image_sets
  customization_for_type('image_sets')
end

#imagesObject



36
37
38
# File 'lib/dugway/theme.rb', line 36

def images
  customization_for_type('images')
end

#layoutObject



24
25
26
# File 'lib/dugway/theme.rb', line 24

def layout
  read_source_file('layout.html')
end

#nameObject



58
59
60
# File 'lib/dugway/theme.rb', line 58

def name
  settings['name']
end

#settingsObject



28
29
30
# File 'lib/dugway/theme.rb', line 28

def settings
  JSON.parse(read_source_file('settings.json'))
end

#valid?(validate_colors: true, validate_layout_attributes: true, validate_options: true) ⇒ Boolean

Returns:

  • (Boolean)


102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/dugway/theme.rb', line 102

def valid?(validate_colors: true, validate_layout_attributes: true, validate_options: true)
  @errors = []
  @warnings = []

  REQUIRED_FILES.each do |file|
    @errors << "Missing source/#{ file }" if read_source_file(file).nil?
  end

  @errors << 'Missing theme name in source/settings.json' if name.blank?
  @errors << 'Invalid theme version in source/settings.json (ex: 1.0.3)' unless !!(version =~ /\d+\.\d+\.\d+/)

  if settings['preset_styles']
    validate_preview
    if settings['preset_styles']['presets']
      settings['preset_styles']['presets'].each do |preset|
        validate_preset_styles(preset)
        validate_style_references(preset)
      end
    else
      @errors << "Missing presets"
    end
  end

  validate_required_color_settings if validate_colors
  validate_required_layout_attributes if validate_layout_attributes

  if validate_options
    validate_options_settings # Validate descriptions, requires, defaults
    # Validate sections for options, images, and image_sets
    validate_setting_sections(settings['options'], 'options') if settings['options']
    validate_setting_sections(settings['images'], 'images') if settings['images']
    validate_setting_sections(settings['image_sets'], 'image_sets') if settings['image_sets']
  end

  @errors.empty?
end

#validate_options_settingsObject



183
184
185
186
187
188
189
# File 'lib/dugway/theme.rb', line 183

def validate_options_settings
  return unless settings['options']

  validate_options_descriptions
  validate_options_requires
  validate_option_defaults
end

#validate_required_color_settingsObject



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/dugway/theme.rb', line 139

def validate_required_color_settings
  if !settings['colors']
    @errors << "Missing colors section in theme settings"
    return
  end

  required_colors_attribute_names = THEME_COLOR_ATTRIBUTE_MAPPINGS['required_color_attributes']
  if !required_colors_attribute_names
    @errors << "Missing required color attributes configuration"
    return
  end

  theme_colors = settings['colors'].map { |c| c['variable'] }
  mappings = THEME_COLOR_ATTRIBUTE_MAPPINGS[name] || {}

  missing_colors = required_colors_attribute_names.reject do |color|
    theme_colors.include?(color) ||
    (mappings.key?(color) && (mappings[color].nil? || theme_colors.include?(mappings[color])))
  end

  unless missing_colors.empty?
    @errors << "Missing required color settings: #{missing_colors.join(', ')}"
  end
end

#validate_required_layout_attributesObject

Validate that the Layout file has expected attributes for:

  • data-bc-page-type on the body tag

  • one data-bc-hook=“header” and one data-bc-hook=“footer” somewhere



167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/dugway/theme.rb', line 167

def validate_required_layout_attributes
  layout_content = read_source_file('layout.html')

  unless layout_content =~ /<body.*?\bdata-bc-page-type\b/
    @errors << "layout.html missing `data-bc-page-type` attribute on body tag"
  end

  header_hooks = layout_content.scan(/data-bc-hook=(?:"|')header(?:"|')/).size
  footer_hooks = layout_content.scan(/data-bc-hook=(?:"|')footer(?:"|')/).size

  @errors << "layout.html must have exactly one `data-bc-hook=\"header\"`" if header_hooks != 1
  @errors << "layout.html must have exactly one `data-bc-hook=\"footer\"`" if footer_hooks != 1
end

#versionObject



62
63
64
# File 'lib/dugway/theme.rb', line 62

def version
  settings['version']
end