page_structured_data 1.0.8 → 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 +4 -4
- data/CHANGELOG.md +12 -0
- data/README.md +57 -4
- data/app/src/page_structured_data/page.rb +16 -3
- data/app/src/page_structured_data/page_types/organization.rb +6 -2
- data/app/src/page_structured_data/page_types/web_site.rb +49 -0
- data/app/views/page_structured_data/_meta_tags.html.erb +5 -1
- data/lib/page_structured_data/version.rb +1 -1
- data/lib/page_structured_data.rb +1 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 58a57c3e6e31ccb80b40dcdc78ccc467b18bb6f377982f70eadd2d84a20f8308
|
|
4
|
+
data.tar.gz: e7b26474f2cdcfc6238c67c39ea87072965b7a07857692068267c4542a4a997a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: eb867392c1857beb772a52294d82ef8229551429b9655c93a79fec3a1193cfba6ce14eeec5bb42741734f938f611a05ce9029120ec9b9936c31bb0060d4b4b47
|
|
7
|
+
data.tar.gz: 18dcb10a552cf8cec3dd2ca3ec9300a40024c808f491f03a04ab5fe7090350516b46b347fc182ab930ac4ec6c91667f8061f1de3d95f793b0c3cf35f06c63aba
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,18 @@ 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
|
+
|
|
14
|
+
## 1.0.9 - 2026-05-06
|
|
15
|
+
|
|
16
|
+
- Add release preparation script and release checklist documentation.
|
|
17
|
+
- Add `to_h` schema hash API for organization page types.
|
|
18
|
+
|
|
7
19
|
## 1.0.8 - 2026-05-06
|
|
8
20
|
|
|
9
21
|
- Add `PageStructuredData::PageTypes::Organization` for schema.org Organization JSON-LD.
|
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
|
-
##
|
|
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
|
|
|
@@ -272,8 +303,28 @@ PageStructuredData::PageTypes::Organization.new(
|
|
|
272
303
|
|
|
273
304
|
Important methods:
|
|
274
305
|
|
|
306
|
+
- `to_h`: returns a structured hash for organization JSON-LD.
|
|
275
307
|
- `json_ld`: returns an organization JSON-LD script tag.
|
|
276
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
|
+
|
|
277
328
|
## Development
|
|
278
329
|
|
|
279
330
|
Run the test suite:
|
|
@@ -288,6 +339,8 @@ Verify the gem can be required:
|
|
|
288
339
|
ruby -Ilib -e 'require "page_structured_data"; puts PageStructuredData::VERSION'
|
|
289
340
|
```
|
|
290
341
|
|
|
342
|
+
Release instructions are documented in [docs/release.md](docs/release.md).
|
|
343
|
+
|
|
291
344
|
## Compatibility Policy
|
|
292
345
|
|
|
293
346
|
This gem is used in production applications. Changes should preserve existing public APIs and rendered output unless a breaking change is intentionally released in a major version.
|
|
@@ -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 <<
|
|
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
|
|
@@ -14,7 +14,7 @@ module PageStructuredData
|
|
|
14
14
|
@parent_organization = parent_organization
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
def
|
|
17
|
+
def to_h # rubocop:disable Metrics/MethodLength
|
|
18
18
|
node = {
|
|
19
19
|
'@context': 'https://schema.org',
|
|
20
20
|
'@type': 'Organization',
|
|
@@ -33,9 +33,13 @@ module PageStructuredData
|
|
|
33
33
|
}
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
+
node
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def json_ld
|
|
36
40
|
%(
|
|
37
41
|
<script type="application/ld+json">
|
|
38
|
-
#{
|
|
42
|
+
#{to_h.to_json}
|
|
39
43
|
</script>
|
|
40
44
|
)
|
|
41
45
|
end
|
|
@@ -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&.
|
|
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 %>">
|
data/lib/page_structured_data.rb
CHANGED
|
@@ -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.
|
|
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
|