schema_dot_org 2.3.3 → 2.5.0

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: 736ca556e9da839382ce55910f9729313cbd37bee13df252fdff1606af240650
4
- data.tar.gz: '08fa546126f7f829e1ee6af9358566e69fef5181afeaacb83c781741353f08af'
3
+ metadata.gz: eba4af5a8f17ea83c93f00956aeb53733a629a2a7dff60a20774f52b4682c5a2
4
+ data.tar.gz: a7f134544c69e830613e9004ac8bee7e8944637270f0f39c569d91cbd2fe1cef
5
5
  SHA512:
6
- metadata.gz: 91dda5511231e77bddf3a15eb5c73c41cbf36a4eef69cf20be03b6b803c156555aeac751bc9d0d0112316a4dec0b8faf472479b0325f69253afb6c868860ec6e
7
- data.tar.gz: cc529cd3d76bf23fb01b8273b6675c063c98b082122fcec9327fd26f428d98e35f158499fcbb20b0513fc67f2c962ccd07483e54040bf44f37f63bd2b6a6779e
6
+ metadata.gz: f840e728482eca79bca2035002fb6f1cd47fb5b41e54ec823ea17dfd6ad2988f9c51d7b82414004a39d3637ae56c80509bf2425cf4373854d00a469e35daa284
7
+ data.tar.gz: a06b1d8b8da895c7713ded7a913d6ee069ff7205ae3f4f3fe13b25bf6f6c7ee2af98fac885d761889b1a09a136f31e37c68bd4295c8ee324917558c6a6c40cca
data/.gitignore CHANGED
@@ -9,3 +9,5 @@
9
9
 
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
+
13
+ *.gem
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- schema_dot_org (2.3.3)
4
+ schema_dot_org (2.5.0)
5
5
  validated_object (~> 2.3)
6
6
 
7
7
  GEM
@@ -21,15 +21,24 @@ GEM
21
21
  tzinfo (~> 2.0)
22
22
  base64 (0.1.1)
23
23
  bigdecimal (3.1.4)
24
+ coderay (1.1.3)
24
25
  concurrent-ruby (1.2.2)
25
26
  connection_pool (2.4.1)
26
27
  diff-lcs (1.5.0)
28
+ doctest2-core (0.9.3)
29
+ doctest2-rspec (0.9.2)
30
+ doctest2-core (~> 0.9.0)
31
+ rspec (~> 3.0)
27
32
  drb (2.1.1)
28
33
  ruby2_keywords
29
34
  i18n (1.14.1)
30
35
  concurrent-ruby (~> 1.0)
36
+ method_source (1.1.0)
31
37
  minitest (5.20.0)
32
38
  mutex_m (0.1.2)
39
+ pry (0.15.2)
40
+ coderay (~> 1.1)
41
+ method_source (~> 1.0)
33
42
  rake (13.0.6)
34
43
  rspec (3.12.0)
35
44
  rspec-core (~> 3.12.0)
@@ -57,6 +66,8 @@ PLATFORMS
57
66
 
58
67
  DEPENDENCIES
59
68
  bundler (~> 2.4)
69
+ doctest2-rspec (~> 0.9.2)
70
+ pry (> 0.0.0)
60
71
  rake (~> 13.0)
61
72
  rspec (~> 3.12)
62
73
  schema_dot_org!
