page_structured_data 1.0.9 → 1.0.10

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: 53bab1f6112cc7060c86d1eedc6096770ea5a6363a9d4e9939094f3576a417cf
4
- data.tar.gz: ecea9e6efd8b44bf45565ec1a790905b55e7794579a91d2b157dec1325ad89c5
3
+ metadata.gz: 58a57c3e6e31ccb80b40dcdc78ccc467b18bb6f377982f70eadd2d84a20f8308
4
+ data.tar.gz: e7b26474f2cdcfc6238c67c39ea87072965b7a07857692068267c4542a4a997a
5
5
  SHA512:
6
- metadata.gz: fda27db244422de502060211a86f759ca0fe7249a8a370fb7d3f7a89ed2f732181eff65d7c8b19ab48a61cc9be4168dae18c14edb1016d2ba7d97941b343c50b
7
- data.tar.gz: 78dcbcefc064a3806f41c8f8d83f1943181e05c260501a207cff31ff425f5ad68e2fcf6d436351e4a58ded9c2c4ee12b4768d0f1f27c822951bde8682b4f381d
6
+ metadata.gz: eb867392c1857beb772a52294d82ef8229551429b9655c93a79fec3a1193cfba6ce14eeec5bb42741734f938f611a05ce9029120ec9b9936c31bb0060d4b4b47
7
+ data.tar.gz: 18dcb10a552cf8cec3dd2ca3ec9300a40024c808f491f03a04ab5fe7090350516b46b347fc182ab930ac4ec6c91667f8061f1de3d95f793b0c3cf35f06c63aba
data/CHANGELOG.md CHANGED
@@ -4,6 +4,13 @@ All notable changes to this project are documented here.
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 1.0.10 - 2026-05-06
8
+
9
+ - Add JSON-LD escaping coverage for organization page types.
10
+ - Add `PageStructuredData::PageTypes::WebSite` for schema.org WebSite JSON-LD.
11
+ - Add `page_types:` support for rendering multiple page type JSON-LD scripts.
12
+ - Add `canonical_url` and `fallback_image` options to `Page`.
13
+
7
14
  ## 1.0.9 - 2026-05-06
8
15
 
9
16
  - Add release preparation script and release checklist documentation.
data/README.md CHANGED
@@ -14,7 +14,7 @@ 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
- - Organization structured data
17
+ - Organization and WebSite structured data
18
18
 
19
19
  ## Requirements
20
20
 
@@ -93,7 +93,9 @@ Set `@page_meta` in the controller or view before the layout renders:
93
93
  title: "Home",
94
94
  extra_title: "Official Page",
95
95
  description: "Welcome to my page",
96
- image: image_url("social/home.png")
96
+ image: image_url("social/home.png"),
97
+ canonical_url: home_url,
98
+ fallback_image: image_url("social/default.png")
97
99
  )
98
100
  ```
99
101
 
@@ -133,13 +135,14 @@ This renders `BreadcrumbList` JSON-LD similar to Google's breadcrumb structured
133
135
 
134
136
  Current compatibility note: when no breadcrumb object is passed, `PageStructuredData::Page` renders current-page-only breadcrumb JSON-LD by default. To opt out, set `config.render_default_breadcrumb_json_ld = false`.
135
137
 
136
- ## Article Page Types
138
+ ## Structured Page Types
137
139
 
138
140
  PageStructuredData includes page types for:
139
141
 
140
142
  - [`BlogPosting`](https://schema.org/BlogPosting)
141
143
  - [`NewsArticle`](https://schema.org/NewsArticle)
142
144
  - [`Organization`](https://schema.org/Organization)
145
+ - [`WebSite`](https://schema.org/WebSite)
143
146
 
144
147
  Use a page type when the current page represents an article:
145
148
 
@@ -191,6 +194,30 @@ organization_page_type = PageStructuredData::PageTypes::Organization.new(
191
194
  )
192
195
  ```
193
196
 
197
+ Use `WebSite` with `Organization` when the current page represents a site or homepage:
198
+
199
+ ```ruby
200
+ organization_page_type = PageStructuredData::PageTypes::Organization.new(
201
+ name: "RocketApex",
202
+ url: "https://rocketapex.com",
203
+ logo: "https://rocketapex.com/logo.png"
204
+ )
205
+
206
+ website_page_type = PageStructuredData::PageTypes::WebSite.new(
207
+ name: "RocketApex",
208
+ url: "https://rocketapex.com",
209
+ description: "Open source projects from RocketApex",
210
+ publisher: organization_page_type
211
+ )
212
+
213
+ @page_meta = PageStructuredData::Page.new(
214
+ title: "RocketApex",
215
+ description: "Open source projects from RocketApex",
216
+ canonical_url: "https://rocketapex.com",
217
+ page_types: [organization_page_type, website_page_type]
218
+ )
219
+ ```
220
+
194
221
  ## API Reference
195
222
 
196
223
  ### `PageStructuredData::Page`
@@ -202,7 +229,10 @@ PageStructuredData::Page.new(
202
229
  image: nil,
203
230
  extra_title: "",
204
231
  breadcrumb: nil,
205
- page_type: nil
232
+ page_type: nil,
233
+ page_types: nil,
234
+ canonical_url: nil,
235
+ fallback_image: nil
206
236
  )
