Class: Www::MagazineBlogCardComponent

Inherits:
ApplicationComponent show all
Includes:
ActionView::Helpers::TagHelper, ActionView::Helpers::UrlHelper
Defined in:
app/components/www/magazine_blog_card_component.rb

Delegated Instance Attributes collapse

Methods inherited from ApplicationComponent

#cms_link, #image_asset_tag, #image_tag, #number_to_currency, #number_with_delimiter, #post_url, #strip_tags

Instance Method Summary collapse

Methods inherited from ApplicationComponent

#fetch_or_fallback

Constructor Details

#initialize(post:, variant: :default, show_reading_time: true, show_author: true, heading_level: :h3) ⇒ MagazineBlogCardComponent

Returns a new instance of MagazineBlogCardComponent.

Parameters:

  • post (Post)

    The blog post to display

  • variant (Symbol) (defaults to: :default)

    :default for grid cards, :hero for featured hero card

  • show_reading_time (Boolean) (defaults to: true)

    Whether to show reading time badge

  • show_author (Boolean) (defaults to: true)

    Whether to show author info

  • heading_level (Symbol) (defaults to: :h3)

    :h2 or :h3 — set according to the parent page's heading hierarchy



12
13
14
15
16
17
18
19
# File 'app/components/www/magazine_blog_card_component.rb', line 12

def initialize(post:, variant: :default, show_reading_time: true, show_author: true, heading_level: :h3)
  super()
  @post = post
  @variant = variant
  @show_reading_time = show_reading_time
  @show_author = show_author
  @heading_level = heading_level
end

Instance Method Details

#author_first_nameObject



48
49
50
# File 'app/components/www/magazine_blog_card_component.rb', line 48

def author_first_name
  @post.author&.first_name || 'WarmlyYours'
end

#author_full_nameObject



52
53
54
# File 'app/components/www/magazine_blog_card_component.rb', line 52

def author_full_name
  @post.author&.name || 'WarmlyYours Team'
end

#author_thumbnail?Boolean

Returns:

  • (Boolean)


71
72
73
# File 'app/components/www/magazine_blog_card_component.rb', line 71

def author_thumbnail?
  author_thumbnail_url.present?
end

#author_thumbnail_urlObject

Author thumbnail URL (profile picture or Gravatar fallback)



57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'app/components/www/magazine_blog_card_component.rb', line 57

def author_thumbnail_url
  return nil unless @post.author

  # Try profile image first (consolidated storage for all party types)
  if (pp = @post.author.profile_image)
    pp.image_url(size: '48x48>')
  elsif (email = @post.author.email&.presence)
    # Gravatar fallback
    require 'digest/md5'
    hash = Digest::MD5.hexdigest(email.downcase)
    "https://www.gravatar.com/avatar/#{hash}.jpg?s=48"
  end
end

#card_classesObject



79
80
81
82
83
# File 'app/components/www/magazine_blog_card_component.rb', line 79

def card_classes
  base = 'magazine-blog-card'
  base += ' magazine-blog-card--hero' if hero?
  base
end

#description_excerptObject



96
97
98
99
100
# File 'app/components/www/magazine_blog_card_component.rb', line 96

def description_excerpt
  return nil unless hero? && @post.description.present?

  helpers.truncate(helpers.strip_tags(@post.description), length: 200)
end

#display_dateObject



32
33
34
# File 'app/components/www/magazine_blog_card_component.rb', line 32

def display_date
  @post.effective_revised_date
end

#formatted_dateObject



36
37
38
39
40
41
42
43
44
45
46
# File 'app/components/www/magazine_blog_card_component.rb', line 36

def formatted_date
  # For hero: "December 2025", for cards: "DEC 2025"
  date = display_date
  return '' unless date

  if hero?
    date.strftime('%B %Y')
  else
    date.strftime('%B %Y').upcase
  end
end

#hero?Boolean

Returns:

  • (Boolean)


75
76
77
# File 'app/components/www/magazine_blog_card_component.rb', line 75

def hero?
  @variant == :hero
end

#image_dimensionsObject



85
86
87
88
89
90
91
92
93
94
# File 'app/components/www/magazine_blog_card_component.rb', line 85

def image_dimensions
  if hero?
    # No crop_mode (skip pad_resize), use fo-auto for smart object detection
    # This produces w-1200,h-600,fo-auto - the image will center-crop to subject
    { width: 1200, height: 600, crop_mode: :none, thumbnail: true }
  else
    # Cards: skip padding, use fo-auto for smart cropping
    { width: 600, height: 400, crop_mode: :none, thumbnail: true }
  end
end

#post_pathObject



21
22
23
# File 'app/components/www/magazine_blog_card_component.rb', line 21

def post_path
  helpers.post_path(@post)
end

#preview_imageObject

Alias for @post#preview_image

Returns:

  • (Object)

    @post#preview_image

See Also:



25
# File 'app/components/www/magazine_blog_card_component.rb', line 25

delegate :preview_image, :subject, :published_at, to: :@post

#published_atObject

Alias for @post#published_at

Returns:

  • (Object)

    @post#published_at

See Also:



25
# File 'app/components/www/magazine_blog_card_component.rb', line 25

delegate :preview_image, :subject, :published_at, to: :@post

#reading_timeObject



27
28
29
30
# File 'app/components/www/magazine_blog_card_component.rb', line 27

def reading_time
  minutes = @post.reading_time_in_minutes
  "#{minutes} min read"
end

#subjectObject

Alias for @post#subject

Returns:

  • (Object)

    @post#subject

See Also:



25
# File 'app/components/www/magazine_blog_card_component.rb', line 25

delegate :preview_image, :subject, :published_at, to: :@post