Class: Crm::FaqRenderedWhereComponent

Inherits:
ViewComponent::Base
  • Object
show all
Includes:
ActionView::Helpers::UrlHelper
Defined in:
app/components/crm/faq_rendered_where_component.rb

Overview

Shows ALL locations where a FAQ appears: standalone page, blog embeds, product/support pages, landing pages.

Usage:
<%= render Crm::FaqRenderedWhereComponent.new(article: @article) %>

Constant Summary collapse

LANDING_PAGE_TAG_PATTERN =

Regex pattern matching landing page tag.

/\Afor-(.+)-page\z/

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(article:) ⇒ FaqRenderedWhereComponent

Returns a new instance of FaqRenderedWhereComponent.

Parameters:

  • article (Article)

    the FAQ article to locate



17
18
19
20
# File 'app/components/crm/faq_rendered_where_component.rb', line 17

def initialize(article:)
  super()
  @article = article
end

Instance Attribute Details

#articleArticle (readonly)

Returns the FAQ article whose locations are being listed.

Returns:

  • (Article)

    the FAQ article whose locations are being listed



14
15
16
# File 'app/components/crm/faq_rendered_where_component.rb', line 14

def article
  @article
end

Instance Method Details

#before_rendervoid

This method returns an undefined value.

Preloads canonical paths for the article's product lines before rendering.



24
25
26
27
28
29
30
31
# File 'app/components/crm/faq_rendered_where_component.rb', line 24

def before_render
  super
  pls = article.product_lines.to_a
  return if pls.empty?

  paths = ProductLine.canonical_paths_for(pls)
  pls.each { |pl| pl.instance_variable_set(:@canonical_path, paths[pl.id]) }
end

#blog_embedsActiveRecord::Relation<EmbeddedFaqAsset>

Returns blog posts embedding this FAQ.

Returns:



41
42
43
44
45
46
47
48
# File 'app/components/crm/faq_rendered_where_component.rb', line 41

def blog_embeds
  @blog_embeds ||= EmbeddedFaqAsset
                   .where(asset_id: article.id, asset_type: 'Article', parent_type: 'Article')
                   .joins('INNER JOIN articles ON articles.id = embedded_assets.parent_id')
                   .where(articles: { type: 'Post' })
                   .includes(:parent)
                   .order(:created_at)
end

#crm_post_path(post) ⇒ String

Returns CRM path to the post.

Parameters:

  • post (Article::Post)

    the blog post embedding the FAQ

Returns:

  • (String)

    CRM path to the post



104
105
106
# File 'app/components/crm/faq_rendered_where_component.rb', line 104

def crm_post_path(post)
  helpers.post_path(post)
end

#derive_landing_path_from_tag(tag) ⇒ String

Fallback when DigitalAsset mapping unavailable: remove for- prefix and -page suffix, convert hyphens to slashes

Parameters:

  • tag (String)

    the landing page tag (e.g. for-bathroom-page)

Returns:

  • (String)

    the derived landing page path



81
82
83
84
# File 'app/components/crm/faq_rendered_where_component.rb', line 81

def derive_landing_path_from_tag(tag)
  page_slug = tag.sub(/\Afor-/, "").sub(/-page\z/, "")
  "/#{page_slug.tr('-', '/')}"
end

#landing_page_pathsArray<String>

Returns landing page paths derived from the article's for-*-page tags.

Returns:

  • (Array<String>)

    landing page paths derived from the article's for-*-page tags



69
70
71
72
73
74
75
76
# File 'app/components/crm/faq_rendered_where_component.rb', line 69

def landing_page_paths
  tag_to_path = defined?(DigitalAsset) ? DigitalAsset.available_page_tags_with_paths : {}
  article.tags.filter_map do |tag|
    next unless tag.to_s.match?(LANDING_PAGE_TAG_PATTERN)

    tag_to_path[tag.to_s].presence || derive_landing_path_from_tag(tag.to_s)
  end.uniq
end

#post_title(post) ⇒ String

Returns the post title, falling back to its subject.

Parameters:

  • post (Article::Post)

    the blog post embedding the FAQ

Returns:

  • (String)

    the post title, falling back to its subject



118
119
120
# File 'app/components/crm/faq_rendered_where_component.rb', line 118

def post_title(post)
  post.title.presence || post.subject
end

#product_line_urlsArray<Hash>

Returns sales product line URLs (:url, :path) where the FAQ appears.

Returns:

  • (Array<Hash>)

    sales product line URLs (:url, :path) where the FAQ appears



51
52
53
54
55
# File 'app/components/crm/faq_rendered_where_component.rb', line 51

def product_line_urls
  return [] unless article.sales? && article.product_lines.any?

  article.product_lines.map { |pl| { url: pl.slug_ltree.to_s, path: "/#{pl.canonical_path}" } }.uniq { |h| h[:url] }
end

#public_post_url(post) ⇒ String?

Returns public URL of the post, or nil when unpublished or slugless.

Parameters:

  • post (Article::Post)

    the blog post embedding the FAQ

Returns:

  • (String, nil)

    public URL of the post, or nil when unpublished or slugless



110
111
112
113
114
# File 'app/components/crm/faq_rendered_where_component.rb', line 110

def public_post_url(post)
  return nil unless post.published? && post.slug.present?

  "#{WEB_URL}/#{post.slug}"
end

#standalone_locationHash?

Returns path and public URL of the standalone FAQ page, or nil when unpublished.

Returns:

  • (Hash, nil)

    path and public URL of the standalone FAQ page, or nil when unpublished



34
35
36
37
38
# File 'app/components/crm/faq_rendered_where_component.rb', line 34

def standalone_location
  return nil unless article.slug.present? && article.published?

  { path: "/faqs/#{article.slug}", url: "#{WEB_URL}/faqs/#{article.slug}" }
end

#support_urlsArray<Hash>

Returns support product line URLs (:url, :path) where the FAQ appears.

Returns:

  • (Array<Hash>)

    support product line URLs (:url, :path) where the FAQ appears



58
59
60
61
62
63
64
65
66
# File 'app/components/crm/faq_rendered_where_component.rb', line 58

def support_urls
  return [] unless article.support? && article.product_lines.any?

  article.product_lines.filter_map do |pl|
    next unless pl.canonical_path

    { url: pl.slug_ltree.to_s, path: "/#{pl.canonical_path}/support" }
  end.uniq { |h| h[:url] }
end

#total_locationsInteger

Returns total number of locations where the FAQ appears.

Returns:

  • (Integer)

    total number of locations where the FAQ appears



87
88
89
90
91
92
93
94
95
# File 'app/components/crm/faq_rendered_where_component.rb', line 87

def total_locations
  count = 0
  count += 1 if standalone_location.present?
  count += blog_embeds.size
  count += product_line_urls.size
  count += support_urls.size
  count += landing_page_paths.size
  count
end

#word_countInteger

Returns word count of the FAQ body.

Returns:

  • (Integer)

    word count of the FAQ body



98
99
100
# File 'app/components/crm/faq_rendered_where_component.rb', line 98

def word_count
  article.faq_word_count
end