page_structured_data 1.0.11 → 1.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9ffd04020a9a4ba900bb7d4bbdac9dd827d48535073a30c657865469df9e1988
4
- data.tar.gz: 4b560fee8a434599acd2ae619fdc7e4a0973f29aa77f8b95191a270047767931
3
+ metadata.gz: 8e263a2b3ad541c2b5e72aa79e71d47d72803ddb8a4ac286898e6c6f35105394
4
+ data.tar.gz: 96f01f8fc820456eb69ba5a351f8971022758088d0a5633240c38c7831df43f9
5
5
  SHA512:
6
- metadata.gz: '08329eddfdf9f7e3682a6016ca84d25b1867e4ce8ebca4c4e7654536b4dff59b8d825351b4489b69342c42d2cc52ab41d96bba1f3cc8adf5a1f8180330d660ba'
7
- data.tar.gz: 270c98e7c0071b9e09e75482a5d766ec685f8a7da103c3ddb15f4df03e895b98fcc52d57e50b93cbfddd992de7d0fbdf6d5de9542b07fec52d0eab977da2903f
6
+ metadata.gz: 802b70166a18b5475e702822cfb7b0c565c7fc59d8dd5059831261676831e1150c95b8f0e1e11b0de493aa120f3e23f2ddd9a619238ebcdd5f25c8f3920d3d6e
7
+ data.tar.gz: bc818be71ea5d603ac3fb6b84e99dcf79fd76607f3272039cde49d65c772f365d812c0f7d260cdf7beda88762012994ae207b309e7a5dc21b94ab129608e0c9e
data/CHANGELOG.md CHANGED
@@ -4,6 +4,20 @@ All notable changes to this project are documented here.
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 1.0.13 - 2026-05-06
8
+
9
+ - Add `PageStructuredData::PageTypes::Person` for reusable schema.org person values.
10
+ - Accept richer article author values and omit blank nested schema fields.
11
+ - Add page-level `base_app_name` and `render_breadcrumb_json_ld` options.
12
+ - Omit blank description and image meta tags.
13
+
14
+ ## 1.0.12 - 2026-05-06
15
+
16
+ - Add reusable interaction statistics for article-like page types.
17
+ - Add `PageStructuredData::PageTypes::DiscussionForumPosting` for forum-style posts.
18
+ - Render Twitter Card meta tags with `name` attributes.
19
+ - Update gem metadata to mention Organization and WebSite JSON-LD support.
20
+
7
21
  ## 1.0.11 - 2026-05-06
8
22
 
9
23
  - Add optional `description` and `founder` support to organization page types.
data/README.md CHANGED
@@ -14,6 +14,9 @@ It helps Rails applications render:
14
14
  - Google-compatible JSON-LD structured data
15
15
  - Breadcrumb structured data
16
16
  - Article structured data for `BlogPosting` and `NewsArticle`
17
+ - Discussion forum post structured data
18
+ - Interaction statistics for public engagement counts
19
+ - Reusable Person structured data
17
20
  - Organization and WebSite structured data
18
21
 
19
22
  ## Requirements
@@ -141,6 +144,8 @@ PageStructuredData includes page types for:
141
144
 
