Module: Www::TowelWarmersHelper

Defined in:
app/helpers/www/towel_warmers_helper.rb

Constant Summary collapse

TOWEL_WARMER_BASE_TAG =

Base tag for towel warmer pages

'for-towel-warmer-page'
FACET_INTRO_TEXT =

SEO-optimized intro text for faceted pages
Maps filter values to keyword-rich descriptions with cross-links

{
  # Finish-based intros
  'Matte Black' => {
    title: 'Matte Black Towel Warmers',
    description: 'Make a bold statement with our <strong>matte black towel warmers</strong>. This trending finish adds sophisticated, industrial-inspired style to modern bathrooms while delivering the same spa-like warmth you expect. Black heated towel racks pair beautifully with contemporary fixtures, white tiles, and minimalist décor.',
    related_links: [
      { text: 'gold', url: '/towel-warmer/gold' },
      { text: 'stainless steel', url: '/towel-warmer/brushed-stainless-steel' }
    ]
  },
  'Gold' => {
    title: 'Gold Towel Warmers',
    description: 'Browse our full collection of <strong>gold towel warmers</strong> in both brushed and polished finishes. ' \
                 'Whether you prefer the subtle, fingerprint-resistant warmth of <strong>brushed gold</strong> or the mirror-like glamour of ' \
                 '<strong>polished gold</strong>, our gold heated towel racks add luxury to any bathroom. PVD-coated for lasting durability.',
    related_links: [
      { text: 'matte black', url: '/towel-warmer/matte-black' },
      { text: 'stainless steel', url: '/towel-warmer/brushed-stainless-steel' }
    ]
  },
  'Brushed Stainless Steel' => {
    title: 'Brushed Stainless Steel Towel Warmers',
    description: 'Our most popular finish, <strong>brushed stainless steel towel warmers</strong> offer versatile style that complements any bathroom. The subtle brushed texture hides water spots and fingerprints while providing durability that lasts for years. A classic choice for heated towel racks.',
    related_links: [
      { text: 'polished stainless steel', url: '/towel-warmer/polished-stainless-steel' },
      { text: 'matte black', url: '/towel-warmer/matte-black' }
    ]
  },
  'Polished Stainless Steel' => {
    title: 'Polished Stainless Steel Towel Warmers',
    description: 'Achieve a sleek, modern look with our <strong>polished stainless steel towel warmers</strong>. The chrome-like mirror finish reflects light beautifully and coordinates with polished fixtures. Also known as chrome towel warmers, these heated towel racks are perfect for contemporary bathrooms.',
    related_links: [
      { text: 'brushed stainless steel', url: '/towel-warmer/brushed-stainless-steel' },
      { text: 'gold', url: '/towel-warmer/gold' }
    ]
  },
  # Mounting-based intros
  'Wall Mounted' => {
    title: 'Wall Mounted Towel Warmers',
    description: 'Maximize your bathroom space with our <strong>wall-mounted towel warmers</strong>. These heated towel racks mount securely to your wall, keeping towels within easy reach of the shower while saving valuable floor space. Available in hardwired and plug-in options.',
    related_links: [
      { text: 'freestanding towel warmers', url: '/towel-warmer/freestanding' },
      { text: 'hardwired options', url: '/towel-warmer/hardwired' }
    ]
  },
  'Freestanding' => {
    title: 'Freestanding Towel Warmers',
    description: 'Enjoy flexibility with our <strong>freestanding towel warmers</strong>. These portable heated towel racks can be placed anywhere with access to an outlet—no wall mounting or permanent installation required. Perfect for renters or bathrooms where wall mounting isn\'t practical.',
    related_links: [
      { text: 'wall-mounted towel warmers', url: '/towel-warmer/wall-mounted' },
      { text: 'plug-in options', url: '/towel-warmer/plug-in' }
    ]
  },
  # Connection-based intros
  'Hardwired' => {
    title: 'Hardwired Towel Warmers',
    description: 'For a seamless, professional look, choose our <strong>hardwired towel warmers</strong>. These heated towel racks connect directly to your home\'s electrical system—no visible cords or outlets required. Ideal for new construction or bathroom renovations where you want a clean, built-in appearance.',
    related_links: [
      { text: 'plug-in towel warmers', url: '/towel-warmer/plug-in' },
      { text: 'dual connection options', url: '/towel-warmer/plug-in-or-hardwired' }
    ]
  },
  'Plug-in' => {
    title: 'Plug-In Towel Warmers',
    description: 'Easy installation meets daily luxury with our <strong>plug-in towel warmers</strong>. Simply mount to your wall and plug into a standard outlet—no electrician needed. These heated towel racks are perfect for DIY installation and can be easily moved if you relocate.',
    related_links: [
      { text: 'hardwired towel warmers', url: '/towel-warmer/hardwired' },
      { text: 'freestanding options', url: '/towel-warmer/freestanding' }
    ]
  },
  'Plug-in or Hardwired' => {
    title: 'Dual Connection Towel Warmers',
    description: 'Get maximum flexibility with our <strong>dual connection towel warmers</strong>. These versatile heated towel racks ship ready to plug in, but the cord can be removed for hardwired installation. Future-proof your investment—start with plug-in today and convert to hardwired during a future renovation.',
    related_links: [
      { text: 'hardwired only', url: '/towel-warmer/hardwired' },
      { text: 'plug-in only', url: '/towel-warmer/plug-in' }
    ]
  },
  # Size-based intros — each targets a distinct buyer intent and keyword cluster:
  #   Compact  → powder room / small bathroom / space-saving
  #   Standard → everyday bathroom / most popular / versatile
  #   Large    → master bath / multiple towels / statement piece
  'Compact' => {
    title: 'Compact Towel Warmers',
    description: '<strong>Compact towel warmers</strong> (under 30″ tall) are purpose-built for powder rooms, ' \
                 'small guest baths, and tight spaces. Their slim profile fits comfortably beside a vanity or above ' \
                 'a toilet tank without crowding the room — yet they still deliver warm, dry towels every day. ' \
                 'A smart upgrade for smaller spaces.',
    related_links: [
      { text: 'standard size towel warmers', url: '/towel-warmer/standard' },
      { text: 'large towel warmers', url: '/towel-warmer/large' }
    ]
  },
  'Standard' => {
    title: 'Standard Size Towel Warmers',
    description: 'Our <strong>standard size towel warmers</strong> (30–40″ tall) are our most popular category — ' \
                 'and for good reason. They strike the ideal balance between heating capacity and wall footprint, ' \
                 'warming one or two full-size bath towels while fitting naturally into most everyday bathrooms. ' \
                 "If you're not sure which size to choose, start here.",
    related_links: [
      { text: 'compact towel warmers', url: '/towel-warmer/compact' },
      { text: 'large towel warmers', url: '/towel-warmer/large' }
    ]
  },
  'Large' => {
    title: 'Large Towel Warmers',
    description: '<strong>Large towel warmers</strong> (over 40″ tall) are designed for master bathrooms and ' \
                 'spa-inspired spaces that call for something exceptional. With more bars and greater height, they ' \
                 'warm multiple bath towels or robes simultaneously — turning a functional fixture into a design ' \
                 'statement. Ideal for primary suites and luxury bath remodels.',
    related_links: [
      { text: 'standard size towel warmers', url: '/towel-warmer/standard' },
      { text: 'compact towel warmers', url: '/towel-warmer/compact' }
    ]
  }
}.freeze
FACET_PAGE_TITLES =

