izi_json_ld 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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