Class: Www::AuthorPresenter

Inherits:
BasePresenter show all
Defined in:
app/presenters/www/author_presenter.rb

Overview

Presenter responsible for emitting Schema.org Person for public author pages

Instance Attribute Summary

Attributes inherited from BasePresenter

#current_account, #options, #url_helper

Delegated Instance Attributes collapse

Methods inherited from BasePresenter

#can?, #capture, #concat, #content_tag, #fa_icon, #link_to, #number_to_currency, #simple_format

Instance Method Summary collapse

Methods inherited from BasePresenter

#initialize

Methods inherited from BasePresenter

#h, #initialize, #present, presents, #r, #safe_present, #u

Constructor Details

This class inherits a constructor from Www::BasePresenter

Instance Method Details

Combined social links with company fallbacks (for author show page)

Returns:

  • (Hash{Symbol => String})

    social URLs keyed by network



128
129
130
131
132
133
134
135
136
137
138
# File 'app/presenters/www/author_presenter.rb', line 128

def combined_social_links
  personal = personal_social_links
  company = h.company_social_links
  {
    facebook: personal['facebook'] || company[:facebook],
    instagram: personal['instagram'] || company[:instagram],
    twitter: personal['twitter'] || company[:twitter],
    linkedin: personal['linkedin'] || company[:linkedin],
    website: personal['website']
  }.compact
end

#departmentString?

Department from the employee record.

Returns:

  • (String, nil)

    department name



99
100
101
# File 'app/presenters/www/author_presenter.rb', line 99

def department
  employee.employee_record&.department
end

#employee_nameString

Employee's full name.

Returns:

  • (String)

    full name



87
88
89
# File 'app/presenters/www/author_presenter.rb', line 87

def employee_name
  employee.full_name
end

#formatted_post_date(post) ⇒ String?

Post date formatted for display.

Parameters:

  • post (Post)

    the post

Returns:

  • (String, nil)

    long-form date



163
164
165
# File 'app/presenters/www/author_presenter.rb', line 163

def (post)
  post.effective_revised_date&.to_date&.to_fs(:long)
end

#hire_yearInteger?

Year the employee was hired.

Returns:

  • (Integer, nil)

    hire year



105
106
107
# File 'app/presenters/www/author_presenter.rb', line 105

def hire_year
  employee.employee_record&.hire_date&.year
end

#job_titleString?

Job title from the employee record.

Returns:

  • (String, nil)

    job title



93
94
95
# File 'app/presenters/www/author_presenter.rb', line 93

def job_title
  employee.employee_record&.job_title
end

#latest_postPost?

Latest published post for this author

Returns:

  • (Post, nil)

    most recent published post



142
143
144
145
146
147
148
149
150
# File 'app/presenters/www/author_presenter.rb', line 142

def latest_post
  return employee.latest_post if employee.respond_to?(:latest_post) && employee.latest_post

  Post.published
      .where(original_author_id: employee.id)
      .order(published_at: :desc, created_at: :desc)
      .select(:id, :slug, :subject, :published_at, :revised_at, :created_at)
      .first
end

Personal social links only

Returns:

  • (Hash{String => String})

    category => URL map



111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'app/presenters/www/author_presenter.rb', line 111

def personal_social_links
  employee.contact_points
          .by_category([
                         ContactPoint::LINKEDIN,
                         ContactPoint::TWITTER,
                         ContactPoint::FACEBOOK,
                         ContactPoint::INSTAGRAM,
                         ContactPoint::WEBSITE
                       ])
          .pluck(:category, :detail)
          .to_h
rescue StandardError
  {}
end

#profile_imageObject

Alias for Employee#profile_image

Returns:

  • (Object)

    Employee#profile_image

See Also:



71
# File 'app/presenters/www/author_presenter.rb', line 71

delegate :profile_image, to: :employee

#profile_image_url(width: 600, height: 600, thumbnail: true) ⇒ String?

Profile image URL

Parameters:

  • width (Integer) (defaults to: 600)

    requested image width

  • height (Integer) (defaults to: 600)

    requested image height

  • thumbnail (Boolean) (defaults to: true)

    request a thumbnail rendition

Returns:

  • (String, nil)

    image URL, or nil without a profile image



78
79
80
81
82
83
# File 'app/presenters/www/author_presenter.rb', line 78

def profile_image_url(width: 600, height: 600, thumbnail: true)
  pp = profile_image
  return unless pp

  pp.image_url(width: width, height: height, thumbnail: thumbnail)
end

#profile_urlString?

Public profile URL for the author page

Returns:

  • (String, nil)

    absolute author URL, or nil when no author page



65
66
67
68
69
# File 'app/presenters/www/author_presenter.rb', line 65

def profile_url
  return unless employee.employee_record&.author_page?

  "#{WEB_URL}/authors/#{employee.employee_record.slug}"
end

#published_posts_countInteger

Number of published posts by this author.

Returns:

  • (Integer)

    published post count



154
155
156
157
158
# File 'app/presenters/www/author_presenter.rb', line 154

def published_posts_count
  return employee.published_posts_count if employee.respond_to?(:published_posts_count)

  Post.published.where(original_author_id: employee.id).count
end

#schema_dot_org_structureSchemaDotOrg::Person

Build full Schema.org Person including profile URL, image and sameAs links

Returns:



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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
# File 'app/presenters/www/author_presenter.rb', line 10

def schema_dot_org_structure
  SchemaDotOrg::Person.new.tap do |p|
    p.givenName = employee.first_name
    p.familyName = employee.last_name
    p.name = employee.full_name

    begin
      p.url = h.author_url(employee.employee_record)
    rescue StandardError
      # ignore URL errors in presenter
    end

    if (pp = employee.profile_image)
      p.image = SchemaDotOrg::ImageObject.new(url: pp.image_url(width: 800))
    end

    links = begin
      employee.contact_points
              .by_category([
                             ContactPoint::LINKEDIN,
                             ContactPoint::TWITTER,
                             ContactPoint::FACEBOOK,
                             ContactPoint::INSTAGRAM,
                             ContactPoint::WEBSITE
                           ])
              .pluck(:detail)
              .compact
              .uniq
    rescue StandardError
      []
    end
    p.sameAs = links if links.present?

    # Include work address from associated company
    if (addr = employee.company&.address)
      p.address = SchemaDotOrg::PostalAddress.new(
        streetAddress: [addr.street1, addr.street2, addr.street3].compact_blank.join(' '),
        addressLocality: addr.city,
        addressRegion: addr.state_code,
        postalCode: addr.zip_compact,
        addressCountry: addr.country&.iso
      )
    end

    # Company association for active employees
    begin
      p.worksFor = h.online_store_schema unless employee.inactive
    rescue StandardError
      # ignore if helper not available in this context
    end
  end
end