Custom page title overrides for specific facet filter values.
Keys match the filter value (e.g. spec_finish_eq). When a single-filter
page matches an entry here, the override title is used verbatim.
Titles incorporate synonym terms observed in GSC query data (e.g. "heated towel rack").

{
  # Finish facets
  'Matte Black'             => 'Black Towel Warmers | Matte Black Towel Warmers | WarmlyYours',
  'Gold'                    => 'Gold Towel Warmers | Brushed & Polished Gold Heated Towel Rack | WarmlyYours',
  'Brushed Stainless Steel' => 'Brushed Stainless Steel Heated Towel Rack | Towel Warmers | WarmlyYours',
  'Polished Stainless Steel' => 'Chrome Towel Warmers | Polished Stainless Steel Heated Rack | WarmlyYours',
  # Mounting facets
  'Wall Mounted'            => 'Wall Mounted Towel Warmers | Heated Towel Rack | WarmlyYours',
  'Freestanding'            => 'Freestanding Towel Warmers | Free Standing Heated Towel Rack | WarmlyYours',
  # Connection facets
  'Hardwired'               => 'Hardwired Towel Warmers | Hardwired Heated Towel Rack | WarmlyYours',
  'Plug-in'                 => 'Plug-In Towel Warmers | Plug-In Heated Towel Rack | WarmlyYours',
  'Plug-in or Hardwired'    => 'Dual Connection Towel Warmers | Plug-In or Hardwired | WarmlyYours',
  # Size facets
  'Compact'                 => 'Compact Towel Warmers | Small Heated Towel Racks | WarmlyYours',
  'Standard'                => 'Standard Towel Warmers | Mid-Size Heated Towel Racks | WarmlyYours',
  'Large'                   => 'Large Towel Warmers | Full-Size Heated Towel Racks | WarmlyYours'
}.freeze
FACET_PAGE_DESCRIPTIONS =