data/README.md CHANGED
@@ -1,19 +1,18 @@
1
- [![Gem Version](https://badge.fury.io/rb/schema_dot_org.svg)](https://badge.fury.io/rb/schema_dot_org)
2
-
3
1
  ## Table of Contents
4
2
 
5
3
  - [SchemaDotOrg](#schemadotorg)
6
- - [Usage](#usage)
7
- - [Principle: No silent failures](#principle-no-silent-failures)
8
- - [You are prevented from creating invalid markup](#you-are-prevented-from-creating-invalid-markup)
9
- - [Supported Schema.org Types](#supported-schemaorg-types)
10
- - [Examples](#examples)
11
- - [WebSite](#website)
12
- - [Organization](#organization)
13
- - [Installation](#installation)
14
- - [Development](#development)
15
- - [Contributing](#contributing)
16
- - [License](#license)
4
+ - [Usage](#usage)
5
+ - [Principle: No silent failures](#principle-no-silent-failures)
6
+ - [You are prevented from creating invalid markup](#you-are-prevented-from-creating-invalid-markup)
7
+ - [Supported Schema.org Types](#supported-schemaorg-types)
8
+ - [Examples](#examples)
9
+ - [BreadcrumbList](#breadcrumblist)
10
+ - [WebSite](#website)
11
+ - [Organization](#organization)
12
+ - [Installation](#installation)
13
+ - [Development](#development)
14
+ - [Contributing](#contributing)
15
+ - [License](#license)
17
16
 
18
17
  # SchemaDotOrg
19
18
 
@@ -24,7 +23,9 @@ Good structured data [helps enhance a website's search result appearance](https:
24
23
 
25
24
  ## Usage
26
25
 
27
- Let's say you have a Rails app. First write plain-ruby code in a helper or controller. Just instantiate
26
+ Let's say you have a Rails app. First write plain-ruby code in a helper or controller.
27
+
28
+ Here's what that'd look like in a controller. Instantiate
28
29
  the structured data object you want in your web page:
29
30
 
30
31
  ```ruby
@@ -96,7 +97,7 @@ Etc., etc.
96
97
 
97
98
  ### You are prevented from creating invalid markup
98
99
 
99
- I make mistakes. So I wanted to know that if my page loads, the markup is good.
100
+ I make mistakes. So I wanted to know that if my page loads, the markup is good. I hate "silent failures".
100
101
 
101
102
  If you use the wrong type or try to set an unknown attribute, SchemaDotOrg will
102
103
  refuse to create the incorrect JSON-LD. Instead, you'll get a message explaining
@@ -117,7 +118,7 @@ In my experience, I never get errors from the lib. I code it once, it works, and
117
118
  I move on to other things.
118
119
 
119
120
  > [!NOTE]
120
- > This automatic validation comes from my [ValidatedObject gem](https://github.com/dogweather/validated_object), which in turn,
121
+ > This automatic validation comes from my [ValidatedObject gem](https://github.com/public-law/validated_object), which in turn,
121
122
  > is a thin wrapper around ActiveRecord::Validations. So there's nothing magical going on here.
122
123
 
123
124
  ## Supported Schema.org Types
@@ -127,6 +128,7 @@ See each type's RSpec for an example of how to use it.
127
128
  | Name | Schema.org Page | RSpec Spec | Source Code |
128
129
  | ---------------------- | ------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
129
130
  | AggregateOffer | [Schema.org](https://schema.org/AggregateOffer) | | [Source](https://github.com/public-law/schema-dot-org/blob/master/lib/schema_dot_org/aggregate_offer.rb) |
131
+ | BreadcrumbList | [Schema.org](https://schema.org/BreadcrumbList) | [RSpec](https://github.com/public-law/schema-dot-org/blob/master/spec/schema_dot_org/breadcrumb_list_spec.rb) | [Source](https://github.com/public-law/schema-dot-org/blob/master/lib/schema_dot_org/breadcrumb_list.rb) |
130
132
  | CollegeOrUniversity | [Schema.org](https://schema.org/CollegeOrUniversity) | [RSpec](https://github.com/public-law/schema-dot-org/blob/master/spec/schema_dot_org/college_or_university_spec.rb) | [Source](https://github.com/public-law/schema-dot-org/blob/master/lib/schema_dot_org/college_or_university.rb) |
131
133
  | Comment | [Schema.org](https://schema.org/Comment) | [RSpec](https://github.com/public-law/schema-dot-org/blob/master/spec/schema_dot_org/comment_spec.rb) | [Source](https://github.com/public-law/schema-dot-org/blob/master/lib/schema_dot_org/comment.rb) |
132
134
  | ContactPoint | [Schema.org](https://schema.org/ContactPoint) | | [Source](https://github.com/public-law/schema-dot-org/blob/master/lib/schema_dot_org/contact_point.rb) |
@@ -145,7 +147,60 @@ See each type's RSpec for an example of how to use it.
145
147
 
146
148
  ## Examples
147
149
 
148
- Here are a few examples. [The source code for these is extremely easy to read.](https://github.com/public-law/schema-dot-org/tree/master/lib/schema_dot_org) Check them out to see all the available attributes.
150
+ ### BreadcrumbList
151
+
152
+ The `make_breadcrumbs` convenience method creates a BreadcrumbList from a simple array of hashes:
153
+
154
+ ```ruby
155
+ links = [
156
+ { name: 'Home', url: 'https://example.com' },
157
+ { name: 'Books', url: 'https://example.com/books' },
158
+ { name: 'Science Fiction', url: 'https://example.com/books/sci-fi' },
159
+ { name: 'Award Winners' } # Last item typically has no URL
160
+ ]
161
+
162
+ SchemaDotOrg
163
+ .make_breadcrumbs(links)
164
+ .to_s
165
+ ```
166
+
167
+ produces:
168
+
169
+ ```html
170
+ <script type="application/ld+json">
171
+ {
172
+ "@context": "https://schema.org",
173
+ "@type": "BreadcrumbList",
174
+ "itemListElement": [
175
+ {
176
+ "@type": "ListItem",
177
+ "position": 1,
178
+ "name": "Home",
179
+ "item": "https://example.com"
180
+ },
181
+ {
182
+ "@type": "ListItem",
183
+ "position": 2,
184
+ "name": "Books",
185
+ "item": "https://example.com/books"
186
+ },
187
+ {
188
+ "@type": "ListItem",
189
+ "position": 3,
190
+ "name": "Science Fiction",
191
+ "item": "https://example.com/books/sci-fi"
192
+ },
193
+ {
194
+ "@type": "ListItem",
195
+ "position": 4,
196
+ "name": "Award Winners"
197
+ }
198
+ ]
199
+ }
200
+ </script>
201
+ ```
202
+
203
+ URLs are automatically validated - invalid URLs will raise an `ArgumentError` with a descriptive message.
149
204
 
150
205
  ### WebSite
151
206
 
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+
4
+ #
5
+ # Model the Google / Schema.org `BreadcrumbList`.
6
+ #
7
+ # The intent is to primarily support Google's BreadcrumbList. Properties
8
+ # from Schema.org are welcome if desired.
9
+ #
10
+ # See https://developers.google.com/search/docs/appearance/structured-data/breadcrumb
11
+ # and https://schema.org/BreadcrumbList
12
+ #
13
+ module SchemaDotOrg
14
+ class BreadcrumbList < SchemaType
15
+ validated_attr :itemListElement, type: Array, presence: true
16
+ end
17
+ end
@@ -9,9 +9,22 @@ require_relative 'product'
9
9
  module SchemaDotOrg
10
10
  class ListItem < SchemaType
11
11
  validated_attr :image, type: String, allow_nil: true
12
- validated_attr :item, type: SchemaDotOrg::Product, allow_nil: true
12
+ validated_attr :item, type: Object, allow_nil: true # Allow String or SchemaType
13
13
  validated_attr :name, type: String, allow_nil: true
14
14
  validated_attr :position, type: Integer, presence: true
15
15
  validated_attr :url, type: String, allow_nil: true
16
+
17
+ validate :item_must_be_valid_type
18
+
19
+
20
+ private
21
+
22
+ def item_must_be_valid_type
23
+ return if item.nil?
24
+ return if item.is_a?(String) # URL
25
+ return if item.is_a?(SchemaDotOrg::SchemaType) # Any Schema.org type
26
+
27
+ errors.add(:item, 'must be a URL string or Schema.org object, but was: ' + item.class.name + ' (' + item.inspect + ')')
28
+ end
16
29
  end
17
30
  end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uri'
4
+
5
+ module SchemaDotOrg
6
+ # Utility module for URL validation
7
+ module UrlValidator
8
+ # Validates that a string is a proper web URL (HTTP/HTTPS with a host)
9
+ #
10
+ # @param url [String] The URL string to validate
11
+ # @return [Boolean] true if the URL is valid, false otherwise
12
+ #
13
+ # Doc Tests:
14
+ # >> SchemaDotOrg::UrlValidator.valid_web_url?('https://example.com') #=> true
15
+ # >> SchemaDotOrg::UrlValidator.valid_web_url?('http://example.com/path') #=> true
16
+ # >> SchemaDotOrg::UrlValidator.valid_web_url?('ftp://example.com') #=> false
17
+ # >> SchemaDotOrg::UrlValidator.valid_web_url?('not-a-url') #=> false
18
+ # >> SchemaDotOrg::UrlValidator.valid_web_url?('') #=> false
19
+ # >> SchemaDotOrg::UrlValidator.valid_web_url?(nil) #=> false
20
+ #
21
+ def self.valid_web_url?(url)
22
+ return false if url.nil? || url.to_s.strip.empty?
23
+
24
+ uri = URI.parse(url.to_s)
25
+
26
+ # Check for valid HTTP/HTTPS scheme
27
+ return false unless %w[http https].include?(uri.scheme)
28
+
29
+ # Check for a host
30
+ return false if uri.host.nil? || uri.host.strip.empty?
31
+
32
+ true
33
+ rescue URI::InvalidURIError
34
+ false
35
+ end
36
+ end
37
+ end
@@ -2,11 +2,42 @@
2
2
  require 'json'
3
3
  require 'validated_object'
4
4
 
5
+
6
+ module SchemaDotOrg
7
+ ##
8
+ # Make a BreadcrumbList from an array of links. This is a convenience
9
+ # method for creating a BreadcrumbList and its ListItems.
10
+ #
11
+ # @example
12
+ # SchemaDotOrg.make_breadcrumbs([
13
+ # { name: 'Home', url: 'https://example.com' },
14
+ # { name: 'Books', url: 'https://example.com/books' },
15
+ # { name: 'Science Fiction' },
16
+ # ])
17
+ #
18
+ # @param links [Array<Hash>] An array of links. Each link is a hash with
19
+ # a `:url` and `:name` key. The `:url` is optional.
20
+ # @return [BreadcrumbList] A BreadcrumbList object.
21
+ # @raise [ArgumentError] If any URL is invalid.
22
+ #
23
+ def self.make_breadcrumbs(links)
24
+ BreadcrumbList.new(itemListElement: links.map.with_index(1) do |link, index|
25
+ url = link[:url]
26
+ name = link[:name]
27
+
28
+ if !url.nil? && !UrlValidator.valid_web_url?(url)
29
+ raise ArgumentError, "URL is not a valid web URL: #{url}"
30
+ end
31
+
32
+ ListItem.new(position: index, item: url, name: name)
33
+ end)
34
+ end
35
+
36
+
5
37
  #
6
38
  # Abstract base class for all the Schema.org types.
7
39
  #
8
- module SchemaDotOrg
9
- class SchemaType < ValidatedObject::Base
40
+ class SchemaType < ValidatedObject::Base
10
41
  EXCLUDED_INSTANCE_VARIABLES = %i[@context_for_validation @validation_context @errors].freeze
11
42
  ROOT_ATTR = { "@context" => "https://schema.org" }.freeze
12
43
  UNQUALIFIED_CLASS_NAME_REGEX = /([^:]+)$/
@@ -116,6 +147,7 @@ end
116
147
 
117
148
 
118
149
  require 'schema_dot_org/aggregate_offer'
150
+ require 'schema_dot_org/breadcrumb_list'
119
151
  require 'schema_dot_org/college_or_university'
120
152
  require 'schema_dot_org/comment'
121
153
  require 'schema_dot_org/contact_point'
@@ -130,4 +162,5 @@ require 'schema_dot_org/place'
130
162
  require 'schema_dot_org/product'
131
163
  require 'schema_dot_org/offer'
132
164
  require 'schema_dot_org/search_action'
165
+ require 'schema_dot_org/url_validator'
133
166
  require 'schema_dot_org/web_site'
@@ -7,9 +7,9 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
7
7
  Gem::Specification.new do |spec|
8
8
  spec.required_ruby_version = '>= 3.0'
9
9
  spec.name = 'schema_dot_org'
10
- spec.version = '2.3.3'
11
- spec.authors = ['Robb Shecter']
12
- spec.email = ['robb@public.law']
10
+ spec.version = '2.5.0'
11
+ spec.authors = ['Robert Shecter']
12
+ spec.email = ['robert@public.law']
13
13
 
14
14
  spec.summary = 'JSON-LD generator for Schema.org vocabulary'
15
15
  spec.description = 'Creates well-formed website metadata with ' \
@@ -30,4 +30,6 @@ Gem::Specification.new do |spec|
30
30
  spec.add_development_dependency "bundler", "~> 2.4"
31
31
  spec.add_development_dependency "rake", "~> 13.0"
32
32
  spec.add_development_dependency "rspec", "~> 3.12"
33
+ spec.add_development_dependency "doctest2-rspec", "~> 0.9.2"
34
+ spec.add_development_dependency "pry", "> 0.0.0"
33
35
  end
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: schema_dot_org
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.3
4
+ version: 2.5.0
5
5
  platform: ruby
6
6
  authors:
7
- - Robb Shecter
7
+ - Robert Shecter
8
8
  bindir: exe
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
@@ -65,9 +65,37 @@ dependencies:
65
65
  - - "~>"
66
66
  - !ruby/object:Gem::Version
67
67
  version: '3.12'
68
+ - !ruby/object:Gem::Dependency
69
+ name: doctest2-rspec
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: 0.9.2
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: 0.9.2
82
+ - !ruby/object:Gem::Dependency
83
+ name: pry
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">"
87
+ - !ruby/object:Gem::Version
88
+ version: 0.0.0
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">"
94
+ - !ruby/object:Gem::Version
95
+ version: 0.0.0
68
96
  description: Creates well-formed website metadata with strongly typed Ruby.
69
97
  email:
70
- - robb@public.law
98
+ - robert@public.law
71
99
  executables: []
72
100
  extensions: []
73
101
  extra_rdoc_files: []
@@ -85,6 +113,7 @@ files:
85
113
  - bin/tapioca
86
114
  - lib/schema_dot_org.rb
87
115
  - lib/schema_dot_org/aggregate_offer.rb
116
+ - lib/schema_dot_org/breadcrumb_list.rb
88
117
  - lib/schema_dot_org/college_or_university.rb
89
118
  - lib/schema_dot_org/comment.rb
90
119
  - lib/schema_dot_org/contact_point.rb
@@ -99,6 +128,7 @@ files:
99
128
  - lib/schema_dot_org/place.rb
100
129
  - lib/schema_dot_org/product.rb
101
130
  - lib/schema_dot_org/search_action.rb
131
+ - lib/schema_dot_org/url_validator.rb
102
132
  - lib/schema_dot_org/web_site.rb
103
133
  - schema_dot_org.gemspec
104
134
  - test-script.rb