page_structured_data 1.0.9 → 1.0.11
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 +11 -0
- data/README.md +64 -5
- data/app/src/page_structured_data/page.rb +16 -3
- data/app/src/page_structured_data/page_types/organization.rb +14 -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: 9ffd04020a9a4ba900bb7d4bbdac9dd827d48535073a30c657865469df9e1988
|
|
4
|
+
data.tar.gz: 4b560fee8a434599acd2ae619fdc7e4a0973f29aa77f8b95191a270047767931
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '08329eddfdf9f7e3682a6016ca84d25b1867e4ce8ebca4c4e7654536b4dff59b8d825351b4489b69342c42d2cc52ab41d96bba1f3cc8adf5a1f8180330d660ba'
|
|
7
|
+
data.tar.gz: 270c98e7c0071b9e09e75482a5d766ec685f8a7da103c3ddb15f4df03e895b98fcc52d57e50b93cbfddd992de7d0fbdf6d5de9542b07fec52d0eab977da2903f
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,17 @@ All notable changes to this project are documented here.
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
## 1.0.11 - 2026-05-06
|
|
8
|
+
|
|
9
|
+
- Add optional `description` and `founder` support to organization page types.
|
|
10
|
+
|
|
11
|
+
## 1.0.10 - 2026-05-06
|
|
12
|
+
|
|
13
|
+
- Add JSON-LD escaping coverage for organization page types.
|
|
14
|
+
- Add `PageStructuredData::PageTypes::WebSite` for schema.org WebSite JSON-LD.
|
|
15
|
+
- Add `page_types:` support for rendering multiple page type JSON-LD scripts.
|
|
16
|
+
- Add `canonical_url` and `fallback_image` options to `Page`.
|
|
17
|
+
|
|
7
18
|
## 1.0.9 - 2026-05-06
|
|
8
19
|
|
|
9
20
|
- 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
|
-
##
|
|
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
|
|
|
@@ -176,8 +179,14 @@ Use `Organization` when the current page represents an organization:
|
|
|
176
179
|
organization_page_type = PageStructuredData::PageTypes::Organization.new(
|
|
177
180
|
name: "RocketApex",
|
|
178
181
|
url: "https://rocketapex.com",
|
|
182
|
+
description: "Open source projects from RocketApex",
|
|
179
183
|
logo: "https://rocketapex.com/logo.png",
|
|
180
184
|
same_as: ["https://github.com/RocketApex"],
|
|
185
|
+
founder: {
|
|
186
|
+
"@type": "Person",
|
|
187
|
+
name: "Jane Doe",
|
|
188
|
+
url: "https://example.com/jane"
|
|
189
|
+
},
|
|
181
190
|
parent_organization: {
|
|
182
191
|
name: "Parent Org",
|
|
183
192
|
url: "https://parent.example"
|
|
@@ -191,6 +200,30 @@ organization_page_type = PageStructuredData::PageTypes::Organization.new(
|
|
|
191
200
|
)
|
|
192
201
|
```
|
|
193
202
|
|
|
203
|
+
Use `WebSite` with `Organization` when the current page represents a site or homepage:
|
|
204
|
+
|
|
205
|
+
```ruby
|
|
206
|
+
organization_page_type = PageStructuredData::PageTypes::Organization.new(
|
|
207
|
+
name: "RocketApex",
|
|
208
|
+
url: "https://rocketapex.com",
|
|
209
|
+
logo: "https://rocketapex.com/logo.png"
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
website_page_type = PageStructuredData::PageTypes::WebSite.new(
|
|
213
|
+
name: "RocketApex",
|
|
214
|
+
url: "https://rocketapex.com",
|
|
215
|
+
description: "Open source projects from RocketApex",
|
|
216
|
+
publisher: organization_page_type
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
@page_meta = PageStructuredData::Page.new(
|
|
220
|
+
title: "RocketApex",
|
|
221
|
+
description: "Open source projects from RocketApex",
|
|
222
|
+
canonical_url: "https://rocketapex.com",
|
|
223
|
+
page_types: [organization_page_type, website_page_type]
|
|
224
|
+
)
|
|
225
|
+
```
|
|
226
|
+
|
|
194
227
|
## API Reference
|
|
195
228
|
|
|
196
229
|
### `PageStructuredData::Page`
|
|
@@ -202,7 +235,10 @@ PageStructuredData::Page.new(
|
|
|
202
235
|
image: nil,
|
|
203
236
|
extra_title: "",
|
|
204
237
|
breadcrumb: nil,
|
|
205
|
-
page_type: nil
|
|
238
|
+
page_type: nil,
|
|
239
|
+
page_types: nil,
|
|
240
|
+
canonical_url: nil,
|
|
241
|
+
fallback_image: nil
|
|
206
242
|
)
|
|
207
243
|
```
|
|
208
244
|
|
|
@@ -210,6 +246,7 @@ Important methods:
|
|
|
210
246
|
|
|
211
247
|
- `page_title`: returns the composed page title.
|
|
212
248
|
- `json_lds`: returns the JSON-LD script tags for breadcrumbs and page type data.
|
|
249
|
+
- `resolved_image`: returns `image` or `fallback_image`.
|
|
213
250
|
|
|
214
251
|
### `PageStructuredData::Breadcrumbs`
|
|
215
252
|
|
|
@@ -262,19 +299,41 @@ Important methods:
|
|
|
262
299
|
PageStructuredData::PageTypes::Organization.new(
|
|
263
300
|
name:,
|
|
264
301
|
url:,
|
|
302
|
+
description: nil,
|
|
265
303
|
logo: nil,
|
|
266
304
|
same_as: [],
|
|
267
|
-
parent_organization: nil
|
|
305
|
+
parent_organization: nil,
|
|
306
|
+
founder: nil
|
|
268
307
|
)
|
|
269
308
|
```
|
|
270
309
|
|
|
271
310
|
`parent_organization` should be a hash with `:name` and `:url` keys.
|
|
311
|
+
`founder` should be a hash or another object that responds to `to_h`.
|
|
272
312
|
|
|
273
313
|
Important methods:
|
|
274
314
|
|
|
275
315
|
- `to_h`: returns a structured hash for organization JSON-LD.
|
|
276
316
|
- `json_ld`: returns an organization JSON-LD script tag.
|
|
277
317
|
|
|
318
|
+
### WebSite Page Type
|
|
319
|
+
|
|
320
|
+
```ruby
|
|
321
|
+
PageStructuredData::PageTypes::WebSite.new(
|
|
322
|
+
name:,
|
|
323
|
+
url:,
|
|
324
|
+
description: nil,
|
|
325
|
+
publisher: nil,
|
|
326
|
+
potential_action: nil
|
|
327
|
+
)
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
`publisher` can be a hash or another page type that responds to `to_h`, such as `PageStructuredData::PageTypes::Organization`.
|
|
331
|
+
|
|
332
|
+
Important methods:
|
|
333
|
+
|
|
334
|
+
- `to_h`: returns a structured hash for WebSite JSON-LD.
|
|
335
|
+
- `json_ld`: returns a WebSite JSON-LD script tag.
|
|
336
|
+
|
|
278
337
|
## Development
|
|
279
338
|
|
|
280
339
|
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 <<
|
|
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
|
|
@@ -4,14 +4,16 @@ module PageStructuredData
|
|
|
4
4
|
module PageTypes
|
|
5
5
|
# Organization structured data for a page
|
|
6
6
|
class Organization
|
|
7
|
-
attr_reader :name, :url, :logo, :same_as, :parent_organization
|
|
7
|
+
attr_reader :name, :url, :description, :logo, :same_as, :parent_organization, :founder
|
|
8
8
|
|
|
9
|
-
def initialize(name:, url:, logo: nil, same_as: [], parent_organization: nil)
|
|
9
|
+
def initialize(name:, url:, description: nil, logo: nil, same_as: [], parent_organization: nil, founder: nil)
|
|
10
10
|
@name = name
|
|
11
11
|
@url = url
|
|
12
|
+
@description = description
|
|
12
13
|
@logo = logo
|
|
13
14
|
@same_as = same_as
|
|
14
15
|
@parent_organization = parent_organization
|
|
16
|
+
@founder = founder
|
|
15
17
|
end
|
|
16
18
|
|
|
17
19
|
def to_h # rubocop:disable Metrics/MethodLength
|
|
@@ -22,8 +24,10 @@ module PageStructuredData
|
|
|
22
24
|
|
|
23
25
|
node[:name] = name
|
|
24
26
|
node[:url] = url
|
|
27
|
+
node[:description] = description if description.present?
|
|
25
28
|
node[:logo] = logo if logo.present?
|
|
26
29
|
node[:sameAs] = same_as if same_as.present?
|
|
30
|
+
node[:founder] = founder_to_h if founder.present?
|
|
27
31
|
|
|
28
32
|
if parent_organization.present?
|
|
29
33
|
node[:parentOrganization] = {
|
|
@@ -43,6 +47,14 @@ module PageStructuredData
|
|
|
43
47
|
</script>
|
|
44
48
|
)
|
|
45
49
|
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def founder_to_h
|
|
54
|
+
return founder.to_h if founder.respond_to?(:to_h)
|
|
55
|
+
|
|
56
|
+
founder
|
|
57
|
+
end
|
|
46
58
|
end
|
|
47
59
|
end
|
|
48
60
|
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.11
|
|
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
|