Custom meta description overrides for specific facet filter values.
Tailored copy per facet — avoids the generic template and targets each
page's actual search intent based on GSC query data.

{
  # Finish facets
  'Matte Black'              => 'Shop matte black towel warmers & black heated towel racks from WarmlyYours. Bold modern finish, wall-mounted or freestanding. UL-listed with same-day shipping.',
  'Gold'                     => 'Shop gold towel warmers in brushed & polished gold finishes from WarmlyYours. PVD-coated for lasting luxury. Wall-mounted & freestanding. UL-listed with same-day shipping.',
  'Brushed Stainless Steel'  => 'Shop brushed stainless steel heated towel racks & towel warmers from WarmlyYours. Our most popular finish—resists fingerprints & water spots. Same-day shipping.',
  'Polished Stainless Steel' => 'Shop chrome & polished stainless steel towel warmers from WarmlyYours. Sleek mirror finish for modern bathrooms. Wall-mounted & freestanding. Same-day shipping.',
  # Mounting facets
  'Wall Mounted'             => 'Shop wall-mounted towel warmers & heated towel racks from WarmlyYours. Hardwired, plug-in & dual connection options. UL-listed with same-day shipping.',
  'Freestanding'             => 'Shop freestanding towel warmers & free standing heated towel racks from WarmlyYours. No installation needed—just plug in. Multiple finishes. Same-day shipping.',
  # Connection facets
  'Hardwired'                => 'Shop hardwired towel warmers & heated towel racks from WarmlyYours. Permanent install, no visible cords—ideal for new builds & remodels. Same-day shipping.',
  'Plug-in'                  => 'Shop plug-in towel warmers & heated towel racks from WarmlyYours. Easy DIY install—no electrician needed. Wall-mounted & freestanding. Same-day shipping.',
  'Plug-in or Hardwired'     => 'Shop dual connection towel warmers from WarmlyYours. Ships plug-in, converts to hardwired—maximum flexibility for any bathroom. UL-listed, same-day shipping.',
  # Size facets
  'Compact'                  => 'Shop compact towel warmers & small heated towel racks from WarmlyYours. Under 30″ tall—ideal for powder rooms & guest baths. UL-listed with same-day shipping.',
  'Standard'                 => 'Shop standard size towel warmers & heated towel racks from WarmlyYours. 30–40″ tall—the most popular size for everyday bathrooms. UL-listed, same-day shipping.',
  'Large'                    => 'Shop large towel warmers & full-size heated towel racks from WarmlyYours. Over 40″ tall—warm multiple towels at once. Perfect for master baths. Same-day shipping.'
}.freeze

Instance Method Summary collapse

Instance Method Details

