dato-rails 0.3.0 → 0.4.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: 02c359d5fbd1d6c3ec6aeb523e4e6cd363d76eeeec4045a195af8d89f62f59f8
4
- data.tar.gz: 3a81c86545557254a92fe7b323bc241cac6b33051d619847d5e911f286cbb0ab
3
+ metadata.gz: 48c76d182eea6b57c5a9fa7dc5731fd203ec11ab3fc6a263c6cd5cfbbed92520
4
+ data.tar.gz: c0109db369f7571f690448dbd4119104a887bfb3e28baa4c7f2481cac090baaf
5
5
  SHA512:
6
- metadata.gz: 49b7857ed9358db19ea94a5c984250ec50b389bc806af3c6df8a7919504c8dbd6aa837c167bffed60f69c8cbd599ed86e03bbedbe721e39adf1b80a758a42adc
7
- data.tar.gz: bcc954ba7e8606a5c807d0d3f1be11b1a82d0a3b065cfef77e051b7b481e3fe8b0f4f424738216ab0602a009446709c14b5d4133eef576e4960fa194fd1f4b4e
6
+ metadata.gz: 90dee86a67536de6913bffe0d2ea41cc776b1b6ab5e884d392bfc2181fe0e73092cffc10398200e995d22dfe95b4c6eadff05618c2d696aa0ec960a4f7fe2d4e
7
+ data.tar.gz: d8a03730831b5a348e095b505bb10b170f36e0da4045417c508de4303579a741aa6bc6a419226aeafb49e18df0a1196d370eca63bd965f01550fffb2d554563c
data/README.md CHANGED
@@ -4,6 +4,8 @@ Use [DatoCMS](https://www.datocms.com/) in your Rails application.
4
4
 
5
5
  This gem allows you to fetch data using Dato GraphQL APIs and render the content in your Rails app.
6
6
 
7
+ 👉 See [this simple tutorial to get started on dev.to](https://dev.to/coorasse/datocms-with-ruby-on-rails-3ae5). 👈
8
+
7
9
  ## Installation
8
10
 
9
11
  Add this line to your application's Gemfile:
@@ -116,7 +118,7 @@ client.live!(your_query)
116
118
 
117
119
  A `ViewComponent` is provided to use both these features very easily!
118
120
 
119
- Given that you have a `ViewComponent` that takes in input only the result of a dato query,
121
+ Given that you have a `MyComponent` that takes in input only the result of a dato query,
120
122
  you probably have the following:
121
123
 
122
124
  ```ruby
@@ -132,6 +134,68 @@ render(Dato::Live.new(MyComponent, my_query, preview: true, live: true))
132
134
 
133
135
  and your component will come to life with live updates 🎉 (requires turbo).
134
136
 
137
+ ## Configuration
138
+
139
+ The following options are available:
140
+
141
+ ```ruby
142
+ # config/initializers/dato.rb
143
+
144
+ Dato::Config.configure do |config|
145
+ config.overrides = {} # default: {}
146
+ config.blocks = {} # default: {}
147
+ config.cache = false # default: false
148
+ config.cache_namespace = 'dato-rails' # default: 'dato-rails'
149
+ config.publish_key = ENV['DATO_PUBLISH_KEY'] # default: ENV['DATO_PUBLISH_KEY']
150
+ config.build_triggger_id = ENV['DATO_BUILD_TRIGGER_ID'] # default: ENV['DATO_BUILD_TRIGGER_ID']
151
+ end
152
+ ```
153
+
154
+ ## Caching
155
+
156
+ The library supports caching of the rendered components.
157
+ If you enable caching, the components rendered using `Dato::Live`, will be cached.
158
+
159
+ To enable caching, you need to set the `cache` option in the configuration.
160
+
161
+ ```ruby
162
+ # config/initializers/dato.rb
163
+
164
+ Dato::Config.configure do |config|
165
+ config.cache = 1.day # if you set it to `true`, it will default to 60 minutes
166
+ end
167
+ ```
168
+
169
+ Now a call to
170
+
171
+ ```ruby
172
+ render(Dato::Live.new(MyComponent, my_query))
173
+ ```
174
+
175
+ will be cached for 1 day.
176
+
177
+ This means that for the next 24 hours, the graphQL endpoint will not be invoked and the whole component rendering will also be skipped.
178
+
179
+ **We will cache the entire HTML result of the component, not only the graphQL response.**
180
+
181
+ If you want to expire the cache you have two options:
182
+
183
+ ### manually
184
+
185
+ executing `Rails.cache.clear(namespace: Dato::Config.cache_namespace)`
186
+
187
+ ### publish endpoint
188
+
189
+ You can take advantage of the publish mechanism of Dato CMS to expire the cache.
190
+ * Mount the `dato-rails` engine in your Rails routes file.
191
+ * Set the `DATO_PUBLISH_KEY` environment variable
192
+ * Create a build trigger with a custom webhook on your Dato CMS project setting.
193
+ * Define the Trigger URL as `https://yourapp.com/dato/publish`
194
+ * Set the `DATO_PUBLISH_KEY` as the Authorization header
195
+ * Copy the build trigger id and set it as `DATO_BUILD_TRIGGER_ID` environment variable.
196
+
197
+
198
+
135
199
  ## Development
136
200
 
137
201
  After checking out the repo, run `bin/setup` to install dependencies.
@@ -6,6 +6,6 @@ class Dato::List < Dato::DastNode
6
6
  end
7
7
 
8
8
  def generated_tag
9
- @node.style == "bulleted" ? "ul" : "ol"
9
+ (@node.style == "bulleted") ? "ul" : "ol"
10
10
  end
11
11
  end
@@ -1,8 +1,8 @@
1
- <% if @live %>
1
+ <% if live %>
2
2
  <script type="text/javascript">
3
- const eventSourceUrl = '<%=@data.url %>';
4
- const componentKlass = '<%=@component_klass%>';
5
- const frameId = '<%=@frame_id%>';
3
+ const eventSourceUrl = '<%=data.url %>';
4
+ const componentKlass = '<%=component_klass%>';
5
+ const frameId = '<%=frame_id%>';
6
6
  const eventSource = new EventSource(eventSourceUrl);
7
7
  eventSource.addEventListener("update", (event) => {
8
8
  const params = new URLSearchParams({
@@ -14,7 +14,13 @@
14
14
  });
15
15
  </script>
16
16
 
17
- <%= turbo_frame_tag @frame_id %>
17
+ <%= turbo_frame_tag frame_id %>
18
18
  <% else %>
19
- <%= render(@component_klass.new(@data)) %>
19
+ <% if cache? %>
20
+ <%= Rails.cache.fetch(cache_key, expires_in: cache_time, namespace: Dato::Config.cache_namespace) do %>
21
+ <% render(component_klass.new(data)) %>
22
+ <% end %>
23
+ <% else %>
24
+ <%= render(component_klass.new(data)) %>
25
+ <% end %>
20
26
  <% end %>
@@ -7,11 +7,34 @@ module Dato
7
7
  class Live < ViewComponent::Base
8
8
  delegate :turbo_frame_tag, to: :helpers
9
9
 
10
+ attr_reader :component_klass, :query, :preview, :live
11
+
10
12
  def initialize(component_klass, query, preview: false, live: false)
11
- @data = dato_fetch(query, preview: preview, live: live)
13
+ super()
12
14
  @component_klass = component_klass
15
+ @query = query
16
+ @preview = preview
13
17
  @live = live
14
- @frame_id = SecureRandom.hex(10)
18
+ end
19
+
20
+ def cache?
21
+ Dato::Config.cache.present?
22
+ end
23
+
24
+ def cache_key
25
+ @cache_key ||= Digest::MD5.hexdigest(query.to_gql)
26
+ end
27
+
28
+ def cache_time
29
+ @cache_time ||= Dato::Config.cache.is_a?(Integer) ? Dato::Config.cache : 60.minutes
30
+ end
31
+
32
+ def data
33
+ @data ||= dato_fetch(query, preview: preview, live: live)
34
+ end
35
+
36
+ def frame_id
37
+ @frame_id ||= SecureRandom.hex(10)
15
38
  end
16
39
 
17
40
  private
@@ -2,8 +2,5 @@
2
2
 
3
3
  module Dato
4
4
  class UnknownBlock < Node
5
- def initialize(block, root)
6
- super(block, root)
7
- end
8
5
  end
9
6
  end
@@ -0,0 +1,37 @@
1
+ require "net/http"
2
+ require "uri"
3
+
4
+ module Dato
5
+ class PublishController < ActionController::Base
6
+ skip_before_action :verify_authenticity_token
7
+ before_action :check, only: :create
8
+
9
+ def create
10
+ Rails.cache.clear(namespace: Dato::Config.cache_namespace)
11
+
12
+ notify_success
13
+
14
+ render json: {message: "ok"}, status: :ok
15
+ end
16
+
17
+ def check
18
+ if request.headers["Authorization"] != Dato::Config.publish_key
19
+ render json: {message: "unauthorized"}, status: :unauthorized
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def notify_success
26
+ if Dato::Config.build_triggger_id.present?
27
+ Thread.new do
28
+ sleep 5 # wait for the build to finish
29
+ uri = URI("https://webhooks.datocms.com/#{Dato::Config.build_triggger_id}/deploy-results")
30
+ req = Net::HTTP::Post.new(uri, "Content-Type" => "application/json")
31
+ req.body = {status: "success"}.to_json
32
+ Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
data/config/routes.rb CHANGED
@@ -1,3 +1,4 @@
1
1
  Dato::Engine.routes.draw do
2
2
  get "live", to: "live#show"
3
+ post "publish", to: "publish#create"
3
4
  end
data/lib/dato/client.rb CHANGED
@@ -1,10 +1,11 @@
1
1
  module Dato
2
2
  class Client < GQLi::Client
3
3
  def initialize(api_token = ENV["DATO_API_TOKEN"], validate_query: false, preview: false, live: false)
4
+ @api_token = api_token
4
5
  super(
5
6
  "https://graphql#{"-listen" if live}.datocms.com/#{"preview" if preview}",
6
7
  headers: {
7
- "Authorization" => api_token
8
+ "Authorization" => @api_token
8
9
  },
9
10
  validate_query: validate_query && !live
10
11
  )
@@ -19,5 +20,14 @@ module Dato
19
20
  errors = parsed_response["errors"]
20
21
  GQLi::Response.new(parsed_response, errors, query)
21
22
  end
23
+
24
+ def search(query)
25
+ url = "https://site-api.datocms.com/search-results?query=#{query}&filter[build_trigger_id]=''"
26
+ response = HTTP.headers({
27
+ "Authorization" => "Bearer #{@api_token}",
28
+ "Accept" => "application/json",
29
+ "X-Api-Version" => 3
30
+ }).timeout(timeout_options).get(url)
31
+ end
22
32
  end
23
33
  end
data/lib/dato/config.rb CHANGED
@@ -4,5 +4,9 @@ module Dato
4
4
 
5
5
  config_accessor(:overrides) { {} }
6
6
  config_accessor(:blocks) { {} }
7
+ config_accessor(:cache) { false }
8
+ config_accessor(:cache_namespace) { "dato-rails" }
9
+ config_accessor(:publish_key) { ENV["DATO_PUBLISH_KEY"] }
10
+ config_accessor(:build_triggger_id) { ENV["DATO_BUILD_TRIGGER_ID"] }
7
11
  end
8
12
  end
data/lib/dato/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Dato
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dato-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alessandro Rodi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-04-04 00:00:00.000000000 Z
11
+ date: 2023-02-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec-rails
@@ -66,6 +66,34 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: vcr
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: webmock
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
69
97
  - !ruby/object:Gem::Dependency
70
98
  name: view_component
71
99
  requirement: !ruby/object:Gem::Requirement
@@ -177,6 +205,7 @@ files:
177
205
  - app/components/dato/unknown_node.html.erb
178
206
  - app/components/dato/unknown_node.rb
179
207
  - app/controllers/dato/live_controller.rb
208
+ - app/controllers/dato/publish_controller.rb
180
209
  - app/views/dato/live/show.html.erb
181
210
  - config/routes.rb
182
211
  - lib/dato.rb
@@ -191,7 +220,7 @@ licenses: []
191
220
  metadata:
192
221
  homepage_uri: https://github.com/renuo/dato-rails
193
222
  source_code_uri: https://github.com/renuo/dato-rails
194
- changelog_uri: https://github.com/renuo/dato-rails/CHANGELOG.md
223
+ changelog_uri: https://github.com/renuo/dato-rails/blob/main/CHANGELOG.md
195
224
  post_install_message:
196
225
  rdoc_options: []
197
226
  require_paths:
@@ -207,7 +236,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
207
236
  - !ruby/object:Gem::Version
208
237
  version: '0'
209
238
  requirements: []
210
- rubygems_version: 3.3.10
239
+ rubygems_version: 3.4.1
211
240
  signing_key:
212
241
  specification_version: 4
213
242
  summary: Use Dato CMS in your Rails application.