142
145
  - [`BlogPosting`](https://schema.org/BlogPosting)
143
146
  - [`NewsArticle`](https://schema.org/NewsArticle)
147
+ - [`DiscussionForumPosting`](https://schema.org/DiscussionForumPosting)
148
+ - [`Person`](https://schema.org/Person)
144
149
  - [`Organization`](https://schema.org/Organization)
145
150
  - [`WebSite`](https://schema.org/WebSite)
146
151
 
@@ -173,6 +178,42 @@ article_page_type = PageStructuredData::PageTypes::BlogPosting.new(
173
178
 
174
179
  For news pages, use `PageStructuredData::PageTypes::NewsArticle` with the same arguments.
175
180
 
181
+ Article-like page types can include public engagement counts as interaction statistics:
182
+
183
+ ```ruby
184
+ article_page_type = PageStructuredData::PageTypes::BlogPosting.new(
185
+ headline: @article.title,
186
+ published_at: @article.published_at,
187
+ updated_at: @article.updated_at,
188
+ likes_count: @article.likes_count,
189
+ comments_count: @article.comments_count,
190
+ shares_count: @article.shares_count
191
+ )
192
+ ```
193
+
194
+ Only include engagement counts that are public and visible on the rendered page.
195
+
196
+ Use `DiscussionForumPosting` when the current page represents a public user-authored forum or community post:
197
+
198
+ ```ruby
199
+ forum_post_page_type = PageStructuredData::PageTypes::DiscussionForumPosting.new(
200
+ headline: @post.title,
201
+ text: @post.content_plaintext,
202
+ url: post_url(@post),
203
+ published_at: @post.created_at,
204
+ updated_at: @post.updated_at,
205
+ authors: [
206
+ {
207
+ name: @post.user.name,
208
+ url: user_url(@post.user)
209
+ }
210
+ ],
211
+ interaction_statistics: [
212
+ PageStructuredData::PageTypes::InteractionStatistic.comment(@post.comments_count)
213
+ ]
214
+ )
215
+ ```
216
+
176
217
  Use `Organization` when the current page represents an organization:
177
218
 
178
219
  ```ruby
@@ -238,10 +279,15 @@ PageStructuredData::Page.new(
238
279
  page_type: nil,
239
280
  page_types: nil,
240
281
  canonical_url: nil,
241
- fallback_image: nil
282
+ fallback_image: nil,
283
+ base_app_name: nil,
284
+ render_breadcrumb_json_ld: nil
242
285
  )
243
286
  ```
244
287
 
288
+ `base_app_name` overrides `PageStructuredData.base_app_name` for one page. Pass an empty string to suppress the global app name for a specific page.
289
+ `render_breadcrumb_json_ld` can be set to `true` or `false` for one page. Leave it as `nil` to use the global `PageStructuredData.render_default_breadcrumb_json_ld` behavior for generated default breadcrumbs. Explicit breadcrumb objects still render when the global default is disabled unless the page sets `render_breadcrumb_json_ld: false`.
290
+
245
291
  Important methods:
246
292
 
247
293
  - `page_title`: returns the composed page title.
@@ -272,7 +318,15 @@ PageStructuredData::PageTypes::BlogPosting.new(
272
318
  published_at:,
273
319
  updated_at:,
274
320
  images: [],
275
- authors: []
321
+ authors: [],
322
+ image: nil,
323
+ article_body: nil,
324
+ text: nil,
325
+ url: nil,
326
+ interaction_statistics: [],
327
+ likes_count: nil,
328
+ comments_count: nil,
329
+ shares_count: nil
276
330
  )
277
331
  ```
278
332
 
@@ -282,17 +336,94 @@ PageStructuredData::PageTypes::NewsArticle.new(
282
336
  published_at:,
283
337
  updated_at:,
284
338
  images: [],
285
- authors: []
339
+ authors: [],
340
+ image: nil,
341
+ article_body: nil,
342
+ text: nil,
343
+ url: nil,
344
+ interaction_statistics: [],
345
+ likes_count: nil,
346
+ comments_count: nil,
347
+ shares_count: nil
286
348
  )
287
349
  ```
288
350
 
289
- `authors` should be an array of hashes with `:name` and `:url` keys.
351
+ `authors` can be an array of hashes, `PageStructuredData::PageTypes::Person` objects, or other objects that respond to `to_h`.
352
+ `image` is a convenience option for one image URL. Use `images` when passing multiple image URLs.
353
+ `text` is an alias for `article_body`.
354
+ `interaction_statistics` should be an array of `PageStructuredData::PageTypes::InteractionStatistic` objects or schema-compatible hashes.
290
355
 
291
356
  Important methods:
292
357
 
293
358
  - `to_h`: returns a structured hash for article JSON-LD.
294
359
  - `json_ld`: returns an article JSON-LD script tag.
295
360
 
361
+ ```ruby
362
+ PageStructuredData::PageTypes::DiscussionForumPosting.new(
363
+ headline:,
364
+ published_at:,
365
+ updated_at:,
366
+ images: [],
367
+ authors: [],
368
+ image: nil,
369
+ article_body: nil,
370
+ text: nil,
371
+ url: nil,
372
+ interaction_statistics: [],
373
+ likes_count: nil,
374
+ comments_count: nil,
375
+ shares_count: nil
376
+ )
377
+ ```
378
+
379
+ ### Interaction Statistics
380
+
381
+ ```ruby
382
+ PageStructuredData::PageTypes::InteractionStatistic.new(
383
+ interaction_type: :like,
384
+ user_interaction_count: 42,
385
+ interaction_service: nil
386
+ )
387
+ ```
388
+
389
+ Convenience constructors are also available:
390
+
391
+ ```ruby
392
+ PageStructuredData::PageTypes::InteractionStatistic.like(42)
393
+ PageStructuredData::PageTypes::InteractionStatistic.comment(12)
394
+ PageStructuredData::PageTypes::InteractionStatistic.share(7)
395
+ ```
396
+
397
+ Supported shorthand interaction types are `:like`, `:comment`, and `:share`. Custom schema.org action types can be passed as strings or hashes.
398
+
399
+ Important methods:
400
+
401
+ - `to_h`: returns a structured hash for `InteractionCounter` JSON-LD.
402
+
403
+ ### Person
404
+
405
+ ```ruby
406
+ PageStructuredData::PageTypes::Person.new(
407
+ name:,
408
+ url: nil,
409
+ image: nil,
410
+ same_as: []
411
+ )
412
+ ```
413
+
414
+ Use `Person` for article authors, organization founders, and other schema.org person values:
415
+
416
+ ```ruby
417
+ author = PageStructuredData::PageTypes::Person.new(
418
+ name: "Jane Doe",
419
+ url: "https://example.com/jane"
420
+ )
421
+ ```
422
+
423
+ Important methods:
424
+
425
+ - `to_h`: returns a compact structured hash for `Person` JSON-LD.
426
+
296
427
  ### Organization Page Type
297
428
 
298
429
  ```ruby
@@ -4,11 +4,11 @@ module PageStructuredData
4
4
  # Basic page metadata for any page
5
5
  class Page
6
6
  attr_reader :title, :description, :image, :extra_title, :breadcrumb, :page_type, :page_types, :canonical_url,
7
- :fallback_image
7
+ :fallback_image, :base_app_name, :render_breadcrumb_json_ld
8
8
 
9
9
  def initialize(title:, description: nil, image: nil, # rubocop:disable Metrics/ParameterLists
10
10
  extra_title: '', breadcrumb: nil, page_type: nil, page_types: nil, canonical_url: nil,
11
- fallback_image: nil)
11
+ fallback_image: nil, base_app_name: nil, render_breadcrumb_json_ld: nil)
12
12
  @title = title
13
13
  @description = description
14
14
  @image = image
@@ -18,6 +18,8 @@ module PageStructuredData
18
18
  @page_types = page_types
19
19
  @canonical_url = canonical_url
20
20
  @fallback_image = fallback_image
21
+ @base_app_name = base_app_name
22
+ @render_breadcrumb_json_ld = render_breadcrumb_json_ld
21
23
  end
22
24
 
23
25
  def title_with_hierarchies
@@ -28,8 +30,8 @@ module PageStructuredData
28
30
 
29
31
  def page_title
30
32
  result = title_with_hierarchies.join(separator)
31
- if base_app_name.present?
32
- result += separator + base_app_name
33
+ if resolved_base_app_name.present?
34
+ result += separator + resolved_base_app_name
33
35
  end
34
36
  result
35
37
  end
@@ -52,13 +54,22 @@ module PageStructuredData
52
54
  end
53
55
 
54
56
  def breadcrumb_json_ld
57
+ return if render_breadcrumb_json_ld == false
55
58
  return breadcrumb.json_ld(current_page_title: title) if breadcrumb.present?
56
- return unless PageStructuredData.render_default_breadcrumb_json_ld
59
+ return unless render_breadcrumb_json_ld?
57
60
 
58
61
  Breadcrumbs.new.json_ld(current_page_title: title)
59
62
  end
60
63
 
61
- def base_app_name
64
+ def render_breadcrumb_json_ld?
65
+ return render_breadcrumb_json_ld unless render_breadcrumb_json_ld.nil?
66
+
67
+ PageStructuredData.render_default_breadcrumb_json_ld
68
+ end
69
+
70
+ def resolved_base_app_name
71
+ return base_app_name unless base_app_name.nil?
72
+
62
73
  PageStructuredData.base_app_name
63
74
  end
64
75
 
@@ -4,32 +4,42 @@ module PageStructuredData
4
4
  module PageTypes
5
5
  # Shared structured data for schema.org article-like page types.
6
6
  class Article
7
- attr_reader :headline, :images, :published_at, :updated_at, :authors
7
+ include SchemaNode
8
8
 
9
- def initialize(headline:, published_at:, updated_at:, images: [], authors: [])
9
+ attr_reader :headline, :images, :published_at, :updated_at, :authors, :article_body, :url,
10
+ :interaction_statistics, :likes_count, :comments_count, :shares_count
11
+
12
+ def initialize(headline:, published_at:, updated_at:, images: [], authors: [], image: nil, article_body: nil, text: nil,
13
+ url: nil, interaction_statistics: [], likes_count: nil, comments_count: nil, shares_count: nil)
10
14
  @headline = headline
11
- @images = images
15
+ @images = image.present? ? Array(image) : Array(images)
12
16
  @published_at = published_at
13
17
  @updated_at = updated_at
14
- @authors = authors
18
+ @authors = Array(authors)
19
+ @article_body = article_body || text
20
+ @url = url
21
+ @interaction_statistics = Array(interaction_statistics)
22
+ @likes_count = likes_count
23
+ @comments_count = comments_count
24
+ @shares_count = shares_count
15
25
  end
16
26
 
17
27
  def to_h
18
- {
28
+ node = {
19
29
  '@context': 'https://schema.org',
20
30
  '@type': schema_type,
21
31
  headline: headline,
22
32
  image: images,
23
33
  datePublished: published_at,
24
34
  dateModified: updated_at,
25
- author: authors.map do |author|
26
- {
27
- '@type': 'Person',
28
- name: author[:name],
29
- url: author[:url],
30
- }
31
- end,
35
+ author: authors.map { |author| author_to_h(author) },
32
36
  }
37
+
38
+ node[:articleBody] = article_body if article_body.present?
39
+ node[:url] = url if url.present?
40
+ node[:interactionStatistic] = interaction_statistics_to_h if interaction_statistics_to_h.any?
41
+
42
+ node
33
43
  end
34
44
 
35
45
  def json_ld
@@ -45,6 +55,46 @@ module PageStructuredData
45
55
  def schema_type
46
56
  raise NotImplementedError, "#{self.class.name} must define #schema_type"
47
57
  end
58
+
59
+ def author_to_h(author)
60
+ return object_to_h(author) if author.respond_to?(:to_h) && !author.is_a?(Hash)
61
+
62
+ compact_node(
63
+ '@type': 'Person',
64
+ name: author[:name] || author['name'],
65
+ url: author[:url] || author['url'],
66
+ image: author[:image] || author['image'],
67
+ sameAs: author[:same_as] || author[:sameAs] || author['same_as'] || author['sameAs']
68
+ )
69
+ end
70
+
71
+ def interaction_statistics_to_h
72
+ @interaction_statistics_to_h ||= all_interaction_statistics.map do |interaction_statistic|
73
+ if interaction_statistic.respond_to?(:to_h)
74
+ interaction_statistic.to_h
75
+ else
76
+ interaction_statistic
77
+ end
78
+ end
79
+ end
80
+
81
+ def all_interaction_statistics
82
+ interaction_statistics + count_interaction_statistics
83
+ end
84
+
85
+ def count_interaction_statistics
86
+ [
87
+ count_interaction_statistic(:like, likes_count),
88
+ count_interaction_statistic(:comment, comments_count),
89
+ count_interaction_statistic(:share, shares_count),
90
+ ].compact
91
+ end
92
+
93
+ def count_interaction_statistic(interaction_type, count)
94
+ return if count.nil?
95
+
96
+ InteractionStatistic.new(interaction_type: interaction_type, user_interaction_count: count)
97
+ end
48
98
  end
49
99
  end
50
100
  end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PageStructuredData
4
+ module PageTypes
5
+ # schema.org structured data for discussion forum posts.
6
+ class DiscussionForumPosting < Article
7
+ private
8
+
9
+ def schema_type
10
+ 'DiscussionForumPosting'
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PageStructuredData
4
+ module PageTypes
5
+ # schema.org InteractionCounter structured data.
6
+ class InteractionStatistic
7
+ include SchemaNode
8
+
9
+ ACTION_TYPES = {
10
+ like: 'LikeAction',
11
+ likes: 'LikeAction',
12
+ comment: 'CommentAction',
13
+ comments: 'CommentAction',
14
+ share: 'ShareAction',
15
+ shares: 'ShareAction',
16
+ }.freeze
17
+
18
+ attr_reader :interaction_type, :user_interaction_count, :interaction_service
19
+
20
+ def self.like(user_interaction_count)
21
+ new(interaction_type: :like, user_interaction_count: user_interaction_count)
22
+ end
23
+
24
+ def self.comment(user_interaction_count)
25
+ new(interaction_type: :comment, user_interaction_count: user_interaction_count)
26
+ end
27
+
28
+ def self.share(user_interaction_count)
29
+ new(interaction_type: :share, user_interaction_count: user_interaction_count)
30
+ end
31
+
32
+ def initialize(interaction_type:, user_interaction_count:, interaction_service: nil)
33
+ @interaction_type = interaction_type
34
+ @user_interaction_count = user_interaction_count
35
+ @interaction_service = interaction_service
36
+ end
37
+
38
+ def to_h
39
+ compact_node(
40
+ '@type': 'InteractionCounter',
41
+ interactionType: interaction_type_to_h,
42
+ userInteractionCount: user_interaction_count,
43
+ interactionService: object_to_h(interaction_service)
44
+ )
45
+ end
46
+
47
+ private
48
+
49
+ def interaction_type_to_h
50
+ return object_to_h(interaction_type) if interaction_type.respond_to?(:to_h)
51
+
52
+ type = ACTION_TYPES.fetch(interaction_type.to_s.to_sym, interaction_type.to_s)
53
+
54
+ { '@type': type }
55
+ end
56
+ end
57
+ end
58
+ end
@@ -4,6 +4,8 @@ module PageStructuredData
4
4
  module PageTypes
5
5
  # Organization structured data for a page
6
6
  class Organization
7
+ include SchemaNode
8
+
7
9
  attr_reader :name, :url, :description, :logo, :same_as, :parent_organization, :founder
8
10
 
9
11
  def initialize(name:, url:, description: nil, logo: nil, same_as: [], parent_organization: nil, founder: nil)
@@ -11,33 +13,23 @@ module PageStructuredData
11
13
  @url = url
12
14
  @description = description
13
15
  @logo = logo
14
- @same_as = same_as
16
+ @same_as = Array(same_as)
15
17
  @parent_organization = parent_organization
16
18
  @founder = founder
17
19
  end
18
20
 
19
21
  def to_h # rubocop:disable Metrics/MethodLength
20
- node = {
22
+ compact_node(
21
23
  '@context': 'https://schema.org',
22
24
  '@type': 'Organization',
23
- }
24
-
25
- node[:name] = name
26
- node[:url] = url
27
- node[:description] = description if description.present?
28
- node[:logo] = logo if logo.present?
29
- node[:sameAs] = same_as if same_as.present?
30
- node[:founder] = founder_to_h if founder.present?
31
-
32
- if parent_organization.present?
33
- node[:parentOrganization] = {
34
- '@type': 'Organization',
35
- name: parent_organization[:name],
36
- url: parent_organization[:url],
37
- }
38
- end
39
-
40
- node
25
+ name: name,
26
+ url: url,
27
+ description: description,
28
+ logo: logo,
29
+ sameAs: same_as,
30
+ founder: object_to_h(founder),
31
+ parentOrganization: parent_organization_to_h
32
+ )
41
33
  end
42
34
 
43
35
  def json_ld
@@ -50,10 +42,15 @@ module PageStructuredData
50
42
 
51
43
  private
52
44
 
53
- def founder_to_h
54
- return founder.to_h if founder.respond_to?(:to_h)
45
+ def parent_organization_to_h
46
+ return object_to_h(parent_organization) if parent_organization.respond_to?(:to_h) && !parent_organization.is_a?(Hash)
47
+ return unless parent_organization.present?
55
48
 
56
- founder
49
+ compact_node(
50
+ '@type': 'Organization',
51
+ name: parent_organization[:name] || parent_organization['name'],
52
+ url: parent_organization[:url] || parent_organization['url']
53
+ )
57
54
  end
58
55
  end
59
56
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PageStructuredData
4
+ module PageTypes
5
+ # schema.org Person structured data.
6
+ class Person
7
+ include SchemaNode
8
+
9
+ attr_reader :name, :url, :image, :same_as
10
+
11
+ def initialize(name:, url: nil, image: nil, same_as: [])
12
+ @name = name
13
+ @url = url
14
+ @image = image
15
+ @same_as = Array(same_as)
16
+ end
17
+
18
+ def to_h
19
+ compact_node(
20
+ '@type': 'Person',
21
+ name: name,
22
+ url: url,
23
+ image: image,
24
+ sameAs: same_as
25
+ )
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PageStructuredData
4
+ module PageTypes
5
+ # Shared helpers for schema.org hash values.
6
+ module SchemaNode
7
+ private
8
+
9
+ def compact_node(node)
10
+ node.each_with_object({}) do |(key, value), compacted|
11
+ next if blank_schema_value?(value)
12
+
13
+ compacted[key] = value
14
+ end
15
+ end
16
+
17
+ def object_to_h(object)
18
+ return object.to_h if object.respond_to?(:to_h)
19
+
20
+ object
21
+ end
22
+
23
+ def blank_schema_value?(value)
24
+ value.nil? || (value.respond_to?(:empty?) && value.empty?)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -4,6 +4,8 @@ module PageStructuredData
4
4
  module PageTypes
5
5
  # WebSite structured data for a page
6
6
  class WebSite
7
+ include SchemaNode
8
+
7
9
  attr_reader :name, :url, :description, :publisher, :potential_action
8
10
 
9
11
  def initialize(name:, url:, description: nil, publisher: nil, potential_action: nil)
@@ -15,18 +17,15 @@ module PageStructuredData
15
17
  end
16
18
 
17
19
  def to_h
18
- node = {
20
+ compact_node(
19
21
  '@context': 'https://schema.org',
20
22
  '@type': 'WebSite',
21
23
  name: name,
22
24
  url: url,
23
- }
24
-
25
- node[:description] = description if description.present?
26
- node[:publisher] = publisher_to_h if publisher.present?
27
- node[:potentialAction] = potential_action if potential_action.present?
28
-
29
- node
25
+ description: description,
26
+ publisher: object_to_h(publisher),
27
+ potentialAction: object_to_h(potential_action)
28
+ )
30
29
  end
31
30
 
32
31
  def json_ld
@@ -37,13 +36,6 @@ module PageStructuredData
37
36
  )
38
37
  end
39
38
 
40
- private
41
-
42
- def publisher_to_h
43
- return publisher.to_h if publisher.respond_to?(:to_h)
44
-
45
- publisher
46
- end
47
39
  end
48
40
  end
49
41
  end
@@ -11,16 +11,28 @@
11
11
  <% end %>
12
12
 
13
13
  <meta name="title" content="<%= title %>">
14
+ <% if description.present? %>
14
15
  <meta name="description" content="<%= description %>">
16
+ <% end %>
17
+ <% if image.present? %>
15
18
  <meta name="image" content="<%= image %>">
19
+ <% end %>
16
20
 
17
21
  <meta property="og:title" content="<%= title %>">
22
+ <% if description.present? %>
18
23
  <meta property="og:description" content="<%= description %>">
24
+ <% end %>
25
+ <% if image.present? %>
19
26
  <meta property="og:image" content="<%= image %>">
27
+ <% end %>
20
28
 
21
- <meta property="twitter:card" content="summary_large_image">
22
- <meta property="twitter:title" content="<%= title %>">
23
- <meta property="twitter:description" content="<%= description %>">
24
- <meta property="twitter:image" content="<%= image %>">
29
+ <meta name="twitter:card" content="summary_large_image">
30
+ <meta name="twitter:title" content="<%= title %>">
31
+ <% if description.present? %>
32
+ <meta name="twitter:description" content="<%= description %>">
33
+ <% end %>
34
+ <% if image.present? %>
35
+ <meta name="twitter:image" content="<%= image %>">
36
+ <% end %>
25
37
 
26
38
  <%= page&.json_lds&.html_safe %>
@@ -1,3 +1,3 @@
1
1
  module PageStructuredData
2
- VERSION = "1.0.11"
2
+ VERSION = "1.0.13"
3
3
  end
@@ -2,9 +2,13 @@ require "page_structured_data/version"
2
2
  require "page_structured_data/engine"
3
3
  require_relative "../app/src/page_structured_data/anchors"
4
4
  require_relative "../app/src/page_structured_data/breadcrumbs"
5
+ require_relative "../app/src/page_structured_data/page_types/schema_node"
6
+ require_relative "../app/src/page_structured_data/page_types/person"
7
+ require_relative "../app/src/page_structured_data/page_types/interaction_statistic"
5
8
  require_relative "../app/src/page_structured_data/page_types/article"
6
9
  require_relative "../app/src/page_structured_data/page_types/blog_posting"
7
10
  require_relative "../app/src/page_structured_data/page_types/news_article"
11
+ require_relative "../app/src/page_structured_data/page_types/discussion_forum_posting"
8
12
  require_relative "../app/src/page_structured_data/page_types/organization"
9
13
  require_relative "../app/src/page_structured_data/page_types/web_site"
10
14
  require_relative "../app/src/page_structured_data/page"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: page_structured_data
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.11
4
+ version: 1.0.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jey Geethan
@@ -32,7 +32,8 @@ dependencies:
32
32
  version: '9.0'
33
33
  description: PageStructuredData gives Rails applications a small page object and view
34
34
  partial for rendering page titles, basic meta tags, Open Graph tags, Twitter card
35
- tags, breadcrumb JSON-LD, and article JSON-LD.
35
+ tags, breadcrumb JSON-LD, article and forum post JSON-LD, Person, Organization,
36
+ and WebSite JSON-LD, and public interaction statistics.
36
37
  email:
37
38
  - opensource@rocketapex.com
38
39
  executables: []
@@ -48,8 +49,12 @@ files:
48
49
  - app/src/page_structured_data/page.rb
49
50
  - app/src/page_structured_data/page_types/article.rb
50
51
  - app/src/page_structured_data/page_types/blog_posting.rb
52
+ - app/src/page_structured_data/page_types/discussion_forum_posting.rb
53
+ - app/src/page_structured_data/page_types/interaction_statistic.rb
51
54
  - app/src/page_structured_data/page_types/news_article.rb
52
55
  - app/src/page_structured_data/page_types/organization.rb
56
+ - app/src/page_structured_data/page_types/person.rb
57
+ - app/src/page_structured_data/page_types/schema_node.rb
53
58
  - app/src/page_structured_data/page_types/web_site.rb
54
59
  - app/views/page_structured_data/_meta_tags.html.erb
55
60
  - config/routes.rb