Build breadcrumb links from active filters
Returns array like: [{ name: 'Towel Warmers', url: '/towel-warmer' }, { name: 'Brushed Gold' }, ...]

Parameters:

  • active_filters (Hash)

    Current Ransack filter params

Returns:

  • (Array<Hash>)

    Breadcrumb link hashes



502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
# File 'app/helpers/www/towel_warmers_helper.rb', line 502

def towel_warmer_breadcrumb_links(active_filters)
  links = [{ name: 'Towel Warmers', url: www_towel_warmers_path }]

  return links if active_filters.blank?

  # Build cumulative path segments for each filter
  path_segments = []

  # Composite finish (e.g. "gold" matching both brushed + polished)
  if active_filters[:spec_finish_in].present?
    TowelWarmerFilterSlugs::COMPOSITE_FINISH_SLUGS.each do |slug, values|
      if Array(active_filters[:spec_finish_in]).sort == values.sort
        path_segments << slug
        links << { name: slug.capitalize, url: "/#{I18n.locale}/towel-warmer/#{path_segments.join('/')}" }
        break
      end
    end
  end

  # Order: finish, style, connection, mounting, size
  filter_order = [
    %i[spec_finish_eq finish],
    %i[spec_bar_shape_eq style],
    %i[spec_connection_method_eq connection],
    %i[spec_mounting_method_eq mounting],
    %i[spec_size_eq size]
  ]

  filter_order.each do |ransack_key, filter_type|
    value = active_filters[ransack_key]
    next if value.blank?

    # Get the slug for this value (size stores slug directly)
    slug = filter_type == :size ? value : TowelWarmerFilterSlugs::RANSACK_TO_SLUG[value]
    next if slug.blank?

    path_segments << slug

    # Get human-readable label
    label = towel_warmer_filter_label(filter_type, value)

    # Build URL path up to this point (use the path format, not query string)
    url = "/#{I18n.locale}/towel-warmer/#{path_segments.join('/')}"

    links << { name: label, url: url }
  end

  # Last link shouldn't have a URL (current page)
  links.last[:url] = nil if links.length > 1

  links
end

#towel_warmer_canonical_url(active_filters) ⇒ String

Build canonical URL for towel warmer filter pages
Strategy: Self-referencing canonical for meaningful filter combinations

Parameters:

  • active_filters (Hash)

    Current Ransack filter params

Returns:

  • (String)

    Canonical URL



585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
# File 'app/helpers/www/towel_warmers_helper.rb', line 585

def towel_warmer_canonical_url(active_filters)
  return www_towel_warmers_url if active_filters.blank?

  # Build the filter path without sort params
  path_segments = []

  # Composite finish first
  if active_filters[:spec_finish_in].present?
    TowelWarmerFilterSlugs::COMPOSITE_FINISH_SLUGS.each do |slug, values|
      if Array(active_filters[:spec_finish_in]).sort == values.sort
        path_segments << slug
        break
      end
    end
  end

  filter_order = [
    %i[spec_finish_eq finish],
    %i[spec_bar_shape_eq style],
    %i[spec_connection_method_eq connection],
    %i[spec_mounting_method_eq mounting],
    %i[spec_size_eq size]
  ]

  filter_order.each do |ransack_key, filter_type|
    value = active_filters[ransack_key]
    next if value.blank?

    # Size stores slug directly, others need lookup
    slug = filter_type == :size ? value : TowelWarmerFilterSlugs::RANSACK_TO_SLUG[value]
    path_segments << slug if slug.present?
  end

  if path_segments.any?
    # Use absolute URL with path format
    "#{request.protocol}#{request.host_with_port}/#{I18n.locale}/towel-warmer/#{path_segments.join('/')}"
  else
    www_towel_warmers_url
  end
end

#towel_warmer_facet_intro(active_filters) ⇒ Hash?

Generate SEO intro text for the current filter combination.

Single-dimension pages get a hand-crafted entry from FACET_INTRO_TEXT.
Multi-dimension pages get a synthesized intro so the H1 is never identical
to any single-dimension parent page — preventing keyword cannibalization.

