rubyblok 1.1.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +0 -137
  3. data/CHANGELOG.md +13 -0
  4. data/README.md +130 -41
  5. data/Rakefile +1 -1
  6. data/lib/generators/rubyblok/hello_world_generator.rb +12 -10
  7. data/lib/generators/rubyblok/image_cache_generator.rb +77 -0
  8. data/lib/generators/rubyblok/install_generator.rb +7 -5
  9. data/lib/generators/rubyblok/migration_generator.rb +10 -8
  10. data/lib/generators/rubyblok/sitemap_config_generator.rb +40 -0
  11. data/lib/generators/rubyblok/webhook_controller_generator.rb +9 -7
  12. data/lib/generators/templates/carrier_wave_config.rb.erb +13 -0
  13. data/lib/generators/templates/image_cache_model.rb.erb +3 -0
  14. data/lib/generators/templates/image_cache_uploader.rb.erb +12 -0
  15. data/lib/generators/templates/migration_create_image_cache.rb.erb +12 -0
  16. data/lib/generators/templates/migration_update_image_cache.rb.erb +8 -0
  17. data/lib/generators/templates/rubyblok.rb +27 -6
  18. data/lib/generators/templates/sitemap.rb.erb +14 -0
  19. data/lib/rubyblok/configuration.rb +4 -3
  20. data/lib/rubyblok/helpers/storyblok_helper.rb +56 -17
  21. data/lib/rubyblok/mixins/model.rb +13 -1
  22. data/lib/rubyblok/mixins/model_cache_class.rb +15 -0
  23. data/lib/rubyblok/mixins/webhook.rb +32 -9
  24. data/lib/rubyblok/railtie.rb +8 -2
  25. data/lib/rubyblok/services/get_storyblok_story.rb +5 -3
  26. data/lib/rubyblok/services/replace_storyblok_url.rb +64 -0
  27. data/lib/rubyblok/version.rb +1 -1
  28. data/lib/rubyblok.rb +18 -15
  29. data/lib/tasks/rubyblok/create_or_update_content.rake +36 -0
  30. data/rubyblok.gemspec +17 -17
  31. metadata +13 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 387e9c3d34367e3cbc2f7bd45bb3c38358e203e009f0d7a79f77c2f0569e590c
4
- data.tar.gz: 13d329d7a0d6498124ee602b9252722051b4bf6f01e62186cc9c6b61fd26da69
3
+ metadata.gz: 97de159fda2be4c48fe193e20470427a8d387b751adf6e6c736cc540ded7bb93
4
+ data.tar.gz: 9e0db1ebff8bcb3d3fc319c1f82c1e43a9c178be17f4cff130263c8f6013579c
5
5
  SHA512:
6
- metadata.gz: 663185c2a74652136c644306457bb110d5c67290826f100e14c4e033e543f7db68bdb24b1f8d5843d78d20e32760ddc861b8f57abedba05cf9da73092f36041f
7
- data.tar.gz: b2000c3d50bc5eef358a3b2cffc43cb2e980f89f63cf0b8a8acc7ac83bfc568e3b0440fd0029473a4f3ba792fd9e416d7e85164eafcc03a4677f81e0082239be
6
+ metadata.gz: 989944be668f8fd1948ce7a708fcbe26015c847d0bfd5ef181998776af887c1524d3a5e671085efa9890d857e401d389eee52cd8d73aad96cc5d6d8dbc054a90
7
+ data.tar.gz: 0db3897c8213431fe5bc44a0bb0f0c3025988ee9dc1d3db6dced4e01c3d6833c7c4098df75bbbcb216d7633d21d9bc356d705a2e1289fb6a13c1b4445465ef01
data/.rubocop.yml CHANGED
@@ -6,146 +6,9 @@ AllCops:
6
6
  NewCops: enable
7
7
  TargetRubyVersion: 3.1.X
8
8
 
9
- Capybara/VisibilityMatcher:
10
- Enabled: false
11
-
12
9
  Documentation:
13
10
  Enabled: false
14
-
15
- Layout/HashAlignment:
16
- Enabled: false
17
11
  Layout/LineLength:
