schema_dot_org 2.2.0 → 2.2.2

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: 39339b796fe48d129c05873ab0a10b6d4ebd683b982723049e25e1bb98b1b893
4
- data.tar.gz: 8e3c46e25e0e00849db2e0817c141f563209fb2ebbf9ec67a10fe8bc8241b9c2
3
+ metadata.gz: 146e2c23c546ada2f45452f78d5e609e0730256b24b72811c834306ef69b5409
4
+ data.tar.gz: c1dbd6ee1c3af15b07b3188eea8decf036e3bc52c97379d78bea1f7ca16a25ea
5
5
  SHA512:
6
- metadata.gz: 243792759980ee75f52dbc022aa59bb211b7a250a1af1078e5d167cd1700ae858d1588aafc9fd9a5ab92a7c89166fc437442ab176e9502744fbd6e7ff1bb2cd8
7
- data.tar.gz: 17abef45bb90add2f3cb699720950a2402cc6c84fad5e37672710caf26ddf9b4556204481e418726322642245172b18b8d634e58088a083296a119f168c25799
6
+ metadata.gz: ea5016b6e3075a5aa21d82faf8a7e00b42f920637b6e8dd97c7a54998eae6fcfb8ae4f98a15a6e45cd471b1614598d0f007f54f67545043b63af89ff1ec85fff
7
+ data.tar.gz: ae7aaf1fbcea2b10918d224c89c26fa71725cf6dac52d27f5960a7096726ca7d3b9c1866477651084d20e71fe118049de3fa4b646fbc26c0da671db2d064b168
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- schema_dot_org (2.2.0)
4
+ schema_dot_org (2.2.2)
5
5
  validated_object (~> 2.3)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -90,6 +90,12 @@ This type safety comes from the [ValidatedObject gem](https://github.com/dogweat
90
90
 
91
91
  ## Supported Schema.org Types
92
92
 
93
+ AggregateOffer, ContactPoint, ItemList, ListItem, Offer, Organization, Person, Place,
94
+ Product, SearchAction, and WebSite.
95
+
96
+ Here are a few examples. The [source code](https://github.com/dogweather/schema-dot-org/tree/master/lib/schema_dot_org) for these is **extremely easy** to read. Check them out to see
97
+ all the available attributes.
98
+
93
99
  ### WebSite
94
100
 
95
101
  Example with only the required attributes:
@@ -146,19 +152,26 @@ Add this line to your application's Gemfile:
146
152
  gem 'schema_dot_org'
147
153
  ```
148
154
 
149
- And then execute:
150
-
151
- $ bundle
155
+ ## Development
152
156
 
153
- Or install it yourself as:
157
+ The Schema.org classes are as DRY as I could possibly make them. They're really
158
+ easy to create and add to. For example, `Product`:
154
159
 
155
- $ gem install schema_dot_org
160
+ ```ruby
161
+ class Product < SchemaType
162
+ validated_attr :description, type: String, allow_nil: true
163
+ validated_attr :image, type: Array, allow_nil: true
164
+ validated_attr :name, type: String
165
+ validated_attr :offers, type: SchemaDotOrg::AggregateOffer
166
+ validated_attr :url, type: String
167
+ end
168
+ ```
156
169
 
157
- ## Development
170
+ The attributes are from the [Schema.org Product spec](https://schema.org/Product).
158
171
 
159
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
172
+ All Rails validations are available. These are just the attributes we've felt like
173
+ adding. PR's are welcome if you want to add more. Also for more Schema.org types.
160
174
 
161
- To install this gem onto your local machine, run `bundle exec rake install`.
162
175
 
163
176
  ## Contributing
164
177
 
@@ -1,9 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'date'
4
- require 'schema_dot_org'
5
- require 'schema_dot_org/offer'
6
-
3
+ #
7
4
  # Model the Schema.org `Thing > Place`. See https://schema.org/Offer
8
5
  #
9
6
  module SchemaDotOrg
@@ -14,19 +11,5 @@ module SchemaDotOrg
14
11
  validated_attr :highPrice, type: Numeric, allow_nil: true
15
12
  validated_attr :offerCount, type: String, allow_nil: true
16
13
  validated_attr :offers, type: Array, allow_nil: true
17
-
18
- def _to_json_struct
19
- {
20
- "priceCurrency" => priceCurrency,
21
- "lowPrice" => lowPrice,
22
- "highPrice" => highPrice,
23
- "offerCount" => offerCount,
24
- "offers" => offers.map(&:to_json_struct)
25
- }
26
- end
27
-
28
- def offers
29
- @offers || []
30
- end
31
14
  end
32
15
  end
@@ -1,25 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'schema_dot_org'
4
-
5
3
 
4
+ #
5
+ # Model the Schema.org `ContactPoint`. See http://schema.org/ContactPoint
6
+ #
6
7
  module SchemaDotOrg
7
- # Model the Schema.org `ContactPoint`. See http://schema.org/ContactPoint
8
8
  class ContactPoint < SchemaType
9
- validated_attr :telephone, type: String, presence: true
10
- validated_attr :contact_type, type: String, presence: true
11
- validated_attr :contact_option, type: String, allow_nil: true
12
9
  validated_attr :area_served, type: Array, allow_nil: true
13
10
  validated_attr :available_language, type: Array, allow_nil: true
14
-
15
- def _to_json_struct
16
- {
17
- 'telephone' => telephone,
18
- 'contactType' => contact_type,
19
- 'contactOption' => contact_option,
20
- 'areaServed' => area_served,
21
- 'availableLanguage' => available_language
22
- }
23
- end
11
+ validated_attr :contact_option, type: String, allow_nil: true
12
+ validated_attr :contact_type, type: String, presence: true
13
+ validated_attr :telephone, type: String, presence: true
24
14
  end
25
15
  end
@@ -1,9 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'schema_dot_org'
4
3
 
4
+ #
5
+ # Model the Schema.org `ItemList`. See https://schema.org/ItemList
6
+ #
5
7
  module SchemaDotOrg
6
- # Model the Schema.org `ItemList`. See https://schema.org/ItemList
7
8
  class ItemList < SchemaType
8
9
  validated_attr :itemListElement, type: Array, presence: true
9
10
  validated_attr :itemListOrder, type: String, allow_nil: true
@@ -11,20 +12,5 @@ module SchemaDotOrg
11
12
 
12
13
  validated_attr :url, type: String, allow_nil: true
13
14
  validated_attr :image, type: String, allow_nil: true
14
-
15
-
16
- def _to_json_struct
17
- {
18
- 'itemListOrder' => itemListOrder,
19
- 'numberOfItems' => numberOfItems,
20
- 'url' => url,
21
- 'image' => image,
22
- 'itemListElement' => itemListElement.map(&:to_json_struct)
23
- }
24
- end
25
-
26
- def itemListElement
27
- @itemListElement || []
28
- end
29
15
  end
30
16
  end
@@ -1,27 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'schema_dot_org'
4
- require 'schema_dot_org/product'
5
3
 
4
+ require_relative 'product'
6
5
 
6
+ #
7
+ # Model the Schema.org `ItemListElement`. See https://schema.org/ItemListElement
8
+ #
7
9
  module SchemaDotOrg
8
- # Model the Schema.org `ItemListElement`. See https://schema.org/ItemListElement
9
10
  class ListItem < SchemaType
10
- validated_attr :position, type: Integer, presence: true
11
- validated_attr :url, type: String, allow_nil: true
12
- validated_attr :name, type: String, allow_nil: true
13
- validated_attr :image, type: String, allow_nil: true
14
-
15
- validated_attr :item, type: Product, allow_nil: true
16
-
17
- def _to_json_struct
18
- {
19
- 'position' => position,
20
- 'url' => url,
21
- 'name' => name,
22
- 'image' => image,
23
- 'item' => object_to_json_struct(item)
24
- }
25
- end
11
+ validated_attr :image, type: String, allow_nil: true
12
+ validated_attr :item, type: SchemaDotOrg::Product, allow_nil: true
13
+ validated_attr :name, type: String, allow_nil: true
14
+ validated_attr :position, type: Integer, presence: true
15
+ validated_attr :url, type: String, allow_nil: true
26
16
  end
27
17
  end
@@ -1,24 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'date'
4
- require 'schema_dot_org'
5
3
 
4
+ #
6
5
  # Model the Schema.org `Thing > Place`. See https://schema.org/Offer
7
6
  #
8
7
  module SchemaDotOrg
9
8
  class Offer < SchemaType
10
- validated_attr :priceCurrency, type: String
11
- validated_attr :price, type: Numeric
12
- validated_attr :availability, type: String, allow_nil: true
13
- validated_attr :url, type: String, allow_nil: true
14
-
15
- def _to_json_struct
16
- {
17
- "price" => price,
18
- "priceCurrency" => priceCurrency,
19
- "availability" => availability,
20
- "url" => url
21
- }
22
- end
9
+ validated_attr :priceCurrency, type: String
10
+ validated_attr :price, type: Numeric
11
+ validated_attr :availability, type: String, allow_nil: true
12
+ validated_attr :url, type: String, allow_nil: true
23
13
  end
24
14
  end
@@ -1,42 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'date'
4
- require 'schema_dot_org'
5
- require 'schema_dot_org/person'
6
- require 'schema_dot_org/place'
7
- require 'schema_dot_org/contact_point'
8
4
 
5
+ require_relative 'person'
6
+ require_relative 'place'
9
7
 
10
8
  module SchemaDotOrg
11
9
  class Organization < SchemaType
10
+ validated_attr :contact_points, type: Array, allow_nil: true
12
11
  validated_attr :email, type: String, allow_nil: true
13
- validated_attr :telephone, type: String, allow_nil: true
14
12
  validated_attr :founder, type: SchemaDotOrg::Person, allow_nil: true
15
13
  validated_attr :founding_date, type: Date, allow_nil: true
16
14
  validated_attr :founding_location, type: SchemaDotOrg::Place, allow_nil: true
17
15
  validated_attr :logo, type: String
18
16
  validated_attr :name, type: String
19
- validated_attr :url, type: String
20
17
  validated_attr :same_as, type: Array, allow_nil: true
21
- validated_attr :contact_points, type: Array, allow_nil: true
22
-
23
- def _to_json_struct
24
- {
25
- "name" => name,
26
- "email" => email,
27
- "telephone" => telephone,
28
- "url" => url,
29
- "logo" => logo,
30
- "founder" => object_to_json_struct(founder),
31
- "foundingDate" => founding_date.to_s,
32
- "foundingLocation" => object_to_json_struct(founding_location),
33
- "sameAs" => same_as,
34
- "contactPoint" => contact_points.map(&:to_json_struct)
35
- }
36
- end
37
-
38
- def contact_points
39
- @contact_points || []
40
- end
18
+ validated_attr :telephone, type: String, allow_nil: true
19
+ validated_attr :url, type: String
41
20
  end
42
21
  end
@@ -1,20 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
 
4
+ #
5
+ # Model the Schema.org **Person**. See http://schema.org/Person
6
+ #
4
7
  module SchemaDotOrg
5
- # Model the Schema.org **Person**. See http://schema.org/Person
6
8
  class Person < SchemaType
7
9
  validated_attr :name, type: String, presence: true
8
10
  validated_attr :same_as, type: Array, allow_nil: true
9
11
  validated_attr :url, type: String, allow_nil: true
10
-
11
-
12
- def _to_json_struct
13
- {
14
- 'name' => name,
15
- 'url' => url,
16
- 'same_as' => same_as
17
- }
18
- end
19
12
  end
20
13
  end
@@ -1,15 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
 
4
+ #
5
+ # Model the Schema.org `Thing > Place`. See http://schema.org/Place
6
+ #
4
7
  module SchemaDotOrg
5
- # Model the Schema.org `Thing > Place`. See http://schema.org/Place
6
8
  class Place < SchemaType
7
9
  validated_attr :address, type: String, presence: true
8
-
9
- def _to_json_struct
10
- {
11
- 'address' => address
12
- }
13
- end
14
10
  end
15
11
  end
@@ -1,31 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'date'
4
- require 'schema_dot_org'
5
- require 'schema_dot_org/aggregate_offer'
6
3
 
4
+ #
7
5
  # Model the Schema.org `Thing > Place`. See https://schema.org/Product
8
6
  #
9
7
  module SchemaDotOrg
10
8
  class Product < SchemaType
11
- validated_attr :name, type: String
12
- validated_attr :url, type: String
13
9
  validated_attr :description, type: String, allow_nil: true
14
10
  validated_attr :image, type: Array, allow_nil: true
11
+ validated_attr :name, type: String
15
12
  validated_attr :offers, type: SchemaDotOrg::AggregateOffer
16
-
17
- def _to_json_struct
18
- {
19
- "name" => name,
20
- "url" => url,
21
- "description" => description,
22
- "image" => image,
23
- "offers" => offers.to_json_struct
24
- }
25
- end
26
-
27
- def image
28
- @image || []
29
- end
13
+ validated_attr :url, type: String
30
14
  end
31
15
  end
@@ -1,17 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
 
4
+ #
5
+ # Model the Schema.org `Thing > SearchAction`. See http://schema.org/SearchAction
6
+ #
4
7
  module SchemaDotOrg
5
- # Model the Schema.org `Thing > SearchAction`. See http://schema.org/SearchAction
6
- class SearchAction < SchemaType
7
- validated_attr :target, type: String, presence: true
8
+ class SearchAction < SchemaDotOrg::SchemaType
8
9
  validated_attr :query_input, type: String, presence: true
9
-
10
- def _to_json_struct
11
- {
12
- 'target' => target,
13
- 'query-input' => query_input ## ! Note the hyphen.
14
- }
15
- end
10
+ validated_attr :target, type: String, presence: true
16
11
  end
17
12
  end
@@ -1,21 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
 
4
+ #
5
+ # Model the Schema.org `Thing > CreativeWork > WebSite`.
6
+ # @See http://schema.org/WebSite
7
+ #
4
8
  module SchemaDotOrg
5
- # Model the Schema.org `Thing > CreativeWork > WebSite`.
6
- # @See http://schema.org/WebSite
7
9
  class WebSite < SchemaType
8
10
  validated_attr :name, type: String, presence: true
9
- validated_attr :url, type: String, presence: true
10
11
  validated_attr :potential_action, type: SchemaDotOrg::SearchAction, allow_nil: true
11
-
12
-
13
- def _to_json_struct
14
- {
15
- 'name' => self.name,
16
- 'url' => self.url,
17
- 'potentialAction' => object_to_json_struct(potential_action)
18
- }
19
- end
12
+ validated_attr :url, type: String, presence: true
20
13
  end
21
14
  end
@@ -1,16 +1,127 @@
1
1
  # frozen_string_literal: true
2
- require 'schema_dot_org/schema_type'
3
- require 'schema_dot_org/search_action'
4
- require 'schema_dot_org/web_site'
5
- require 'schema_dot_org/organization'
6
- require 'schema_dot_org/product'
2
+ require 'json'
3
+ require 'validated_object'
4
+
5
+ #
6
+ # Abstract base class for all the Schema.org types.
7
+ #
8
+ module SchemaDotOrg
9
+ class SchemaType < ValidatedObject::Base
10
+ ROOT_ATTR = { "@context" => "https://schema.org" }.freeze
11
+ UNQUALIFIED_CLASS_NAME_REGEX = /([^:]+)$/
12
+
13
+
14
+ def to_s
15
+ json_string = to_json_ld(pretty: (!rails_production? && !ENV['SCHEMA_DOT_ORG_MINIFIED_JSON']))
16
+
17
+ # Mark as safe if we're in Rails
18
+ if json_string.respond_to?(:html_safe)
19
+ json_string.html_safe
20
+ else
21
+ json_string
22
+ end
23
+ end
24
+
25
+
26
+ def to_json_ld(pretty: false)
27
+ "<script type=\"application/ld+json\">\n" + to_json(pretty: pretty, as_root: true) + "\n</script>"
28
+ end
29
+
30
+
31
+ def to_json(pretty: false, as_root: false)
32
+ structure = as_root ? ROOT_ATTR.merge(to_json_struct) : to_json_struct
33
+
34
+ if pretty
35
+ JSON.pretty_generate(structure)
36
+ else
37
+ structure.to_json
38
+ end
39
+ end
40
+
41
+
42
+ # Use the class name to create the "@type" attribute.
43
+ # @return a hash structure representing json.
44
+ def to_json_struct
45
+ { "@type" => un_namespaced_classname }.merge(_to_json_struct.reject { |_, v| v.blank? })
46
+ end
47
+
48
+
49
+ def _to_json_struct
50
+ attrs_and_values
51
+ end
52
+
53
+
54
+ # @return the classname without the module namespace.
55
+ def un_namespaced_classname
56
+ self.class.name =~ UNQUALIFIED_CLASS_NAME_REGEX
57
+ Regexp.last_match(1)
58
+ end
59
+
60
+
61
+ def object_to_json_struct(object)
62
+ return nil unless object
63
+ object.to_json_struct
64
+ end
65
+
66
+
67
+ def attrs_and_values
68
+ attrs.map do |attr|
69
+ # Clean up and andle the `query-input` attribute, which
70
+ # doesn't follow the normal camelCase convention.
71
+ attr_name = snake_case_to_lower_camel_case(attr.to_s.delete_prefix('@')).sub('queryInput', 'query-input')
72
+ attr_value = instance_variable_get(attr)
73
+
74
+ [attr_name, resolve_value(attr_value)]
75
+ end.to_h
76
+ end
77
+
78
+
79
+ def resolve_value(value)
80
+ if value.is_a?(Array)
81
+ value.map { |v| resolve_value(v) }
82
+
83
+ elsif value.is_a?(Date)
84
+ value.to_s
85
+
86
+ elsif is_schema_type?(value)
87
+ value.to_json_struct
88
+
89
+ else
90
+ value
91
+ end
92
+ end
93
+
94
+
95
+ def snake_case_to_lower_camel_case(snake_case)
96
+ snake_case.to_s.split('_').map.with_index { |s, i| i.zero? ? s : s.capitalize }.join
97
+ end
98
+
99
+
100
+ def attrs
101
+ instance_variables.reject{ |v| [:@validation_context, :@errors].include?(v) }
102
+ end
103
+
104
+
105
+ def is_schema_type?(object)
106
+ object.class.module_parent == SchemaDotOrg
107
+ end
108
+
109
+
110
+ def rails_production?
111
+ defined?(Rails) && Rails.env.production?
112
+ end
113
+ end
114
+ end
115
+
116
+
117
+ require 'schema_dot_org/aggregate_offer'
118
+ require 'schema_dot_org/contact_point'
7
119
  require 'schema_dot_org/item_list'
8
120
  require 'schema_dot_org/list_item'
121
+ require 'schema_dot_org/organization'
9
122
  require 'schema_dot_org/person'
10
123
  require 'schema_dot_org/place'
11
- require 'schema_dot_org/aggregate_offer'
124
+ require 'schema_dot_org/product'
12
125
  require 'schema_dot_org/offer'
13
- require 'schema_dot_org/contact_point'
14
-
15
- module SchemaDotOrg
16
- end
126
+ require 'schema_dot_org/search_action'
127
+ require 'schema_dot_org/web_site'
@@ -7,7 +7,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
7
7
  Gem::Specification.new do |spec|
8
8
  spec.required_ruby_version = '>= 2.6'
9
9
  spec.name = 'schema_dot_org'
10
- spec.version = '2.2.0'
10
+ spec.version = '2.2.2'
11
11
  spec.authors = ['Robb Shecter']
12
12
  spec.email = ['robb@public.law']
13
13
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: schema_dot_org
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robb Shecter
@@ -95,7 +95,6 @@ files:
95
95
  - lib/schema_dot_org/person.rb
96
96
  - lib/schema_dot_org/place.rb
97
97
  - lib/schema_dot_org/product.rb
98
- - lib/schema_dot_org/schema_type.rb
99
98
  - lib/schema_dot_org/search_action.rb
100
99
  - lib/schema_dot_org/web_site.rb
101
100
  - schema_dot_org.gemspec
@@ -1,67 +0,0 @@
1
- require 'json'
2
- require 'validated_object'
3
-
4
- module SchemaDotOrg
5
- class SchemaType < ValidatedObject::Base
6
- ROOT_ATTR = { "@context" => "http://schema.org" }.freeze
7
- UNQUALIFIED_CLASS_NAME_REGEX = /([^:]+)$/
8
-
9
-
10
- def to_s
11
- json_string = to_json_ld(pretty: (!rails_production? && !ENV['SCHEMA_DOT_ORG_MINIFIED_JSON']))
12
-
13
- # Mark as safe if we're in Rails
14
- if json_string.respond_to?(:html_safe)
15
- json_string.html_safe
16
- else
17
- json_string
18
- end
19
- end
20
-
21
-
22
- def to_json_ld(pretty: false)
23
- "<script type=\"application/ld+json\">\n" + to_json(pretty: pretty, as_root: true) + "\n</script>"
24
- end
25
-
26
-
27
- def to_json(pretty: false, as_root: false)
28
- structure = as_root ? ROOT_ATTR.merge(to_json_struct) : to_json_struct
29
-
30
- if pretty
31
- JSON.pretty_generate(structure)
32
- else
33
- structure.to_json
34
- end
35
- end
36
-
37
-
38
- # Use the class name to create the "@type" attribute.
39
- # @return a hash structure representing json.
40
- def to_json_struct
41
- { "@type" => un_namespaced_classname }.merge(_to_json_struct.reject { |_, v| v.blank? })
42
- end
43
-
44
-
45
- def _to_json_struct
46
- raise "For subclasses to implement"
47
- end
48
-
49
-
50
- # @return the classname without the module namespace.
51
- def un_namespaced_classname
52
- self.class.name =~ UNQUALIFIED_CLASS_NAME_REGEX
53
- Regexp.last_match(1)
54
- end
55
-
56
- def object_to_json_struct(object)
57
- return nil unless object
58
- object.to_json_struct
59
- end
60
-
61
- private
62
-
63
- def rails_production?
64
- defined?(Rails) && Rails.env.production?
65
- end
66
- end
67
- end