Parameters:

  • active_filters (Hash)

    Current Ransack filter params

Returns:

  • (Hash, nil)

    { title:, description:, related_links: } or nil if no intro



245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
# File 'app/helpers/www/towel_warmers_helper.rb', line 245

def towel_warmer_facet_intro(active_filters)
  return nil if active_filters.blank?

  # Multi-filter: synthesize a combined, unique intro
  return towel_warmer_combined_facet_intro(active_filters) if active_filters.size > 1

  # Single-filter: use the hand-crafted entry by priority: finish > mounting > connection > size
  filter_value = composite_finish_label(active_filters) ||
                 active_filters[:spec_finish_eq] ||
                 active_filters[:spec_mounting_method_eq] ||
                 active_filters[:spec_connection_method_eq] ||
                 active_filters[:spec_size_eq]&.then { |v| TowelWarmerFilterSlugs::SIZE_LABELS[v] }

  return nil if filter_value.blank?

  intro = FACET_INTRO_TEXT[filter_value]
  return nil unless intro

  # FACET_INTRO_TEXT stores raw paths; localize them through cms_link at render time
  localize_intro_links(intro)
end

#towel_warmer_facet_introduction_html(facet_intro) ⇒ String

Build the introduction HTML for the facet hero.
Cross-links between facet pages are handled by the features/benefits section
further down the page so the hero copy stays clean and focused.

Parameters:

  • facet_intro (Hash)

    { title:, description:, related_links: }

Returns:

  • (String)

    Raw HTML safe string



233
234
235
# File 'app/helpers/www/towel_warmers_helper.rb', line 233

def towel_warmer_facet_introduction_html(facet_intro)
  "<p>#{facet_intro[:description]}</p>"
end

#towel_warmer_facet_tags(active_filters) ⇒ Array<String>

Generate facet-specific tag(s) based on active filters
Returns array of tags in priority order (most specific first)

Examples:

towel_warmer_facet_tags({ spec_mounting_method_eq: 'Wall Mounted' })
# => ['for-towel-warmer-wall-mounted-page']

towel_warmer_facet_tags({ spec_finish_eq: 'Matte Black', spec_mounting_method_eq: 'Wall Mounted' })
# => ['for-towel-warmer-matte-black-page', 'for-towel-warmer-wall-mounted-page']

Parameters:

  • active_filters (Hash)

    Current Ransack filter params

Returns:

  • (Array<String>)

    Tags in priority order



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'app/helpers/www/towel_warmers_helper.rb', line 32

def towel_warmer_facet_tags(active_filters)
  return [] if active_filters.blank?

  tags = []

  # Composite finish gets its own tag (e.g. for-towel-warmer-gold-page)
  if active_filters[:spec_finish_in].present?
    TowelWarmerFilterSlugs::COMPOSITE_FINISH_SLUGS.each do |slug, values|
      if Array(active_filters[:spec_finish_in]).sort == values.sort
        tags << "for-towel-warmer-#{slug}-page"
        break
      end
    end
  end

  # Priority order for tag specificity: finish > mounting > connection > size
  filter_keys = %i[
    spec_finish_eq
    spec_mounting_method_eq
    spec_connection_method_eq
  ]

  filter_keys.each do |key|
    value = active_filters[key]
    next if value.blank?

    slug = value.to_s.parameterize
    tags << "for-towel-warmer-#{slug}-page"
  end

  # Size filter uses a slug directly (e.g. 'compact', 'standard', 'large')
  tags << "for-towel-warmer-#{active_filters[:spec_size_eq]}-page" if active_filters[:spec_size_eq].present?

  tags
end

#towel_warmer_faqs_with_priority(active_filters) ⇒ Array<Article>

Retrieve FAQs for towel warmer pages, sorted by popularity (votes)
Collects FAQs from both facet-specific and generic tags, then sorts by votes

Parameters:

  • active_filters (Hash)

    Current Ransack filter params

Returns:

  • (Array<Article>)

    FAQ articles sorted by popularity (most helpful first)



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'app/helpers/www/towel_warmers_helper.rb', line 74