18
12
  Max: 120
19
- Layout/MultilineMethodCallIndentation:
20
- EnforcedStyle: aligned
21
- Lint/AmbiguousBlockAssociation:
22
- Exclude:
23
- - spec/**/*
24
- Lint/IneffectiveAccessModifier:
25
- Enabled: false
26
- Lint/MissingSuper:
27
- Enabled: false
28
- Lint/RedundantSplatExpansion:
29
- Enabled: false
30
- Lint/UriEscapeUnescape:
31
- Enabled: false
32
- Metrics/BlockLength:
33
- Enabled: false
34
- Metrics/ClassLength:
35
- Max: 500
36
- Metrics/ModuleLength:
37
- Max: 250
38
- Exclude:
39
- - spec/**/*
40
- Naming/AccessorMethodName:
41
- Enabled: false
42
- Naming/BlockForwarding:
43
- Enabled: false
44
- Naming/InclusiveLanguage:
45
- Enabled: false
46
- Naming/FileName:
47
- Enabled: false
48
- Naming/MemoizedInstanceVariableName:
49
- Enabled: false
50
- Naming/PredicateName:
51
- Enabled: false
52
- Naming/VariableNumber:
53
- Enabled: false
54
- Style/ClassAndModuleChildren:
55
- Enabled: false
56
- Style/Documentation:
57
- Enabled: false
58
- Style/ExponentialNotation:
59
- Enabled: false
60
- Style/FetchEnvVar:
61
- Enabled: true
62
- Exclude:
63
- - spec/**/*
64
- Style/FormatString:
65
- Enabled: false
66
- Style/FormatStringToken:
67
- Enabled: false
68
- Style/FrozenStringLiteralComment:
69
- Enabled: false
70
- Style/HashSyntax:
71
- EnforcedStyle: ruby19
72
- Style/InPatternThen:
73
- Enabled: false
74
- Style/MultilineInPatternThen:
75
- Enabled: false
76
- Style/MapToHash:
77
- Enabled: false
78
- Style/NumericLiteralPrefix:
79
- Enabled: false
80
- Style/NumericPredicate:
81
- Enabled: false
82
- Style/OpenStructUse:
83
- Enabled: false
84
- Style/SafeNavigation:
85
- Enabled: false
86
- Style/StringLiterals:
87
- EnforcedStyle: double_quotes
88
- Style/TrailingCommaInArrayLiteral:
89
- EnforcedStyleForMultiline: comma
90
- Style/TrailingCommaInHashLiteral:
91
- EnforcedStyleForMultiline: comma
92
-
93
- RSpec/AnyInstance:
94
- Enabled: false
95
- RSpec/ChangeByZero:
96
- Enabled: false
97
- RSpec/ContextWording:
98
- Enabled: false
99
- RSpec/DescribedClass:
100
- Enabled: false
101
- RSpec/DescribeClass:
102
- Enabled: false
103
- RSpec/ExampleLength:
104
- Enabled: false
105
- RSpec/ExampleWording:
106
- Enabled: false
107
- RSpec/ExpectInHook:
108
- Enabled: false
109
- RSpec/HooksBeforeExamples:
110
- Enabled: false
111
- RSpec/ImplicitBlockExpectation:
112
- Enabled: false
113
- RSpec/InstanceVariable:
114
- Exclude:
115
- - spec/views/**/*
116
- RSpec/LetBeforeExamples:
117
- Enabled: false
118
- RSpec/LetSetup:
119
- Enabled: false
120
- RSpec/MessageChain:
121
- Enabled: false
122
- RSpec/MessageSpies:
123
- Enabled: false
124
- RSpec/MultipleDescribes:
125
- Enabled: false
126
- RSpec/MultipleExpectations:
127
- Enabled: false
128
- RSpec/MultipleMemoizedHelpers:
129
- Enabled: false
130
- RSpec/NamedSubject:
131
- Enabled: false
132
13
  RSpec/NestedGroups:
133
14
  Enabled: false
