rubyblok 1.2.0 → 1.3.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 +4 -4
- data/.rubocop.yml +2 -0
- data/CHANGELOG.md +7 -0
- data/README.md +23 -2
- data/lib/rubyblok/helpers/storyblok_helper.rb +12 -6
- data/lib/rubyblok/mixins/model_cache_class.rb +15 -0
- data/lib/rubyblok/mixins/webhook.rb +27 -6
- data/lib/rubyblok/railtie.rb +4 -0
- data/lib/rubyblok/version.rb +1 -1
- data/lib/rubyblok.rb +2 -2
- data/lib/tasks/rubyblok/create_or_update_content.rake +36 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 97de159fda2be4c48fe193e20470427a8d387b751adf6e6c736cc540ded7bb93
|
4
|
+
data.tar.gz: 9e0db1ebff8bcb3d3fc319c1f82c1e43a9c178be17f4cff130263c8f6013579c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 989944be668f8fd1948ce7a708fcbe26015c847d0bfd5ef181998776af887c1524d3a5e671085efa9890d857e401d389eee52cd8d73aad96cc5d6d8dbc054a90
|
7
|
+
data.tar.gz: 0db3897c8213431fe5bc44a0bb0f0c3025988ee9dc1d3db6dced4e01c3d6833c7c4098df75bbbcb216d7633d21d9bc356d705a2e1289fb6a13c1b4445465ef01
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,13 @@
|
|
2
2
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
|
5
|
+
## [1.3.0] - 2024-07-04
|
6
|
+
|
7
|
+
### Added
|
8
|
+
- Securing webhook with secret token
|
9
|
+
- Visibility property on components
|
10
|
+
- Rake task to download all content
|
11
|
+
|
5
12
|
## [1.2.0] - 2024-06-17
|
6
13
|
|
7
14
|
### Added
|
data/README.md
CHANGED
@@ -71,7 +71,7 @@ config.cached = false
|
|
71
71
|
|
72
72
|
Now you have created your first Hello World page! Start your Rails server, access the `/pages` route and you will be able to see the page.
|
73
73
|
|
74
|
-
### Activate the visual editor
|
74
|
+
### Activate the visual editor
|
75
75
|
Here are the steps to configure the visual editor at Storyblok. This allows you to see a preview of your changes in the Storyblok interface as you edit and save.
|
76
76
|
|
77
77
|
At Storyblok, select your Space and go to _Settings > Visual Editor_.
|
@@ -138,12 +138,16 @@ text = {
|
|
138
138
|
# Output: "<p>this is a richtext</p>"
|
139
139
|
```
|
140
140
|
|
141
|
+
You can prevent rendering content on production by adding a boolean field type with the name "invisible_on_production" to your Storyblok block.
|
142
|
+
|
141
143
|
### rubyblok_blocks_tag
|
142
144
|
Use this tag to render more than one component:
|
143
145
|
```
|
144
146
|
<%= rubyblok_blocks_tag(blok.bloks) %>
|
145
147
|
```
|
146
148
|
|
149
|
+
You can prevent rendering content on production by adding a boolean field type with the name "invisible_on_production" to your Storyblok block.
|
150
|
+
|
147
151
|
### Updating content manually at the caching layer
|
148
152
|
In case you need to update the caching layer with new content added to Storyblok, run the following command:
|
149
153
|
```
|
@@ -168,14 +172,31 @@ If you want to update the local cache on every page request (ie. the content is
|
|
168
172
|
config.auto_update = true
|
169
173
|
```
|
170
174
|
|
175
|
+
You can also use the rake task `rubyblok:create_or_update_content` to update the local cache:
|
176
|
+
|
177
|
+
```bash
|
178
|
+
rails rubyblok:create_or_update_content # Using the version configured on `Rubyblok.configuration.version`.
|
179
|
+
```
|
180
|
+
|
181
|
+
or with the `version` argument (`draft` or `published`):
|
182
|
+
|
183
|
+
```bash
|
184
|
+
rails rubyblok:create_or_update_content[published]
|
185
|
+
```
|
186
|
+
|
171
187
|
## Storyblok webhook
|
172
188
|
The Storyblok webhook will be responsible for updating and deleting content in the local database in case of changes. [Learn more here.](https://www.storyblok.com/docs/guide/in-depth/webhooks)
|
173
189
|
|
174
|
-
|
190
|
+
1. First generate the webhook controller:
|
175
191
|
```bash
|
176
192
|
rails g rubyblok:webhook_controller STORYBLOK_WEBHOOK
|
177
193
|
```
|
178
194
|
|
195
|
+
2. You need to set the webhook secret used in Storyblok in the `config/initializers/rubyblok.rb` file:
|
196
|
+
```
|
197
|
+
config.webhook_secret = 'secret'
|
198
|
+
```
|
199
|
+
|
179
200
|
## Caching storyblok images
|
180
201
|
You can store your storyblok images and videos on your own S3 storage by enabling this rubyblok feature.
|
181
202
|
|
@@ -1,6 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'rubyblok/mixins/model_cache_class'
|
4
|
+
|
3
5
|
module StoryblokHelper
|
6
|
+
include Rubyblok::Mixins::ModelCacheClass
|
7
|
+
|
4
8
|
def rubyblok_content_tag(content)
|
5
9
|
return if content.blank?
|
6
10
|
|
@@ -26,9 +30,15 @@ module StoryblokHelper
|
|
26
30
|
end
|
27
31
|
|
28
32
|
def rubyblok_component_tag(blok:, partial: blok.component)
|
33
|
+
return if invisible_on_production?(blok)
|
34
|
+
|
29
35
|
render_partial(partial:, locals: { blok: }).prepend(rubyblok_editable_tag(blok).to_s)
|
30
36
|
end
|
31
37
|
|
38
|
+
def invisible_on_production?(blok)
|
39
|
+
Rails.env.production? && blok.fetch('invisible_on_production', false)
|
40
|
+
end
|
41
|
+
|
32
42
|
# rubocop:disable Rails/OutputSafety
|
33
43
|
def rubyblok_markdown_tag(content)
|
34
44
|
markdown_renderer.render(content).html_safe
|
@@ -67,22 +77,18 @@ module StoryblokHelper
|
|
67
77
|
def get_story_via_api(slug, save: false)
|
68
78
|
story = Rubyblok::Services::GetStoryblokStory.call(slug:)
|
69
79
|
replace_storyblok_url(story).tap do |storyblok_story|
|
70
|
-
|
80
|
+
model_cache_class.find_or_create(storyblok_story) if save
|
71
81
|
end
|
72
82
|
end
|
73
83
|
|
74
84
|
def get_story_via_cache(slug)
|
75
|
-
|
85
|
+
model_cache_class.fetch_content(slug)
|
76
86
|
end
|
77
87
|
|
78
88
|
def replace_storyblok_url(story)
|
79
89
|
Rubyblok::Services::ReplaceStoryblokUrl.call(story:)
|
80
90
|
end
|
81
91
|
|
82
|
-
def model
|
83
|
-
Rubyblok.configuration.model_name.classify.constantize
|
84
|
-
end
|
85
|
-
|
86
92
|
def rich_text_renderer
|
87
93
|
ctx = {}
|
88
94
|
path = component_path
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support/concern'
|
4
|
+
|
5
|
+
module Rubyblok
|
6
|
+
module Mixins
|
7
|
+
module ModelCacheClass
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
def model_cache_class
|
11
|
+
Rubyblok.configuration.model_name.classify.constantize
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -6,24 +6,45 @@ module Rubyblok
|
|
6
6
|
module Mixins
|
7
7
|
module Webhook
|
8
8
|
extend ActiveSupport::Concern
|
9
|
+
include Rubyblok::Mixins::ModelCacheClass
|
9
10
|
|
10
|
-
included do
|
11
|
+
included do # rubocop:disable Metrics/BlockLength
|
11
12
|
skip_before_action :verify_authenticity_token, only: [:create]
|
12
13
|
|
13
14
|
def create
|
15
|
+
verify_signature(request.raw_post) if webhook_secret.present?
|
16
|
+
|
14
17
|
payload = JSON.parse(request.raw_post)
|
18
|
+
case payload['action']
|
19
|
+
when 'published'
|
20
|
+
update_story(payload)
|
21
|
+
when 'unpublished', 'deleted'
|
22
|
+
model_cache_class.find_by(storyblok_story_id: payload['story_id'])&.destroy!
|
23
|
+
end
|
24
|
+
|
25
|
+
render(json: { success: true })
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
15
29
|
|
30
|
+
def update_story(payload)
|
16
31
|
storyblok_story = Rubyblok::Services::GetStoryblokStory.call(slug: payload['story_id'])
|
17
32
|
storyblok_story = Rubyblok::Services::ReplaceStoryblokUrl.call(story: storyblok_story)
|
18
|
-
|
33
|
+
model_cache_class.find_or_create(storyblok_story)
|
34
|
+
end
|
19
35
|
|
20
|
-
|
36
|
+
def verify_signature(payload_body)
|
37
|
+
signature =
|
38
|
+
OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'), webhook_secret, payload_body)
|
39
|
+
raise StandardError, 'Signature check failed!' unless verified?(signature)
|
21
40
|
end
|
22
41
|
|
23
|
-
|
42
|
+
def verified?(signature)
|
43
|
+
Rack::Utils.secure_compare(signature, request.env['HTTP_WEBHOOK_SIGNATURE'])
|
44
|
+
end
|
24
45
|
|
25
|
-
def
|
26
|
-
Rubyblok.configuration.
|
46
|
+
def webhook_secret
|
47
|
+
Rubyblok.configuration.webhook_secret
|
27
48
|
end
|
28
49
|
end
|
29
50
|
end
|
data/lib/rubyblok/railtie.rb
CHANGED
data/lib/rubyblok/version.rb
CHANGED
data/lib/rubyblok.rb
CHANGED
@@ -7,10 +7,11 @@ require 'hash_dot'
|
|
7
7
|
require_relative 'rubyblok/helpers/storyblok_helper'
|
8
8
|
require_relative 'rubyblok/version'
|
9
9
|
require_relative 'rubyblok/configuration'
|
10
|
-
require_relative 'rubyblok/railtie' if defined?(Rails)
|
10
|
+
require_relative 'rubyblok/railtie' if defined?(Rails::Railtie)
|
11
11
|
require_relative 'rubyblok/services/get_storyblok_story'
|
12
12
|
require_relative 'rubyblok/services/replace_storyblok_url'
|
13
13
|
require_relative 'rubyblok/mixins/model'
|
14
|
+
require_relative 'rubyblok/mixins/model_cache_class'
|
14
15
|
require_relative 'rubyblok/mixins/webhook'
|
15
16
|
require_relative 'generators/rubyblok/migration_generator'
|
16
17
|
require_relative 'generators/rubyblok/install_generator'
|
@@ -29,5 +30,4 @@ module Rubyblok
|
|
29
30
|
end
|
30
31
|
|
31
32
|
class Error < StandardError; end
|
32
|
-
# Your code goes here...
|
33
33
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
PER_PAGE = 50
|
4
|
+
|
5
|
+
namespace :rubyblok do
|
6
|
+
desc 'Create or update cached Storyblok stories'
|
7
|
+
task :create_or_update_content, [:version] => [:environment] do |_task, args|
|
8
|
+
include Rubyblok::Mixins::ModelCacheClass
|
9
|
+
|
10
|
+
args.with_defaults(version: Rubyblok.configuration.version)
|
11
|
+
|
12
|
+
raise ArgumentError, "Invalid version \"#{args[:version]}\"" unless %w[draft published].include?(args[:version])
|
13
|
+
|
14
|
+
client = storyblok_client(args[:version])
|
15
|
+
page = 1
|
16
|
+
|
17
|
+
loop do
|
18
|
+
stories = get_stories(client:, page:)
|
19
|
+
break if stories.empty?
|
20
|
+
|
21
|
+
stories.each { |story| model_cache_class.find_or_create(story) }
|
22
|
+
|
23
|
+
page += 1
|
24
|
+
|
25
|
+
sleep 1
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def storyblok_client(version)
|
30
|
+
Storyblok::Client.new(token: Rubyblok.configuration.api_token, version:)
|
31
|
+
end
|
32
|
+
|
33
|
+
def get_stories(client:, page:)
|
34
|
+
client.stories(page:, per_page: PER_PAGE).dig('data', 'stories')
|
35
|
+
end
|
36
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubyblok
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- 100 Starlings
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-07-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hash_dot
|
@@ -107,11 +107,13 @@ files:
|
|
107
107
|
- lib/rubyblok/configuration.rb
|
108
108
|
- lib/rubyblok/helpers/storyblok_helper.rb
|
109
109
|
- lib/rubyblok/mixins/model.rb
|
110
|
+
- lib/rubyblok/mixins/model_cache_class.rb
|
110
111
|
- lib/rubyblok/mixins/webhook.rb
|
111
112
|
- lib/rubyblok/railtie.rb
|
112
113
|
- lib/rubyblok/services/get_storyblok_story.rb
|
113
114
|
- lib/rubyblok/services/replace_storyblok_url.rb
|
114
115
|
- lib/rubyblok/version.rb
|
116
|
+
- lib/tasks/rubyblok/create_or_update_content.rake
|
115
117
|
- rubyblok.gemspec
|
116
118
|
homepage: http://www.rubyblok.com
|
117
119
|
licenses:
|