def towel_warmer_faqs_with_priority(active_filters)
  facet_tags = towel_warmer_facet_tags(active_filters)

  # If no facet filters, just return generic FAQs (already sorted by votes)
  return retrieve_faqs(tags: TOWEL_WARMER_BASE_TAG, add_vote_data: true) if facet_tags.empty?

  collected_faqs = []
  seen_ids = Set.new

  # 1. Collect FAQs for each facet tag
  facet_tags.each do |tag|
    faqs = retrieve_faqs(tags: tag, add_vote_data: true)
    faqs.each do |faq|
      next if seen_ids.include?(faq.id)

      collected_faqs << faq
      seen_ids << faq.id
    end
  end

  # 2. Add generic towel warmer FAQs (avoiding duplicates)
  generic_faqs = retrieve_faqs(tags: TOWEL_WARMER_BASE_TAG, add_vote_data: true)
  generic_faqs.each do |faq|
    next if seen_ids.include?(faq.id)

    collected_faqs << faq
    seen_ids << faq.id
  end

  # 3. Sort by popularity (most helpful first)
  # Sort by: positive_votes + sort_booster DESC, then vote_count DESC, then subject ASC
  collected_faqs.sort_by { |faq| [-(faq.positive_votes.to_i + faq.sort_booster.to_i), -faq.vote_count.to_i, faq.subject.to_s] }
end

#towel_warmer_filter_label(filter_type, value) ⇒ Object

Get human-readable label for a filter value



556
557
558
559
560
561
562
563
564
565
566
# File 'app/helpers/www/towel_warmers_helper.rb', line 556

def towel_warmer_filter_label(filter_type, value)
  case filter_type
  when :style
    value.gsub('Bars', '').strip # "Round Bars" -> "Round"
  when :size
    TowelWarmerFilterSlugs::SIZE_LABELS[value] || value # "compact" -> "Compact"
  else
    # :finish, :connection, :mounting are already human-readable
    value
  end
end

#towel_warmer_nav_benefit_cardsObject

Returns the 4 navigation benefit cards for the "Why Choose" section.
Paths are passed through cms_link so all links are locale-aware.



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
# File 'app/helpers/www/towel_warmers_helper.rb', line 269

def towel_warmer_nav_benefit_cards
  [
    {
      url: nil, icon: 'palette', title: 'Finish Options', family: :sharp_regular,
      description: "Available in <a href=\"#{cms_link('/towel-warmer/brushed-stainless-steel')}\">brushed stainless</a>, " \
                   "<a href=\"#{cms_link('/towel-warmer/polished-stainless-steel')}\">polished stainless</a>, " \
                   "<a href=\"#{cms_link('/towel-warmer/matte-black')}\">matte black</a>, and " \
                   "<a href=\"#{cms_link('/towel-warmer/gold')}\">gold</a>."
    },
    {
      url: nil, icon: 'screwdriver-wrench', title: 'Mounting Options', family: :sharp_regular,
      description: "Choose <a href=\"#{cms_link('/towel-warmer/wall-mounted')}\">wall-mounted</a> for a clean, built-in look or " \
                   "<a href=\"#{cms_link('/towel-warmer/freestanding')}\">freestanding</a> for flexible, no-drill placement anywhere in your bathroom."
    },
    {
      url: nil, icon: 'plug', title: 'Connection Type', family: :sharp_regular,
      description: "Install as <a href=\"#{cms_link('/towel-warmer/plug-in')}\">plug-in</a> for easy DIY setup, " \
                   "<a href=\"#{cms_link('/towel-warmer/hardwired')}\">hardwired</a> for a cord-free finish, or choose " \
                   "<a href=\"#{cms_link('/towel-warmer/plug-in-or-hardwired')}\">dual connection</a> for maximum flexibility."
    },
    {
      url: nil, icon: 'ruler', title: 'Size for Every Space', family: :sharp_regular,
      description: "Shop <a href=\"#{cms_link('/towel-warmer/compact')}\">compact</a> (under 30\u2033) for powder rooms, " \
                   "<a href=\"#{cms_link('/towel-warmer/standard')}\">standard</a> (30\u201340\u2033) for everyday bathrooms, or " \
                   "<a href=\"#{cms_link('/towel-warmer/large')}\">large</a> (over 40\u2033) for master suites."
    }
  ]
