izi_json_ld 1.0.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.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/README.rdoc +3 -0
  3. data/app/entities/aggregate_rating_entity.rb +5 -0
  4. data/app/entities/application_entity.rb +25 -0
  5. data/app/entities/offer_entity.rb +10 -0
  6. data/app/entities/product_entity.rb +14 -0
  7. data/app/entities/rating_entity.rb +9 -0
  8. data/app/entities/review_entity.rb +11 -0
  9. data/app/entities/service_entity.rb +10 -0
  10. data/app/helpers/critical_helper.rb +118 -0
  11. data/lib/izi_json_ld.rb +23 -0
  12. data/lib/izi_json_ld/engine.rb +11 -0
  13. data/lib/izi_json_ld/extentions/autoload_paths.rb +6 -0
  14. data/lib/izi_json_ld/types.rb +7 -0
  15. data/lib/izi_json_ld/version.rb +5 -0
  16. data/spec/dummy/Gemfile +14 -0
  17. data/spec/dummy/Gemfile.lock +229 -0
  18. data/spec/dummy/Rakefile +6 -0
  19. data/spec/dummy/app/assets/config/manifest.js +0 -0
  20. data/spec/dummy/app/controllers/application_controller.rb +2 -0
  21. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  22. data/spec/dummy/app/models/application_record.rb +3 -0
  23. data/spec/dummy/app/views/layouts/application.html.erb +15 -0
  24. data/spec/dummy/bin/_guard-core +29 -0
  25. data/spec/dummy/bin/guard +29 -0
  26. data/spec/dummy/bin/rails +4 -0
  27. data/spec/dummy/bin/rake +4 -0
  28. data/spec/dummy/bin/rspec +29 -0
  29. data/spec/dummy/bin/setup +33 -0
  30. data/spec/dummy/config.ru +6 -0
  31. data/spec/dummy/config/application.rb +14 -0
  32. data/spec/dummy/config/boot.rb +5 -0
  33. data/spec/dummy/config/database.yml +25 -0
  34. data/spec/dummy/config/environment.rb +5 -0
  35. data/spec/dummy/config/environments/development.rb +76 -0
  36. data/spec/dummy/config/environments/production.rb +120 -0
  37. data/spec/dummy/config/environments/test.rb +59 -0
  38. data/spec/dummy/config/initializers/assets.rb +12 -0
  39. data/spec/dummy/config/initializers/backtrace_silencers.rb +8 -0
  40. data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
  41. data/spec/dummy/config/initializers/filter_parameter_logging.rb +6 -0
  42. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  43. data/spec/dummy/config/puma.rb +43 -0
  44. data/spec/dummy/config/routes.rb +3 -0
  45. data/spec/dummy/db/test.sqlite3 +0 -0
  46. data/spec/dummy/log/development.log +0 -0
  47. data/spec/dummy/log/test.log +1249 -0
  48. data/spec/dummy/tmp/development_secret.txt +1 -0
  49. data/spec/entities/aggregate_rating_entity_spec.rb +34 -0
  50. data/spec/entities/offer_entity_spec.rb +45 -0
  51. data/spec/entities/product_entity_spec.rb +49 -0
  52. data/spec/entities/rating_entity_spec.rb +34 -0
  53. data/spec/entities/review_entity_spec.rb +44 -0
  54. data/spec/entities/service_entity_spec.rb +62 -0
  55. data/spec/rails_helper.rb +64 -0
  56. data/spec/spec_helper.rb +96 -0
  57. metadata +168 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 829963d96abb460e0ea484d424bfe2d1c788bb73817f43f71c3c272a1dd8fe8e