134
- RSpec/RepeatedDescription:
135
- Enabled: false
136
- RSpec/RepeatedExampleGroupBody:
137
- Enabled: false
138
- RSpec/RepeatedExampleGroupDescription:
139
- Enabled: false
140
- RSpec/StubbedMock:
141
- Enabled: false
142
- RSpec/VerifiedDoubles:
143
- Enabled: false
144
- RSpec/VerifiedDoubleReference:
145
- Enabled: false
146
- RSpec/FilePath:
147
- Enabled: false
148
- RSpec/SpecFilePathFormat:
149
- Enabled: false
150
- Style/FetchEnvVar:
151
- Enabled: false
data/CHANGELOG.md CHANGED
@@ -2,6 +2,19 @@
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
+
12
+ ## [1.2.0] - 2024-06-17
13
+
14
+ ### Added
15
+ - Caching Storyblok images on S3
16
+ - Fragment caching of Rubyblok components
17
+
5
18
  ## [1.1.0] - 2024-05-02
6
19
 
7
20
  ### Added
data/README.md CHANGED
@@ -8,13 +8,18 @@ This integration allows you to edit your content online, preview it in real-time
8
8
  In addition, Rubyblok provides an abstraction layer and stores all your content locally, reducing data usage and enhancing performance. This enables new functionalities that leverage the local data, such as global content search, sitemaps, and listings. Ultimately, this setup increases resilience by eliminating dependency on external data sources.
9
9
 
10
10
  ## Table of Contents