end

#towel_warmer_page_description(active_filters) ⇒ Object

Dynamic meta description based on active filters



468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
# File 'app/helpers/www/towel_warmers_helper.rb', line 468

def towel_warmer_page_description(active_filters)
  return 'Shop heated towel racks & electric towel warmers at WarmlyYours. Wall-mounted & freestanding heated towel rack styles in matte black, brushed gold & stainless steel. UL-listed, same-day shipping.' if active_filters.blank?

  # Use tailored per-facet copy for single-filter pages
  size_label = TowelWarmerFilterSlugs::SIZE_LABELS[active_filters[:spec_size_eq]]
  filter_value = composite_finish_label(active_filters) ||
                 active_filters[:spec_finish_eq] ||
                 active_filters[:spec_mounting_method_eq] ||
                 active_filters[:spec_connection_method_eq] ||
                 size_label

  return FACET_PAGE_DESCRIPTIONS[filter_value] if active_filters.size == 1 && filter_value.present? && FACET_PAGE_DESCRIPTIONS.key?(filter_value)

  # Multi-filter fallback: natural language order (mounting/connection first, then finish, then size)
  parts = []
  parts << active_filters[:spec_mounting_method_eq]&.downcase if active_filters[:spec_mounting_method_eq].present?
  parts << active_filters[:spec_connection_method_eq]&.downcase if active_filters[:spec_connection_method_eq].present?
  composite = composite_finish_label(active_filters)
  parts << (composite || active_filters[:spec_finish_eq])&.downcase if composite || active_filters[:spec_finish_eq].present?
  parts << size_label&.downcase if size_label.present?
  parts.compact!

  if parts.any?
    "Shop #{parts.join(' ')} towel warmers from WarmlyYours. UL-listed with same-day shipping and expert support."
  else
    'Shop heated towel racks & electric towel warmers at WarmlyYours. Wall-mounted & freestanding heated towel rack styles in matte black, brushed gold & stainless steel. UL-listed, same-day shipping.'
  end
end

#towel_warmer_page_title(active_filters) ⇒ Object

Dynamic page title based on active filters



437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
# File 'app/helpers/www/towel_warmers_helper.rb', line 437

def towel_warmer_page_title(active_filters)
  base = 'Towel Warmers'

  return "Heated Towel Racks & #{base} | Electric Towel Dryers | WarmlyYours" if active_filters.blank?

  # Check for a custom title override (single-filter pages only)
  size_label = TowelWarmerFilterSlugs::SIZE_LABELS[active_filters[:spec_size_eq]]
  filter_value = composite_finish_label(active_filters) ||
                 active_filters[:spec_finish_eq] ||
                 active_filters[:spec_mounting_method_eq] ||
                 active_filters[:spec_connection_method_eq] ||
                 size_label

  return FACET_PAGE_TITLES[filter_value] if active_filters.size == 1 && filter_value.present? && FACET_PAGE_TITLES.key?(filter_value)

  # Multi-filter fallback: natural language order (mounting/connection qualifier first, then finish, then size)
  parts = []
  parts << active_filters[:spec_mounting_method_eq] if active_filters[:spec_mounting_method_eq].present?
  parts << active_filters[:spec_connection_method_eq] if active_filters[:spec_connection_method_eq].present?
  composite = composite_finish_label(active_filters)
  parts << (composite || active_filters[:spec_finish_eq]) if composite || active_filters[:spec_finish_eq].present?
  parts << size_label if size_label.present?

  if parts.any?
    "#{parts.join(' ')} Towel Warmers | Heated Towel Rack | WarmlyYours"
  else
    "Heated Towel Racks & #{base} | Electric Towel Dryers | WarmlyYours"
  end
end