207
237
  ```
208
238
 
@@ -210,6 +240,7 @@ Important methods:
210
240
 
211
241
  - `page_title`: returns the composed page title.
212
242
  - `json_lds`: returns the JSON-LD script tags for breadcrumbs and page type data.
243
+ - `resolved_image`: returns `image` or `fallback_image`.
213
244
 
214
245
  ### `PageStructuredData::Breadcrumbs`
215
246
 
@@ -275,6 +306,25 @@ Important methods:
275
306
  - `to_h`: returns a structured hash for organization JSON-LD.
276
307
  - `json_ld`: returns an organization JSON-LD script tag.
277
308
 
309
+ ### WebSite Page Type
310
+
311
+ ```ruby
312
+ PageStructuredData::PageTypes::WebSite.new(
313
+ name:,
314
+ url:,
315
+ description: nil,
316
+ publisher: nil,
317
+ potential_action: nil
318
+ )
319
+ ```
320
+
321
+ `publisher` can be a hash or another page type that responds to `to_h`, such as `PageStructuredData::PageTypes::Organization`.
322
+
323
+ Important methods:
324
+
325
+ - `to_h`: returns a structured hash for WebSite JSON-LD.
326
+ - `json_ld`: returns a WebSite JSON-LD script tag.
327
+
278
328
  ## Development
279
329
 
280
330
  Run the test suite:
@@ -3,16 +3,21 @@
3
3
  module PageStructuredData
4
4
  # Basic page metadata for any page
5
5
  class Page
6
- attr_reader :title, :description, :image, :extra_title, :breadcrumb, :page_type
6
+ attr_reader :title, :description, :image, :extra_title, :breadcrumb, :page_type, :page_types, :canonical_url,
7
+ :fallback_image
7
8
 
8
9
  def initialize(title:, description: nil, image: nil, # rubocop:disable Metrics/ParameterLists
9
- extra_title: '', breadcrumb: nil, page_type: nil)
10
+ extra_title: '', breadcrumb: nil, page_type: nil, page_types: nil, canonical_url: nil,
11
+ fallback_image: nil)
10
12
  @title = title
11
13
  @description = description
12
14
  @image = image
13
15
  @extra_title = extra_title
14
16
  @breadcrumb = breadcrumb
15
17
  @page_type = page_type
18
+ @page_types = page_types
19
+ @canonical_url = canonical_url
20
+ @fallback_image = fallback_image
16
21
  end
17
22
 
18
23
  def title_with_hierarchies
@@ -32,12 +37,20 @@ module PageStructuredData
32
37
  def json_lds
33
38
  output = []
34
39
  output << breadcrumb_json_ld if (breadcrumb_json_ld = self.breadcrumb_json_ld).present?
35
- output << page_type.json_ld if page_type.present?
40
+ resolved_page_types.each { |resolved_page_type| output << resolved_page_type.json_ld }
36
41
  output.join
37
42
  end
38
43
 
44
+ def resolved_image
45
+ image || fallback_image
46
+ end
47
+
39
48
  private
40
49
 
50
+ def resolved_page_types
51
+ Array.wrap(page_types.presence || page_type).compact
52
+ end
53
+
41
54
  def breadcrumb_json_ld
42
55
  return breadcrumb.json_ld(current_page_title: title) if breadcrumb.present?
43
56
  return unless PageStructuredData.render_default_breadcrumb_json_ld
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PageStructuredData
4
+ module PageTypes
5
+ # WebSite structured data for a page
6
+ class WebSite
7
+ attr_reader :name, :url, :description, :publisher, :potential_action
8
+
9
+ def initialize(name:, url:, description: nil, publisher: nil, potential_action: nil)
10
+ @name = name
11
+ @url = url
12
+ @description = description
13
+ @publisher = publisher
14
+ @potential_action = potential_action
15
+ end
16
+
17
+ def to_h
18
+ node = {
19
+ '@context': 'https://schema.org',
20
+ '@type': 'WebSite',
21
+ name: name,
22
+ 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
30
+ end
31
+
32
+ def json_ld
33
+ %(
34
+ <script type="application/ld+json">
35
+ #{to_h.to_json}
36
+ </script>
37
+ )
38
+ end
39
+
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
+ end
48
+ end
49
+ end
@@ -2,9 +2,13 @@
2
2
 
3
3
  <% title = page&.page_title %>
4
4
  <% description = page&.description %>
5
- <% image = page&.image || default_image_url || nil %>
5
+ <% image = page&.resolved_image || default_image_url || nil %>
6
+ <% canonical_url = page&.canonical_url %>
6
7
 
7
8
  <title><%= title %></title>
9
+ <% if canonical_url.present? %>
10
+ <link rel="canonical" href="<%= canonical_url %>">
11
+ <% end %>
8
12
 
9
13
  <meta name="title" content="<%= title %>">
10
14
  <meta name="description" content="<%= description %>">
@@ -1,3 +1,3 @@
1
1
  module PageStructuredData
2
- VERSION = "1.0.9"
2
+ VERSION = "1.0.10"
3
3
  end
@@ -6,6 +6,7 @@ require_relative "../app/src/page_structured_data/page_types/article"
6
6
  require_relative "../app/src/page_structured_data/page_types/blog_posting"
7
7
  require_relative "../app/src/page_structured_data/page_types/news_article"
8
8
  require_relative "../app/src/page_structured_data/page_types/organization"
9
+ require_relative "../app/src/page_structured_data/page_types/web_site"
9
10
  require_relative "../app/src/page_structured_data/page"
10
11
 
11
12
  module PageStructuredData
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.9
4
+ version: 1.0.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jey Geethan
@@ -50,6 +50,7 @@ files:
50
50
  - app/src/page_structured_data/page_types/blog_posting.rb
51
51
  - app/src/page_structured_data/page_types/news_article.rb
52
52
  - app/src/page_structured_data/page_types/organization.rb
53
+ - app/src/page_structured_data/page_types/web_site.rb
53
54
  - app/views/page_structured_data/_meta_tags.html.erb
54
55
  - config/routes.rb
55
56
  - lib/page_structured_data.rb