Class: PostPresenter
Instance Attribute Summary
#current_account, #options, #url_helper
Instance Method Summary
collapse
#can?, #capture, #concat, #content_tag, #fa_icon, #h, #initialize, #link_to, #number_to_currency, #present, presents, #r, #safe_present, #simple_format, #u
Constructor Details
This class inherits a constructor from BasePresenter
Instance Method Details
#article_body(preview_mode: false) ⇒ Object
58
59
60
|
# File 'app/presenters/post_presenter.rb', line 58
def article_body(preview_mode: false)
localized_solution_with_toc(preview_mode: preview_mode).body
end
|
#article_body_desc ⇒ Object
72
73
74
|
# File 'app/presenters/post_presenter.rb', line 72
def article_body_desc
h.truncate(post&.description || stripped_article_body, length: 300)
end
|
#article_published_at ⇒ Object
166
167
168
169
|
# File 'app/presenters/post_presenter.rb', line 166
def article_published_at
r.effective_published_date&.to_datetime
end
|
#article_published_at_formatted ⇒ Object
171
172
173
174
175
|
# File 'app/presenters/post_presenter.rb', line 171
def article_published_at_formatted
return unless article_published_at
article_published_at.strftime('%B %-d, %Y')
end
|
#article_revised_at ⇒ Object
177
178
179
|
# File 'app/presenters/post_presenter.rb', line 177
def article_revised_at
r.revised_at&.to_datetime
end
|
#article_revised_at_formatted ⇒ Object
181
182
183
184
185
|
# File 'app/presenters/post_presenter.rb', line 181
def article_revised_at_formatted
return unless article_revised_at
article_revised_at.strftime('%B %-d, %Y')
end
|
#article_section ⇒ Object
204
205
206
207
|
# File 'app/presenters/post_presenter.rb', line 204
def article_section
r.meta_keywords&.split(',')&.first&.strip.presence || r.tags&.first.presence || 'Uncategorized'
end
|
#article_tags ⇒ Object
197
198
199
200
201
202
|
# File 'app/presenters/post_presenter.rb', line 197
def article_tags
keywords = r.meta_keywords&.split(',')&.map(&:strip)
keywords = r.tags if keywords.blank?
(keywords || []).reject { |t| t.to_s.start_with?('for-') }
end
|
#article_toc(preview_mode: false) ⇒ Object
54
55
56
|
# File 'app/presenters/post_presenter.rb', line 54
def article_toc(preview_mode: false)
localized_solution_with_toc(preview_mode: preview_mode).toc
end
|
#author_name ⇒ Object
113
114
115
116
117
|
# File 'app/presenters/post_presenter.rb', line 113
def author_name
return 'https://www.facebook.com/WarmlyYours/' unless r.author&.full_name
r.author&.full_name
end
|
159
160
161
162
163
164
|
# File 'app/presenters/post_presenter.rb', line 159
def
'@WarmlyYours'
end
|
#breadcrumbs_hash ⇒ Object
16
17
18
19
20
21
22
23
24
25
26
27
|
# File 'app/presenters/post_presenter.rb', line 16
def breadcrumbs_hash
bc_array = [{ name: 'Radiant Journal', url: h.cms_link('/posts') }]
custom_breadcrumbs = r.breadcrumbs_hash.dup
if custom_breadcrumbs.blank? && (main_tag = r.main_public_tag)
tag_title, tag = Post.category_tags_for_select.detect { |to| to[1] == main_tag }
bc_array << { name: tag_title, url: h.cms_link("/posts/#{tag}/tag") } if tag_title && tag
else
bc_array.concat(custom_breadcrumbs)
end
bc_array
end
|
#cache_key ⇒ Object
8
9
10
|
# File 'app/presenters/post_presenter.rb', line 8
def cache_key
"#{I18n.locale}/#{post.cache_key}"
end
|
#canonical_link ⇒ Object
76
77
78
|
# File 'app/presenters/post_presenter.rb', line 76
def canonical_link
h.cms_link(h.post_url(r), strip_params: true)
end
|
#get_image ⇒ Object
48
49
50
51
52
|
# File 'app/presenters/post_presenter.rb', line 48
def get_image
return unless r.preview_image
h.og_image_asset_url(r.preview_image)
end
|
#get_keywords ⇒ Object
12
13
14
|
# File 'app/presenters/post_presenter.rb', line 12
def get_keywords
r.meta_keywords.presence || r.tags&.join(', ')
end
|
#localized_solution_with_toc(preview_mode: false) ⇒ Object
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
|
# File 'app/presenters/post_presenter.rb', line 209
def localized_solution_with_toc(preview_mode: false)
s = OpenStruct.new(body: localized_solution(nil, preview_mode: preview_mode), toc: nil, body_html_doc: nil)
return s unless r.has_toc
doc = localized_solution_html_doc(preview_mode: preview_mode)
= doc.css(toc_selector.presence || 'h2')
toc = {}
.each do |element|
next unless (title = element.text.strip.presence)
element_anchor = element.text.parameterize
toc[title] = element_anchor
h.content_tag(:a, title, name: element_anchor)
element['id'] = element_anchor
end
s.body_html_doc = doc
s.body = doc.at('body')&.inner_html.presence&.html_safe
s.toc = h.render(partial: '/posts/toc', locals: { toc: toc })
s
end
|
132
133
134
135
136
137
138
|
# File 'app/presenters/post_presenter.rb', line 132
def meta_description(max_length: 160)
description = r.meta_description.presence
description ||= r.description.presence
description ||= r.subject.presence
h.truncate(description, length: max_length, separator: ' ')
end
|
140
141
142
|
# File 'app/presenters/post_presenter.rb', line 140
def meta_keywords
r.meta_keywords.presence || r.tags&.join(', ').presence
end
|
105
106
107
|
# File 'app/presenters/post_presenter.rb', line 105
def
r..size
end
|
#preview_image_presenter ⇒ Object
42
43
44
45
46
|
# File 'app/presenters/post_presenter.rb', line 42
def preview_image_presenter
return unless r.preview_image
h.present(r.preview_image, Www::ImagePresenter)
end
|
#publish_label ⇒ Object
187
188
189
190
191
192
193
194
195
|
# File 'app/presenters/post_presenter.rb', line 187
def publish_label
return unless article_published_at
if article_revised_at && article_revised_at > article_published_at
"Updated on #{article_revised_at_formatted}"
else
"Published on #{article_published_at_formatted}"
end
end
|
#quick_links_hash ⇒ Object
29
30
31
32
33
34
35
36
37
38
39
40
|
# File 'app/presenters/post_presenter.rb', line 29
def quick_links_hash
ql_array = breadcrumbs_hash.dup
if breadcrumbs_hash.any? { |h| h[:url].match?(/floor|indoor-heating/) }
ql_array << { name: 'Instant Quote', url: h.cms_link('/floor-heating/quote-builder') }
ql_array << { name: 'Running Costs', url: h.cms_link('/floor-heating/cost-calculator') }
end
if breadcrumbs_hash.any? { |h| h[:url].match?(%r{/snow-melting|outdoor-heating}) }
ql_array << { name: 'Instant Quote', url: h.cms_link('/snow-melting/quote-builder') }
ql_array << { name: 'Running Costs', url: h.cms_link('/snow-melting/cost-calculator') }
end
ql_array.uniq { |h| h[:url] }.sort_by { |h| h[:name] }
end
|
#reading_time_in_minutes ⇒ Object
68
69
70
|
# File 'app/presenters/post_presenter.rb', line 68
def reading_time_in_minutes
(stripped_article_body.to_s.split.size / 200.0).ceil
end
|
#render_body(preview_mode: false) ⇒ Object
80
81
82
83
84
85
86
87
88
89
90
91
92
|
# File 'app/presenters/post_presenter.rb', line 80
def render_body(preview_mode: false)
locale = I18n.locale
body = Liquid::ParseEnvironment.parse(article_body(preview_mode: preview_mode).to_s).render(
'preview_mode' => preview_mode,
'locale' => locale.to_s,
'canada' => %i[en-CA fr-CA].include?(locale),
'usa' => locale == :'en-US'
)
return body if preview_mode
Seo::ImageOptimizer.new.process(body).html_out
end
|
#render_description ⇒ Object
94
95
96
97
98
99
100
101
102
103
|
# File 'app/presenters/post_presenter.rb', line 94
def render_description
return unless r.description.present?
locale = I18n.locale
Liquid::ParseEnvironment.parse(r.description.to_s).render(
'locale' => locale.to_s,
'canada' => %i[en-CA fr-CA].include?(locale),
'usa' => locale == :'en-US'
).html_safe
end
|
#schema_dot_org_structure ⇒ Object
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
|
# File 'app/presenters/post_presenter.rb', line 232
def schema_dot_org_structure
wc = word_count.to_i
schema = SchemaDotOrg::BlogPosting.new(
identifier: id.to_s,
headline: subject,
name: subject,
description: meta_description,
articleBody: stripped_article_body,
keywords: article_tags,
wordcount: wc.positive? ? wc.to_s : nil,
inLanguage: I18n.locale.to_s.tr('_', '-'),
datePublished: r.effective_published_date,
dateModified: r.effective_revised_date,
dateCreated: created_at,
articleSection: article_section,
mainEntityOfPage: canon_link,
url: canon_link,
author: build_author_schema,
publisher: build_publisher_schema,
image: build_image_schema,
comment:
)
schema.id_iri = canon_link
schema
end
|
#stripped_article_body ⇒ Object
62
63
64
65
66
|
# File 'app/presenters/post_presenter.rb', line 62
def stripped_article_body
parsed_body = Liquid::ParseEnvironment.parse(article_body.to_s)
stripped_body = h.strip_tags(parsed_body.render)
stripped_body&.tr('"', '”')
end
|
#to_json_ld ⇒ Object
258
259
260
|
# File 'app/presenters/post_presenter.rb', line 258
def to_json_ld
schema_dot_org_structure.to_s
end
|
#user_image ⇒ Object
119
120
121
122
123
|
# File 'app/presenters/post_presenter.rb', line 119
def user_image
return unless r.author&.email
"https://www.gravatar.com/avatar/#{Digest::MD5.hexdigest(r.author&.email&.presence)}.jpg"
end
|
#user_image_tag ⇒ Object
125
126
127
128
129
130
|
# File 'app/presenters/post_presenter.rb', line 125
def user_image_tag
img_url = user_image_url(size: '90x90>')
return unless img_url
h.image_tag(img_url, alt: r.author&.full_name, class: 'img-fluid', width: 90, height: 90)
end
|
#user_image_url(size: '90x90>') ⇒ Object
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
# File 'app/presenters/post_presenter.rb', line 144
def user_image_url(size: '90x90>')
return unless r.author
if (pp = r.author&.profile_image)
pp.image_url(size: size)
elsif (email = r.author&.email&.presence)
require 'digest/md5'
hash = Digest::MD5.hexdigest(email.downcase)
"https://www.gravatar.com/avatar/#{hash}.jpg"
else
nil
end
end
|
#word_count ⇒ Object
109
110
111
|
# File 'app/presenters/post_presenter.rb', line 109
def word_count
r.localized_solution&.presence&.scan(/\w+/)&.size
end
|