11
- 1. [Installation](#installation)
12
- 2. [Getting Started](#getting-started)
13
- 3. [Rubyblok tags](#rubyblok-tags)
14
- 4. [How to Run Tests](#how-to-run-tests)
15
- 5. [Guide for Contributing](#guide-for-contributing)
16
- 6. [How to Contact Us](#how-to-contact-us)
17
- 7. [License](#license)
11
+ 1. [Installation](#installation)
12
+ 2. [Getting Started](#getting-started)
13
+ 3. [Rubyblok tags](#rubyblok-tags)
14
+ 4. [Rubyblok workflows](#rubyblok-workflows)
15
+ 5. [Rubyblok webhook](#rubyblok-webhook)
16
+ 6. [Caching storyblok images](#caching-storyblok-images)
17
+ 7. [Caching views](#caching-views)
18
+ 8. [Sitemap configuration](#sitemap-configuration)
19
+ 9. [How to Run Tests](#how-to-run-tests)
20
+ 10. [Guide for Contributing](#guide-for-contributing)
21
+ 11. [How to Contact Us](#how-to-contact-us)
22
+ 12. [License](#license)
18
23
 
19
24
  ## Installation
20
25
  Rubyblok 1.0 works with Rails 6.0 onwards. Run:
@@ -29,28 +34,14 @@ Create a new Space, in _My Spaces > Add Space_. Select the free Community plan b
29
34
 
30
35
  Get your Storyblok API token in your account, at _Storyblok Space > Settings > Access tokens_ page. Copy the "Preview" access level key.
31
36
 
32
- Add the key to your `STORYBLOK_API_TOKEN` in your env file, like this example:
37
+ Add the API token to your `config/initializers/rubyblok.rb` file:
33
38
 
34
39
  ```
35
- STORYBLOK_API_TOKEN=<your API token>
36
- ```
37
- You will also need to add the variables below to your env file:
38
- ```
39
- STORYBLOK_VERSION=draft
40
- STORYBLOK_WEBHOOK_SECRET=''
40
+ config.api_token = <your API token>
41
41
  ```
42
42
 
43
43
  ## Getting Started
44
44
 
45
- ### Necessary gems
46
- You need to add some gems to your app for Rubyblok to work correctly. Run the following commands:
47
-
48
- ```bash
49
- bundle add "storyblok"
50
- bundle add "hash_dot"
51
- bundle add "dotenv-rails"
52
- ```
53
-
54
45
  ### Hello world - Your first Rubyblok page
55
46
  Let's get started with Rubyblok by creating your first page in three steps.
56
47
  Note that it is important that you have your Storyblok space set up as described above, in the `Storyblok account and new space` section.
@@ -62,25 +53,25 @@ rails g rubyblok:install
62
53
 
63
54
  2. Now let's generate and run a migration to create the `pages` table and the `Page` model:
64
55
  ```bash
65
- rails g rubyblok:migration page
56
+ rails g rubyblok:migration PAGE
66
57
 
67
58
  rails db:migrate
68
59
  ```
69
60
 
70
61
  3. Finally, let's generate your first page:
71
62
  ```bash
72
- rails g rubyblok:hello_world page
63
+ rails g rubyblok:hello_world PAGE
73
64
  ```
74
- This will automatically create a new route, controller, views and styling for your hello world page.
65
+ This will automatically create a new `/pages` route, a `PagesController`, views and styling for your hello world page.
75
66
 
76
- For this example, go to the `rubyblok.rb` file and turn the caching option off:
67
+ For this example, go to the `config/initializers/rubyblok.rb` file and turn the caching option off:
77
68
  ```
78
69
  config.cached = false
79
70
  ```
80
71
 
81
- 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.
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.
82
73
 
83
- ### Activate the visual editor
74
+ ### Activate the visual editor
84
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.
85
76
 
86
77
  At Storyblok, select your Space and go to _Settings > Visual Editor_.
@@ -111,14 +102,6 @@ This will start a proxy server.
111
102
 
112
103
  By doing this initial setup, you are able to see your first Storyblok page inside your app and edit its content in the Storyblok admin interface 🎉
113
104
 
114
- ### Storyblok webhook
115
- 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)
116
-
117
- Generate the webhook controller:
118
- ```bash
119
- rails g rubyblok:webhook_controller storyblok_webhook
120
- ```
121
-
122
105
  ## Rubyblok tags
123
106
 
124
107
  ### rubyblok_story_tag
@@ -127,7 +110,7 @@ Use this tag to render stories:
127
110
  # Slug: full_slug of the storyblok story
128
111
  <%= rubyblok_story_tag(slug) %>
129
112
  ```
130
- The name of the storyblok blok should match the rails partial, ie the `header` storyblok blok should have a corresponding `_header.html.erb` partial in the `config.component_path` directory. The partial is called with a `blok` local variable which contains the storyblok blok properties.
113
+ The name of the storyblok block should match the rails partial, ie if the block is named `header`, it should have a corresponding `_header.html.erb` partial in the directory defined in `config.component_path`. The partial is called with a `blok` local variable which contains the storyblok block properties.
131
114
 
132
115
  ### rubyblok_content_tag
133
116
  It renders content of Text, TextArea, Markdown or Richtext storyblok fields.
@@ -155,20 +138,126 @@ text = {
155
138
  # Output: "<p>this is a richtext</p>"
156
139
  ```
157
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
+
158
143
  ### rubyblok_blocks_tag
159
144
  Use this tag to render more than one component:
160
145
  ```
161
146
  <%= rubyblok_blocks_tag(blok.bloks) %>
162
147
  ```
163
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
+
164
151
  ### Updating content manually at the caching layer
165
152
  In case you need to update the caching layer with new content added to Storyblok, run the following command:
166
153
  ```
167
154
  # Slug: full_slug of the storyblok story
168
- storyblok_story_content = Rubyblok::Services::GetStoryblokStory.call(slug: slug)
169
- <MODEL_NAME>.find_or_initialize_by(storyblok_story_slug: page)
170
- .update(storyblok_story_content:, storyblok_story_id: storyblok_story_content["id"])
155
+ storyblok_story = Rubyblok::Services::GetStoryblokStory.call(slug: slug)
156
+ <MODEL_NAME>.find_or_create(storyblok_story)
157
+ ```
158
+
159
+ ## Rubyblok workflows
160
+
161
+ ### Non-cached mode (default)
162
+ Rubyblok fetches the content via the Storyblok API and the content is not cached locally.
163
+
164
+ ### Cached mode
165
+ Rubyblok fetches the content from the local database. This mode is useful ie. if you don't want to call the API on every page request or you want to index the content locally. To enable this mode you need to set the cached feature on in the `config/initializers/rubyblok.rb` file:
166
+ ```
167
+ config.cached = true
168
+ ```
169
+
170
+ If you want to update the local cache on every page request (ie. the content is not updated via the webhook), you need to set the auto_update feature on in the `config/initializers/rubyblok.rb` file:
171
+ ```
172
+ config.auto_update = true
173
+ ```
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
+
187
+ ## Storyblok webhook
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)
189
+
190
+ 1. First generate the webhook controller:
191
+ ```bash
192
+ rails g rubyblok:webhook_controller STORYBLOK_WEBHOOK
193
+ ```
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
+
200
+ ## Caching storyblok images
201
+ You can store your storyblok images and videos on your own S3 storage by enabling this rubyblok feature.
202
+
203
+ 1. First, you need to run the image cache generator, which will create the model file, the uploader file and the carrierwave config file for you:
204
+ ```bash
205
+ rails g rubyblok:image_cache STORYBLOK_IMAGE
206
+ ```
207
+
208
+ 2. Add the following gems to your Gemfile:
209
+ ```
210
+ bundle add 'carrierwave'
211
+ bundle add 'fog-aws'
212
+
213
+ ```
214
+
215
+ 3. Now let's run a migration to create the `storyblok_images` table:
216
+ ```bash
217
+ rails db:migrate
218
+ ```
219
+
220
+ 4. Finally, enable the image cache feature in the `config/initializers/rubyblok.rb` file:
221
+ ```
222
+ config.use_cdn_images = true
223
+ ```
224
+
225
+ Please note that it caches only images added as an `Asset` field type in Storyblok.
226
+
227
+ ## Caching views
228
+
229
+ You can enable fragment caching on rubyblok components by setting the cache_views feature on in the `config/initializers/rubyblok.rb` file:
230
+ ```
231
+ config.cache_views = true
232
+ ```
233
+ Please note that if any of the component partials changes you need to clear the cache.
234
+
235
+ ## Sitemap configuration
236
+ You can generate a sitemap configuration for your website with the following command:
237
+ ```
238
+ rails g rubyblok:sitemap_config
239
+ ```
240
+ This generator will create a sitemap configuration for the `sitemap_generator` gem and add the gem to your Gemfile in case it's not already there.
241
+ The sitemap is generated only for cached content. Please make sure that the `cached` configuration value is `true` on `config/initializers/rubyblok.rb`.
242
+ Open `config/sitemap.rb` and add your hostname:
243
+ ```
244
+ # ...
245
+
246
+ # TODO: Configure your hostname here
247
+ SitemapGenerator::Sitemap.default_host = ''
248
+
249
+ # ...
250
+ ```
251
+ For example:
252
+ ```
253
+ # ...
254
+
255
+ # TODO: Configure your hostname here
256
+ SitemapGenerator::Sitemap.default_host = 'https://myhost.com'
257
+
258
+ # ...
171
259
  ```
260
+ In order to generate your sitemap or customize this configuration, please read [the sitemap_generator gem documentation](https://github.com/kjvarga/sitemap_generator).
172
261
 
173
262
  ## How to Run Tests
174
263
  You can run unit tests for RubyBlok with the following command:
data/Rakefile CHANGED
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "bundler/gem_tasks"
3
+ require 'bundler/gem_tasks'
4
4
  task default: %i[]
@@ -1,9 +1,11 @@
1
- require "rails/generators"
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators'
2
4
 
3
5
  module Rubyblok
4
6
  module Generators
5
7
  class HelloWorldGenerator < Rails::Generators::NamedBase
6
- source_root File.expand_path("../templates", __dir__)
8
+ source_root File.expand_path('../templates', __dir__)
7
9
 
8
10
  desc 'Generates a "Hello, world" Rubyblok page.'
9
11
 
@@ -16,23 +18,23 @@ module Rubyblok
16
18
  private
17
19
 
18
20
  def add_controller
19
- template("hello_world_generator/controller.rb.erb", "app/controllers/#{plural_file_name}_controller.rb")
21
+ template('hello_world_generator/controller.rb.erb', "app/controllers/#{plural_file_name}_controller.rb")
20
22
  end
21
23
 
22
24
  def add_route
23
- insert_into_file("config/routes.rb", after: "Rails.application.routes.draw do") do
25
+ insert_into_file('config/routes.rb', after: 'Rails.application.routes.draw do') do
24
26
  "\n get '/#{plural_file_name}' => '#{plural_file_name}#index'\n"
25
27
  end
26
28
  end
27
29
 
28
30
  def copy_views
29
- template("hello_world_generator/index.html.erb", "app/views/#{plural_file_name}/index.html.erb")
30
- template("hello_world_generator/_feature.html.erb", "app/views/#{destination_partial_path}/_feature.html.erb")
31
- template("hello_world_generator/_page.html.erb", "app/views/#{destination_partial_path}/_page.html.erb")
32
- template("hello_world_generator/_grid.html.erb", "app/views/#{destination_partial_path}/_grid.html.erb")
33
- template("hello_world_generator/_teaser.html.erb", "app/views/#{destination_partial_path}/_teaser.html.erb")
31
+ template('hello_world_generator/index.html.erb', "app/views/#{plural_file_name}/index.html.erb")
32
+ template('hello_world_generator/_feature.html.erb', "app/views/#{destination_partial_path}/_feature.html.erb")
33
+ template('hello_world_generator/_page.html.erb', "app/views/#{destination_partial_path}/_page.html.erb")
34
+ template('hello_world_generator/_grid.html.erb', "app/views/#{destination_partial_path}/_grid.html.erb")
35
+ template('hello_world_generator/_teaser.html.erb', "app/views/#{destination_partial_path}/_teaser.html.erb")
34
36
 
35
- copy_file("hello_world_generator/styles.css", "app/assets/stylesheets/hello.css")
37
+ copy_file('hello_world_generator/styles.css', 'app/assets/stylesheets/hello.css')
36
38
  end
37
39
 
38
40
  def destination_partial_path
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators'
4
+ require 'rails/generators/active_record'
5
+
6
+ module Rubyblok
7
+ module Generators
8
+ class ImageCacheGenerator < ::Rails::Generators::NamedBase
9
+ include ::Rails::Generators::Migration
10
+ source_root File.expand_path('../templates', __dir__)
11
+ desc 'Installs image cache migration and model files.'
12
+
13
+ def install
14
+ if table_exist?
15
+ migration_template('migration_update_image_cache.rb.erb', "db/migrate/update_#{plural_file_name}.rb",
16
+ migration_version:)
17
+ else
18
+ migration_template('migration_create_image_cache.rb.erb', "db/migrate/create_#{plural_file_name}.rb",
19
+ migration_version:)
20
+ end
21
+
22
+ create_or_update_model
23
+ add_model_name_to_config
24
+ end
25
+
26
+ def self.next_migration_number(dirname)
27
+ ActiveRecord::Generators::Base.next_migration_number(dirname)
28
+ end
29
+
30
+ private
31
+
32
+ def migration_version
33
+ "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
34
+ end
35
+
36
+ def table_exist?
37
+ ActiveRecord::Base.connection.table_exists?(plural_file_name.to_sym)
38
+ end
39
+
40
+ def create_or_update_model
41
+ if table_exist?
42
+ add_mixins_to_existing_model
43
+ else
44
+ generate_new_model_from_template
45
+ end
46
+ end
47
+
48
+ def add_mixins_to_existing_model
49
+ model_path = "app/models/#{file_name}.rb"
50
+ mixins_code = "\n mount_uploader :image, #{class_name}Uploader\n"
51
+
52
+ insert_into_file model_path, after: "class #{class_name} < ApplicationRecord" do
53
+ mixins_code
54
+ end
55
+
56
+ add_uploader_and_config
57
+ end
58
+
59
+ def generate_new_model_from_template
60
+ template('image_cache_model.rb.erb', "app/models/#{file_name}.rb")
61
+ add_uploader_and_config
62
+ end
63
+
64
+ def add_uploader_and_config
65
+ template('image_cache_uploader.rb.erb', "app/uploaders/#{file_name}_uploader.rb")
66
+ template('carrier_wave_config.rb.erb', 'config/initializers/carrier_wave.rb')
67
+ end
68
+
69
+ def add_model_name_to_config
70
+ model_path = 'config/initializers/rubyblok.rb'
71
+ insert_into_file model_path, after: 'config.image_model_name = "' do
72
+ class_name
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -1,15 +1,17 @@
1
- require "rails/generators"
2
- require "rails/generators/active_record"
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators'
4
+ require 'rails/generators/active_record'
3
5
 
4
6
  module Rubyblok
5
7
  module Generators
6
8
  class InstallGenerator < Rails::Generators::Base
7
- source_root File.expand_path("../templates", __dir__)
9
+ source_root File.expand_path('../templates', __dir__)
8
10
 
9
- desc "Generates an initializer file."
11
+ desc 'Generates an initializer file.'
10
12
 
11
13
  def copy_initializer
12
- template("rubyblok.rb", "config/initializers/rubyblok.rb")
14
+ template('rubyblok.rb', 'config/initializers/rubyblok.rb')
13
15
  end
14
16
  end
15
17
  end
@@ -1,19 +1,21 @@
1
- require "rails/generators"
2
- require "rails/generators/active_record"
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators'
4
+ require 'rails/generators/active_record'
3
5
 
4
6
  module Rubyblok
5
7
  module Generators
6
8
  class MigrationGenerator < ::Rails::Generators::NamedBase
7
9
  include ::Rails::Generators::Migration
8
- source_root File.expand_path("../templates", __dir__)
9
- desc "Installs Rubyblok migration and model files."
10
+ source_root File.expand_path('../templates', __dir__)
11
+ desc 'Installs Rubyblok migration and model files.'
10
12
 
11
13
  def install
12
14
  if table_exist?
13
- migration_template("migration_update.rb.erb", "db/migrate/update_rubyblok_#{plural_file_name}.rb",
15
+ migration_template('migration_update.rb.erb', "db/migrate/update_rubyblok_#{plural_file_name}.rb",
14
16
  migration_version:)
15
17
  else
16
- migration_template("migration_create.rb.erb", "db/migrate/create_rubyblok_#{plural_file_name}.rb",
18
+ migration_template('migration_create.rb.erb', "db/migrate/create_rubyblok_#{plural_file_name}.rb",
17
19
  migration_version:)
18
20
  end
19
21
 
@@ -53,11 +55,11 @@ module Rubyblok
53
55
  end
54
56
 
55
57
  def generate_new_model_from_template
56
- template("model.rb.erb", "app/models/#{file_name}.rb")
58
+ template('model.rb.erb', "app/models/#{file_name}.rb")
57
59
  end
58
60
 
59
61
  def add_model_name_to_config
60
- model_path = "config/initializers/rubyblok.rb"
62
+ model_path = 'config/initializers/rubyblok.rb'
61
63
  insert_into_file model_path, after: 'config.model_name = "' do
62
64
  class_name
63
65
  end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators'
4
+
5
+ module Rubyblok
6
+ module Generators
7
+ class SitemapConfigGenerator < Rails::Generators::Base
8
+ source_root File.expand_path('../templates', __dir__)
9
+
10
+ desc 'Generates a configuration for the sitemap_generator gem'
11
+
12
+ def generate_sitemap_config
13
+ copy_config
14
+ add_sitemap_generator_gem
15
+ end
16
+
17
+ private
18
+
19
+ def copy_config
20
+ template('sitemap.rb.erb', 'config/sitemap.rb')
21
+ end
22
+
23
+ def add_sitemap_generator_gem
24
+ append_to_file(gemfile_path) { "gem 'sitemap_generator'" } if add_sitemap_generator_gem?
25
+ end
26
+
27
+ def add_sitemap_generator_gem?
28
+ !gemfile_content.match?(/\bsitemap_generator\b/)
29
+ end
30
+
31
+ def gemfile_content
32
+ File.read(gemfile_path)
33
+ end
34
+
35
+ def gemfile_path
36
+ Rails.root.join('Gemfile')
37
+ end
38
+ end
39
+ end
40
+ end