4
+ data.tar.gz: 310de3da62be69677e36359a3aa8aa625e5ba2ea4c5208f616ad6821d53b9402
5
+ SHA512:
6
+ metadata.gz: 2c00cd328bb712e104d28644f6f10340cfd15e2c35493f40330d78df20e6004ef481c7e9eb3b9fd10b32b24c3abee9893941c065585411f8ffdc512fe76b23c0
7
+ data.tar.gz: ea23f754afc1bf8ac65f3bdbba4754569fd803a7846689ff38840738322292c97727e222ebbc4d6d62b96e73d3981993c56f665b0c685b4dca819cdfe606cd3b
data/README.rdoc ADDED
@@ -0,0 +1,3 @@
1
+ # Izi JSON-ld
2
+
3
+ Utils to add json-ld schema more easily
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AggregateRatingEntity < RatingEntity
4
+ extra '@type', 'AggregateRating'
5
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ApplicationEntity < Dry::Struct
4
+ transform_keys(&:to_sym)
5
+ delegate :extras, to: :class
6
+ delegate :as_json, to: :to_h
7
+
8
+ def to_h
9
+ extras.merge(super)
10
+ end
11
+
12
+ def to_json(*args)
13
+ super.html_safe
14
+ end
15
+
16
+ class << self
17
+ def extras
18
+ @extras ||= {}
19
+ end
20
+
21
+ def extra(key, value)
22
+ extras[key] = value
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ class OfferEntity < ApplicationEntity
4
+ extra '@type', 'Offer'
5
+
6
+ attribute :url, ::IziJsonLd::Types::Coercible::String
7
+ attribute :price, ::IziJsonLd::Types::Coercible::Float
8
+ attribute :priceCurrency, ::IziJsonLd::Types::String.optional.default('USD')
9
+ attribute :availability, ::IziJsonLd::Types::String.optional.default('https://schema.org/OnlineOnly')
10
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ProductEntity < ApplicationEntity
4
+ extra '@context', 'http://www.schema.org'
5
+ extra '@type', 'Product'
6
+
7
+ attribute :name, ::IziJsonLd::Types::String
8
+ attribute? :brand, ::IziJsonLd::Types::String.optional
9
+ attribute? :image, ::IziJsonLd::Types::String.optional
10
+ attribute? :description, ::IziJsonLd::Types::String.optional
11
+
12
+ attribute? :offers, OfferEntity.optional
13
+ attribute? :aggregateRating, AggregateRatingEntity.optional
14
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class RatingEntity < ApplicationEntity
4
+ extra '@type', 'Rating'
5
+
6
+ attribute :bestRating, ::IziJsonLd::Types::Coercible::Float.optional.default(5)
7
+ attribute :worstRating, ::IziJsonLd::Types::Coercible::Float.optional.default(1)
8
+ attribute :ratingValue, ::IziJsonLd::Types::Coercible::Float
9
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ReviewEntity < ApplicationEntity
4
+ extra '@type', 'Review'
5
+
6
+ attribute? :author, ::IziJsonLd::Types::String.optional
7
+ attribute? :description, ::IziJsonLd::Types::String.optional
8
+ attribute? :reviewRating, RatingEntity.optional
9
+
10
+ attribute? :datePublished, (::IziJsonLd::Types::Nominal::Date | ::IziJsonLd::Types::JSON::Date).optional
11
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ServiceEntity < ApplicationEntity
4
+ extra '@context', 'http://www.schema.org'
5
+ extra '@type', 'Service'
6
+
7
+ attribute :name, ::IziJsonLd::Types::String
8
+ attribute? :review, ::ReviewEntity.optional
9
+ attribute? :reviews, ::IziJsonLd::Types::Array.of(::ReviewEntity).optional
10
+ end
@@ -0,0 +1,118 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CriticalHelper
4
+ def css_preload(names)
5
+ return '' if names.blank?
6
+ names = Array.wrap(names)
7
+
8
+ link = stylesheet_link_tag(*names, rel: 'preload', as: 'style', onload: 'this.rel="stylesheet"')
9
+ noscript = content_tag :noscript do
10
+ stylesheet_link_tag(*names)
11
+ end
12
+
13
+ link + noscript
14
+ end
15
+
16
+ def inline_js(name)
17
+ IziJsonLd::InlineAsset.inline_js(name).html_safe
18
+ end
19
+
20
+ def inline_css(name)
21
+ raw = IziJsonLd::InlineAsset.inline_css(name).html_safe
22
+ raw = "<!-- CRIT CSS: #{name} -->".html_safe + raw if Rails.env.development?
23
+ raw
24
+ end
25
+
26
+ def critical_js
27
+ inline_js('crit-utils/bundle.js').presence || '<!-- CRIT JS NOT FOUND! -->'.html_safe
28
+ end
29
+
30
+ def critical_css(params = {})
31
+ scope = params.fetch(:scope, 'critical')
32
+ name = find_scoped_css(scope)
33
+ stylesheets = Array.wrap(params.fetch(:stylesheets, []))
34
+ data = StringIO.new
35
+
36
+ if name.blank?
37
+ # insert stylesheets directly if not crit css
38
+ data << '<!-- CRIT CSS NOT FOUND! -->'
39
+ data << stylesheet_link_tag(*stylesheets) if stylesheets.present?
40
+ else
41
+ data << inline_css(name)
42
+ data << css_preload(stylesheets) if stylesheets.present?
43
+ data << inline_js('crit-utils/measure.js') if Rails.env.development?
44
+ end
45
+
46
+ data.string.html_safe
47
+ end
48
+
49
+ def smart_picture(object, *args, **xargs, &block)
50
+ return '' if object.blank?
51
+
52
+ IziJsonLd::SmartPicture.render(object, *args, **xargs, &block)
53
+ end
54
+
55
+ def debug_critical_css(scope_name = 'critical')
56
+ {
57
+ lookup: scoped_css_files(scope_name),
58
+ found: find_scoped_css(scope_name)
59
+ }.to_json.html_safe
60
+ end
61
+
62
+ private
63
+
64
+ def scoped_css_files(scope_name)
65
+ [
66
+ "#{controller_path}_#{action_name}",
67
+ controller_path,
68
+ *scoped_namespace_file(scope_name),
69
+ "#{controller_name}_#{action_name}",
70
+ controller_name,
71
+ scope_name
72
+ ].compact.uniq.map { |l| File.join(scope_name, "#{l}.css") }
73
+ end
74
+
75
+ def scoped_namespace_file(scope_name)
76
+ scopes = []
77
+ return scopes if controller_path == controller_name
78
+
79
+ parts = controller_path.gsub(/\/#{controller_name}$/, '').split('/').reject(&:blank?)
80
+ parts.each { |p| scopes.unshift(File.join([scopes.first, p].compact)) }
81
+
82
+ scopes.uniq
83
+ end
84
+
85
+ def find_scoped_css(scope_name)
86
+ scoped_css_files(scope_name).detect { |n| asset_exist?(n) }
87
+ end
88
+
89
+ def fetch_items(object, fields)
90
+ Array.wrap(fields).map do |name|
91
+ object.respond_to?(name) ? object.public_send(name) : nil
92
+ end.compact
93
+ end
94
+
95
+ def asset_exist?(name)
96
+ return find_asset_source(name)&.present? if Rails.env.development?
97
+
98
+ manifest.assets.key?(name)
99
+ end
100
+
101
+ def find_asset_source(name)
102
+ return find_sources_fallback(name) if old_manifest?
103
+
104
+ manifest.find_sources(name)&.first
105
+ end
106
+
107
+ def find_sources_fallback(asset_path)
108
+ Rails.application.assets.find_asset(asset_path)
109
+ end
110
+
111
+ def old_manifest?
112
+ !manifest.respond_to?(:find_sources)
113
+ end
114
+
115
+ def manifest
116
+ @manifest ||= Rails.application.assets_manifest
117
+ end
118
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'izi_json_ld/version'
4
+ require 'pathname'
5
+
6
+ # core setup
7
+ module IziJsonLd
8
+ class << self
9
+ def configure
10
+ yield self
11
+ end
12
+ end
13
+
14
+ autoload :Types, 'izi_json_ld/types'
15
+
16
+ class << self
17
+ def root_path
18
+ @root_path ||= Pathname.new(File.dirname(File.expand_path(__dir__)))
19
+ end
20
+ end
21
+ end
22
+
23
+ require 'izi_json_ld/engine'
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'dry-struct'
4
+
5
+ module IziJsonLd
6
+ class Engine < ::Rails::Engine
7
+ engine_name 'izi_json_ld'
8
+
9
+ require_relative 'extentions/autoload_paths'
10
+ end
11
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ # isolate_namespace IziJsonLd
4
+ ::IziJsonLd::Engine.config.autoload_paths += %W[
5
+ #{IziJsonLd.root_path}/app/helpers
6
+ ]
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IziJsonLd
4
+ module Types
5
+ include Dry.Types()
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IziJsonLd
4
+ VERSION = '1.0.0'
5
+ end
@@ -0,0 +1,14 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'byebug'
4
+ gem 'dry-struct'
5
+ gem 'faker'
6
+ gem 'rails'
7
+ gem 'sqlite3'
8
+
9
+ group :test do
10
+ gem 'guard', require: false
11
+ gem 'guard-rspec', require: false
12
+ gem 'rspec'
13
+ gem 'rspec-rails'
14
+ end
@@ -0,0 +1,229 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ actioncable (6.1.3)
5
+ actionpack (= 6.1.3)
6
+ activesupport (= 6.1.3)
7
+ nio4r (~> 2.0)
8
+ websocket-driver (>= 0.6.1)
9
+ actionmailbox (6.1.3)
10
+ actionpack (= 6.1.3)
11
+ activejob (= 6.1.3)
12
+ activerecord (= 6.1.3)
13
+ activestorage (= 6.1.3)
14
+ activesupport (= 6.1.3)
15
+ mail (>= 2.7.1)
16
+ actionmailer (6.1.3)
17
+ actionpack (= 6.1.3)
18
+ actionview (= 6.1.3)
19
+ activejob (= 6.1.3)
20
+ activesupport (= 6.1.3)
21
+ mail (~> 2.5, >= 2.5.4)
22
+ rails-dom-testing (~> 2.0)
23
+ actionpack (6.1.3)
24
+ actionview (= 6.1.3)
25
+ activesupport (= 6.1.3)
26
+ rack (~> 2.0, >= 2.0.9)
27
+ rack-test (>= 0.6.3)
28
+ rails-dom-testing (~> 2.0)
29
+ rails-html-sanitizer (~> 1.0, >= 1.2.0)
30
+ actiontext (6.1.3)
31
+ actionpack (= 6.1.3)
32
+ activerecord (= 6.1.3)
33
+ activestorage (= 6.1.3)
34
+ activesupport (= 6.1.3)
35
+ nokogiri (>= 1.8.5)
36
+ actionview (6.1.3)
37
+ activesupport (= 6.1.3)
38
+ builder (~> 3.1)
39
+ erubi (~> 1.4)
40
+ rails-dom-testing (~> 2.0)
41
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
42
+ activejob (6.1.3)
43
+ activesupport (= 6.1.3)
44
+ globalid (>= 0.3.6)
45
+ activemodel (6.1.3)
46
+ activesupport (= 6.1.3)
47
+ activerecord (6.1.3)
48
+ activemodel (= 6.1.3)
49
+ activesupport (= 6.1.3)
50
+ activestorage (6.1.3)
51
+ actionpack (= 6.1.3)
52
+ activejob (= 6.1.3)
53
+ activerecord (= 6.1.3)
54
+ activesupport (= 6.1.3)
55
+ marcel (~> 0.3.1)
56
+ mimemagic (~> 0.3.2)
57
+ activesupport (6.1.3)
58
+ concurrent-ruby (~> 1.0, >= 1.0.2)
59
+ i18n (>= 1.6, < 2)
60
+ minitest (>= 5.1)
61
+ tzinfo (~> 2.0)
62
+ zeitwerk (~> 2.3)
63
+ builder (3.2.4)
64
+ byebug (11.1.3)
65
+ coderay (1.1.3)
66
+ concurrent-ruby (1.1.8)
67
+ crass (1.0.6)
68
+ diff-lcs (1.4.4)
69
+ dry-configurable (0.12.1)
70
+ concurrent-ruby (~> 1.0)
71
+ dry-core (~> 0.5, >= 0.5.0)
72
+ dry-container (0.7.2)
73
+ concurrent-ruby (~> 1.0)
74
+ dry-configurable (~> 0.1, >= 0.1.3)
75
+ dry-core (0.5.0)
76
+ concurrent-ruby (~> 1.0)
77
+ dry-inflector (0.2.0)
78
+ dry-logic (1.1.0)
79
+ concurrent-ruby (~> 1.0)
80
+ dry-core (~> 0.5, >= 0.5)
81
+ dry-struct (1.4.0)
82
+ dry-core (~> 0.5, >= 0.5)
83
+ dry-types (~> 1.5)
84
+ ice_nine (~> 0.11)
85
+ dry-types (1.5.1)
86
+ concurrent-ruby (~> 1.0)
87
+ dry-container (~> 0.3)
88
+ dry-core (~> 0.5, >= 0.5)
89
+ dry-inflector (~> 0.1, >= 0.1.2)
90
+ dry-logic (~> 1.0, >= 1.0.2)
91
+ erubi (1.10.0)
92
+ faker (2.17.0)
93
+ i18n (>= 1.6, < 2)
94
+ ffi (1.15.0)
95
+ formatador (0.2.5)
96
+ globalid (0.4.2)
97
+ activesupport (>= 4.2.0)
98
+ guard (2.16.2)
99
+ formatador (>= 0.2.4)
100
+ listen (>= 2.7, < 4.0)
101
+ lumberjack (>= 1.0.12, < 2.0)
102
+ nenv (~> 0.1)
103
+ notiffany (~> 0.0)
104
+ pry (>= 0.9.12)
105
+ shellany (~> 0.0)
106
+ thor (>= 0.18.1)
107
+ guard-compat (1.2.1)
108
+ guard-rspec (4.7.3)
109
+ guard (~> 2.1)
110
+ guard-compat (~> 1.1)
111
+ rspec (>= 2.99.0, < 4.0)
112
+ i18n (1.8.9)
113
+ concurrent-ruby (~> 1.0)
114
+ ice_nine (0.11.2)
115
+ listen (3.4.1)
116
+ rb-fsevent (~> 0.10, >= 0.10.3)
117
+ rb-inotify (~> 0.9, >= 0.9.10)
118
+ loofah (2.9.0)
119
+ crass (~> 1.0.2)
120
+ nokogiri (>= 1.5.9)
121
+ lumberjack (1.2.8)
122
+ mail (2.7.1)
123
+ mini_mime (>= 0.1.1)
124
+ marcel (0.3.3)
125
+ mimemagic (~> 0.3.2)
126
+ method_source (1.0.0)
127
+ mimemagic (0.3.5)
128
+ mini_mime (1.0.2)
129
+ mini_portile2 (2.5.0)
130
+ minitest (5.14.4)
131
+ nenv (0.3.0)
132
+ nio4r (2.5.7)
133
+ nokogiri (1.11.2)
134
+ mini_portile2 (~> 2.5.0)
135
+ racc (~> 1.4)
136
+ notiffany (0.1.3)
137
+ nenv (~> 0.1)
138
+ shellany (~> 0.0)
139
+ pry (0.14.0)
140
+ coderay (~> 1.1)
141
+ method_source (~> 1.0)
142
+ racc (1.5.2)
143
+ rack (2.2.3)
144
+ rack-test (1.1.0)
145
+ rack (>= 1.0, < 3)
146
+ rails (6.1.3)
147
+ actioncable (= 6.1.3)
148
+ actionmailbox (= 6.1.3)
149
+ actionmailer (= 6.1.3)
150
+ actionpack (= 6.1.3)
151
+ actiontext (= 6.1.3)
152
+ actionview (= 6.1.3)
153
+ activejob (= 6.1.3)
154
+ activemodel (= 6.1.3)
155
+ activerecord (= 6.1.3)
156
+ activestorage (= 6.1.3)
157
+ activesupport (= 6.1.3)
158
+ bundler (>= 1.15.0)
159
+ railties (= 6.1.3)
160
+ sprockets-rails (>= 2.0.0)
161
+ rails-dom-testing (2.0.3)
162
+ activesupport (>= 4.2.0)
163
+ nokogiri (>= 1.6)
164
+ rails-html-sanitizer (1.3.0)
165
+ loofah (~> 2.3)
166
+ railties (6.1.3)
167
+ actionpack (= 6.1.3)
168
+ activesupport (= 6.1.3)
169
+ method_source
170
+ rake (>= 0.8.7)
171
+ thor (~> 1.0)
172
+ rake (13.0.3)
173
+ rb-fsevent (0.10.4)
174
+ rb-inotify (0.10.1)
175
+ ffi (~> 1.0)
176
+ rspec (3.10.0)
177
+ rspec-core (~> 3.10.0)
178
+ rspec-expectations (~> 3.10.0)
179
+ rspec-mocks (~> 3.10.0)
180
+ rspec-core (3.10.1)
181
+ rspec-support (~> 3.10.0)
182
+ rspec-expectations (3.10.1)
183
+ diff-lcs (>= 1.2.0, < 2.0)
184
+ rspec-support (~> 3.10.0)
185
+ rspec-mocks (3.10.2)
186
+ diff-lcs (>= 1.2.0, < 2.0)
187
+ rspec-support (~> 3.10.0)
188
+ rspec-rails (5.0.0)
189
+ actionpack (>= 5.2)
190
+ activesupport (>= 5.2)
191
+ railties (>= 5.2)
192
+ rspec-core (~> 3.10)
193
+ rspec-expectations (~> 3.10)
194
+ rspec-mocks (~> 3.10)
195
+ rspec-support (~> 3.10)
196
+ rspec-support (3.10.2)
197
+ shellany (0.0.1)
198
+ sprockets (4.0.2)
199
+ concurrent-ruby (~> 1.0)
200
+ rack (> 1, < 3)
201
+ sprockets-rails (3.2.2)
202
+ actionpack (>= 4.0)
203
+ activesupport (>= 4.0)
204
+ sprockets (>= 3.0.0)
205
+ sqlite3 (1.4.2)
206
+ thor (1.1.0)
207
+ tzinfo (2.0.4)
208
+ concurrent-ruby (~> 1.0)
209
+ websocket-driver (0.7.3)
210
+ websocket-extensions (>= 0.1.0)
211
+ websocket-extensions (0.1.5)
212
+ zeitwerk (2.4.2)
213
+
214
+ PLATFORMS
215
+ ruby
216
+
217
+ DEPENDENCIES
218
+ byebug
219
+ dry-struct
220
+ faker
221
+ guard
222
+ guard-rspec
223
+ rails
224
+ rspec
225
+ rspec-rails
226
+ sqlite3
227
+
228
+ BUNDLED WITH
229
+ 2.1.4