solidus_content 0.1.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 (89) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +72 -0
  3. data/.gem_release.yml +5 -0
  4. data/.github/stale.yml +17 -0
  5. data/.gitignore +20 -0
  6. data/.rspec +2 -0
  7. data/.rubocop.yml +38 -0
  8. data/Gemfile +38 -0
  9. data/LICENSE +26 -0
  10. data/README.md +439 -0
  11. data/Rakefile +6 -0
  12. data/app/assets/javascripts/spree/backend/solidus_content.js +2 -0
  13. data/app/assets/javascripts/spree/frontend/solidus_content.js +2 -0
  14. data/app/assets/stylesheets/spree/backend/solidus_content.css +4 -0
  15. data/app/assets/stylesheets/spree/frontend/solidus_content.css +4 -0
  16. data/app/controllers/solidus_content/resource_controller.rb +35 -0
  17. data/app/controllers/spree/admin/entries_controller.rb +25 -0
  18. data/app/controllers/spree/admin/entry_types_controller.rb +25 -0
  19. data/app/controllers/spree/solidus_content_controller.rb +13 -0
  20. data/app/models/solidus_content/application_record.rb +5 -0
  21. data/app/models/solidus_content/entry.rb +44 -0
  22. data/app/models/solidus_content/entry_type.rb +55 -0
  23. data/app/models/solidus_content/provider/fields.rb +20 -0
  24. data/app/views/spree/admin/entries/_form.html.erb +31 -0
  25. data/app/views/spree/admin/entries/_options_form.html.erb +18 -0
  26. data/app/views/spree/admin/entries/edit.html.erb +16 -0
  27. data/app/views/spree/admin/entries/index.html.erb +54 -0
  28. data/app/views/spree/admin/entries/new.html.erb +21 -0
  29. data/app/views/spree/admin/entry_types/_form.html.erb +30 -0
  30. data/app/views/spree/admin/entry_types/_options_form.html.erb +16 -0
  31. data/app/views/spree/admin/entry_types/edit.html.erb +16 -0
  32. data/app/views/spree/admin/entry_types/index.html.erb +54 -0
  33. data/app/views/spree/admin/entry_types/new.html.erb +21 -0
  34. data/app/views/spree/admin/shared/_solidus_content_sub_menu.html.erb +9 -0
  35. data/bin/console +17 -0
  36. data/bin/rails +7 -0
  37. data/bin/rails-engine +13 -0
  38. data/bin/rails-sandbox +16 -0
  39. data/bin/rake +7 -0
  40. data/bin/rspec +7 -0
  41. data/bin/sandbox +84 -0
  42. data/bin/setup +8 -0
  43. data/config/initializers/spree.rb +12 -0
  44. data/config/locales/en.yml +51 -0
  45. data/config/routes.rb +14 -0
  46. data/db/migrate/20200207135842_create_solidus_content_entries.rb +11 -0
  47. data/db/migrate/20200306110114_create_solidus_content_entry_types.rb +12 -0
  48. data/lib/generators/solidus_content/install/install_generator.rb +36 -0
  49. data/lib/generators/solidus_content/install/templates/initializer.rb +20 -0
  50. data/lib/solidus_content.rb +10 -0
  51. data/lib/solidus_content/active_record.rb +7 -0
  52. data/lib/solidus_content/configuration.rb +38 -0
  53. data/lib/solidus_content/engine.rb +19 -0
  54. data/lib/solidus_content/factories.rb +13 -0
  55. data/lib/solidus_content/providers.rb +23 -0
  56. data/lib/solidus_content/providers/contentful.rb +36 -0
  57. data/lib/solidus_content/providers/json.rb +27 -0
  58. data/lib/solidus_content/providers/prismic.rb +36 -0
  59. data/lib/solidus_content/providers/raw.rb +22 -0
  60. data/lib/solidus_content/providers/solidus_static_content.rb +23 -0
  61. data/lib/solidus_content/providers/yaml.rb +33 -0
  62. data/lib/solidus_content/version.rb +5 -0
  63. data/solidus_content.gemspec +36 -0
  64. data/spec/features/admin/content/create_entry_spec.rb +36 -0
  65. data/spec/features/admin/content/create_entry_type_spec.rb +36 -0
  66. data/spec/features/admin/content/delete_entry_spec.rb +20 -0
  67. data/spec/features/admin/content/delete_entry_type_spec.rb +20 -0
  68. data/spec/features/admin/content/edit_entry_spec.rb +45 -0
  69. data/spec/features/admin/content/edit_entry_type_spec.rb +44 -0
  70. data/spec/features/admin/content/list_entries_spec.rb +33 -0
  71. data/spec/features/admin/content/list_entry_types_spec.rb +33 -0
  72. data/spec/features/admin/sidebar_spec.rb +19 -0
  73. data/spec/features/render_content_with_views_spec.rb +41 -0
  74. data/spec/fixtures/content/example.json +1 -0
  75. data/spec/fixtures/content/example.yaml +1 -0
  76. data/spec/fixtures/content/example.yml +1 -0
  77. data/spec/fixtures/content/example_2.yaml +1 -0
  78. data/spec/models/solidus_content/entry_spec.rb +100 -0
  79. data/spec/models/solidus_content/entry_type_spec.rb +106 -0
  80. data/spec/solidus_content/configuration_spec.rb +37 -0
  81. data/spec/solidus_content/providers/contentful_spec.rb +56 -0
  82. data/spec/solidus_content/providers/json_spec.rb +33 -0
  83. data/spec/solidus_content/providers/prismic_spec.rb +82 -0
  84. data/spec/solidus_content/providers/solidus_static_content_spec.rb +34 -0
  85. data/spec/solidus_content/providers/yaml_spec.rb +51 -0
  86. data/spec/solidus_content_spec.rb +23 -0
  87. data/spec/spec_helper.rb +32 -0
  88. data/spec/support/warden.rb +5 -0
  89. metadata +206 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e98fe492987ee0529a11e434b3d832a76ff4eeb07e44f3084d9eb1b79b18c87e
4
+ data.tar.gz: f73fd253f4f1ccbd4aca79833bcfc2ceb15aa5c27f2064cda84cf64dacea300d
5
+ SHA512:
6
+ metadata.gz: 256fb4d66dfa430f90638cb31688ac951f3860f7951e8366253a1935628c99e7ba0197c1611d075adf7cc8200a786e241c9f0dc8d9a1d1f67d818f4c86f44b2c
7
+ data.tar.gz: da6e62c6b2fe8fe5e26c225df3fe511fecec3575213d44aa618cb29dfe36e8d01203a9e0984225359a530e97f4177191bccc13ec7fea862878e38ec7f49cc498
@@ -0,0 +1,72 @@
1
+ version: 2.1
2
+
3
+ orbs:
4
+ # Always take the latest version of the orb, this allows us to
5
+ # run specs against Solidus supported versions only without the need
6
+ # to change this configuration every time a Solidus version is released
7
+ # or goes EOL.
8
+ solidusio_extensions: solidusio/extensions@volatile
9
+
10
+ jobs:
11
+ run-specs-with-postgres:
12
+ executor: solidusio_extensions/postgres
13
+ steps:
14
+ - solidusio_extensions/run-tests
15
+ run-specs-with-mysql:
16
+ executor: solidusio_extensions/mysql
17
+ steps:
18
+ - solidusio_extensions/run-tests
19
+ lint-code:
20
+ executor: solidusio_extensions/sqlite-memory
21
+ steps:
22
+ - checkout
23
+ - run:
24
+ name: 'Solidus master: Generate Gemfile.lock'
25
+ command: bundle lock
26
+ environment:
27
+ SOLIDUS_BRANCH: master
28
+ when: always
29
+ - restore_cache:
30
+ name: 'Solidus master: Restore Bundler cache'
31
+ keys:
32
+ - gems-v3-ruby-v2-5-6-solidus-master-{{ .Branch }}-{{ checksum "Gemfile.lock" }}
33
+ - gems-v3-ruby-v2-5-6-solidus-master-
34
+ when: always
35
+ - run:
36
+ name: 'Solidus master: Install gems'
37
+ command: bundle install --path=vendor/bundle
38
+ environment:
39
+ SOLIDUS_BRANCH: master
40
+ when: always
41
+ - save_cache:
42
+ name: 'Solidus master: Save Bundler cache'
43
+ key: gems-v3-ruby-v2-5-6-solidus-master-{{ .Branch }}-{{ checksum "Gemfile.lock" }}
44
+ paths:
45
+ - vendor/bundle
46
+ when: always
47
+ - run:
48
+ name: 'Runs RuboCop on Solidus master'
49
+ command: bundle exec rubocop -ESP
50
+ environment:
51
+ SOLIDUS_BRANCH: master
52
+ TEST_RESULTS_PATH: test-results/gems-v3-ruby-v2-5-6-solidus-master/results.xml
53
+ when: always
54
+
55
+ workflows:
56
+ "Run specs on supported Solidus versions":
57
+ jobs:
58
+ - run-specs-with-postgres
59
+ - run-specs-with-mysql
60
+ - lint-code
61
+
62
+ "Weekly run specs against master":
63
+ triggers:
64
+ - schedule:
65
+ cron: "0 0 * * 4" # every Thursday
66
+ filters:
67
+ branches:
68
+ only:
69
+ - master
70
+ jobs:
71
+ - run-specs-with-postgres
72
+ - run-specs-with-mysql
@@ -0,0 +1,5 @@
1
+ bump:
2
+ recurse: false
3
+ file: 'lib/solidus_content/version.rb'
4
+ message: Bump SolidusContent to %{version}
5
+ tag: true
@@ -0,0 +1,17 @@
1
+ # Number of days of inactivity before an issue becomes stale
2
+ daysUntilStale: 60
3
+ # Number of days of inactivity before a stale issue is closed
4
+ daysUntilClose: 7
5
+ # Issues with these labels will never be considered stale
6
+ exemptLabels:
7
+ - pinned
8
+ - security
9
+ # Label to use when marking an issue as stale
10
+ staleLabel: wontfix
11
+ # Comment to post when marking an issue as stale. Set to `false` to disable
12
+ markComment: >
13
+ This issue has been automatically marked as stale because it has not had
14
+ recent activity. It will be closed if no further activity occurs. Thank you
15
+ for your contributions.
16
+ # Comment to post when closing a stale issue. Set to `false` to disable
17
+ closeComment: false
@@ -0,0 +1,20 @@
1
+ *.gem
2
+ \#*
3
+ *~
4
+ .#*
5
+ .DS_Store
6
+ .idea
7
+ .project
8
+ .sass-cache
9
+ coverage
10
+ Gemfile.lock
11
+ tmp
12
+ nbproject
13
+ pkg
14
+ *.swp
15
+ spec/dummy
16
+ spec/examples.txt
17
+ /sandbox
18
+ .rvmrc
19
+ .ruby-version
20
+ .ruby-gemset
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
@@ -0,0 +1,38 @@
1
+ require:
2
+ - solidus_dev_support/rubocop
3
+
4
+ AllCops:
5
+ Exclude:
6
+ - sandbox/**/*
7
+ - spec/dummy/**/*
8
+ - vendor/bundle/**/*
9
+
10
+ RSpec/DescribeClass:
11
+ Enabled: false
12
+
13
+ Style/ClassAndModuleChildren:
14
+ Enabled: false
15
+
16
+ Rails/ApplicationRecord:
17
+ Enabled: false
18
+
19
+ RSpec/MessageSpies:
20
+ Enabled: false
21
+
22
+ RSpec/MultipleExpectations:
23
+ Enabled: false
24
+
25
+ RSpec/NamedSubject:
26
+ Enabled: false
27
+
28
+ Style/FrozenStringLiteralComment:
29
+ Exclude:
30
+ - spec/**/*
31
+ - db/migrate/**/*
32
+ - bin/**/*
33
+
34
+ RSpec/NestedGroups:
35
+ Enabled: false
36
+
37
+ RSpec/VerifiedDoubles:
38
+ IgnoreSymbolicNames: true
data/Gemfile ADDED
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
5
+
6
+ branch = ENV.fetch('SOLIDUS_BRANCH', 'master')
7
+ gem 'solidus', github: 'solidusio/solidus', branch: branch
8
+
9
+ # Needed to help Bundler figure out how to resolve dependencies,
10
+ # otherwise it takes forever to resolve them.
11
+ # See https://github.com/bundler/bundler/issues/6677
12
+ gem 'rails', '>0.a'
13
+
14
+ # Provides basic authentication functionality for testing parts of your engine
15
+ gem 'solidus_auth_devise'
16
+
17
+ case ENV['DB']
18
+ when 'mysql'
19
+ gem 'mysql2'
20
+ when 'postgresql'
21
+ gem 'pg'
22
+ else
23
+ gem 'sqlite3'
24
+ end
25
+
26
+ # Supported content providers
27
+ gem 'contentful'
28
+ gem 'prismic.io', require: 'prismic'
29
+ gem 'solidus_static_content', github: 'solidusio-contrib/solidus_static_content'
30
+
31
+ gemspec
32
+
33
+ # Use a local Gemfile to include development dependencies that might not be
34
+ # relevant for the project or for other contributors, e.g. pry-byebug.
35
+ #
36
+ # We use `send` instead of calling `eval_gemfile` to work around an issue with
37
+ # how Dependabot parses projects: https://github.com/dependabot/dependabot-core/issues/1658.
38
+ send(:eval_gemfile, 'Gemfile-local') if File.exist? 'Gemfile-local'
data/LICENSE ADDED
@@ -0,0 +1,26 @@
1
+ Copyright (c) 2020 Nebulab
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+ * Neither the name Solidus nor the names of its contributors may be used to
13
+ endorse or promote products derived from this software without specific
14
+ prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,439 @@
1
+
2
+ # SolidusContent
3
+
4
+ [![nebulab](https://circleci.com/gh/nebulab/solidus_content.svg?style=shield)](https://app.circleci.com/pipelines/github/nebulab/solidus_content)
5
+
6
+ Introduction goes here.
7
+
8
+ ## Installation
9
+
10
+ Add solidus_content to your Gemfile:
11
+
12
+ ```ruby
13
+ gem 'solidus_content'
14
+ ```
15
+
16
+ Bundle your dependencies and run the installation generator:
17
+
18
+ ```shell
19
+ bundle
20
+ bin/rails generate solidus_content:install
21
+ ```
22
+
23
+ ## Usage
24
+
25
+ Create an entry type for the home page:
26
+
27
+ ```rb
28
+ home_entry_type = SolidusContent::EntryType.create!(
29
+ name: :home,
30
+ provider_name: :json,
31
+ options: { path: 'data/home' }
32
+ )
33
+ ```
34
+
35
+ Create a default entry for the home page:
36
+
37
+ ```rb
38
+ home = SolidusContent::Entry.create!(
39
+ entry_type: home_entry_type,
40
+ slug: :default,
41
+ )
42
+ ```
43
+
44
+ And then write a file inside your app root under `data/home/default.json`:
45
+
46
+ ```json
47
+ {"title":"Hello World!"}
48
+ ```
49
+
50
+ ### Within an existing view
51
+
52
+ Use the content inside an existing view, e.g. `app/views/spree/home/index.html.erb`:
53
+
54
+ ```erb
55
+ <% data = SolidusContent::Entry.data_for(:home, 'default') %>
56
+
57
+ <h1><%= data[:title] %></h1>
58
+ ```
59
+
60
+ ### With the default route
61
+
62
+ SolidusContent will add a default route that starts with `/c/`, by adding a view
63
+ inside `app/views/spree/solidus_content/` with the name of the entry type you'll
64
+ be able to render your content.
65
+
66
+ E.g. `app/views/spree/solidus_content/home.html.erb`:
67
+ ```erb
68
+ <h1><%= @entry.data[:title] %></h1>
69
+ ```
70
+
71
+ Then, visit `/c/home/default` or even just `/c/home` (when the content slug is
72
+ "default" it can be omitted).
73
+
74
+
75
+ ### With a custom route
76
+
77
+ You can also define a custom route in your `Application` routes file and use
78
+ the `SolidusContent` controller to render your content from a dedicated view:
79
+
80
+ ```rb
81
+ # config/routes.rb
82
+ Rails.application.routes.draw do
83
+ # Will render app/views/spree/solidus_content/home.html.erb
84
+ root to: 'spree/solidus_content#show', type: :home, id: :default
85
+
86
+ # Will render app/views/spree/solidus_content/info.html.erb
87
+ get "privacy", to: 'spree/solidus_content#show', type: :info, id: :privacy
88
+ get "legal", to: 'spree/solidus_content#show', type: :info, id: :legal
89
+
90
+ # Will render app/views/spree/solidus_content/post.html.erb
91
+ get "blog/:id", to: 'spree/solidus_content#show', type: :post
92
+
93
+ mount Spree::Core::Engine, at: '/'
94
+ end
95
+ ```
96
+
97
+ ## Configuration
98
+
99
+ Configure SolidusContent in an initializer:
100
+
101
+ ```rb
102
+ # config/initializers/solidus_content.rb
103
+
104
+ SolidusContent.configure do |config|
105
+ # Your configuration goes here, please refer to the examples provided in the
106
+ # initializer generated by `bin/rails g solidus_content:install`
107
+ end
108
+ ```
109
+
110
+ ## Available Content Providers
111
+
112
+ ### RAW
113
+
114
+ This is the most simple provider, its data will come directly from the entry
115
+ options.
116
+
117
+ ```rb
118
+ posts = SolidusContent::EntryType.create(
119
+ name: 'posts',
120
+ provider_name: 'raw',
121
+ )
122
+ entry = SolidusContent::Entry.create(
123
+ slug: '2020-03-27-hello-world',
124
+ entry_type: posts,
125
+ options: { title: "Hello World!", body: "My first post!" }
126
+ )
127
+ ```
128
+
129
+ ### JSON
130
+
131
+ Will fetch the data from a JSON file within the directory specified by the
132
+ `path` entry-type option and with a basename corresponding to the entry `slug`.
133
+
134
+ ```rb
135
+ posts = SolidusContent::EntryType.create(
136
+ name: 'posts',
137
+ provider_name: 'json',
138
+ options: { path: 'data/posts' }
139
+ )
140
+ entry = SolidusContent::Entry.create(
141
+ slug: '2020-03-27-hello-world',
142
+ entry_type: posts,
143
+ )
144
+ ```
145
+
146
+ ```jsonc
147
+ // [RAILS_ROOT]/data/posts/2020-03-27-hello-world.json
148
+ {"title": "Hello World!", "body": "My first post!"}
149
+ ```
150
+
151
+ _NOTE: Absolute paths are taken as they are and won't be joined to `Rails.root`._
152
+
153
+ ### YAML
154
+
155
+ Will fetch the data from a YAML file within the directory specified by the
156
+ `path` entry-type option and with a basename corresponding to the entry `slug`.
157
+
158
+ If there isn't a file with the `yml` extension, the `yaml` extension will be tried.
159
+
160
+ ```rb
161
+ posts = SolidusContent::EntryType.create(
162
+ name: 'posts',
163
+ provider_name: 'yaml',
164
+ options: { path: 'data/posts' }
165
+ )
166
+ entry = SolidusContent::Entry.create(
167
+ slug: '2020-03-27-hello-world',
168
+ entry_type: posts,
169
+ )
170
+ ```
171
+
172
+ ```yaml
173
+ # [RAILS_ROOT]/data/posts/2020-03-27-hello-world.yml
174
+
175
+ title: Hello World!
176
+ body: My first post!
177
+ ```
178
+
179
+ _NOTE: Absolute paths are taken as they are and won't be joined to `Rails.root`._
180
+
181
+ ### Solidus static content
182
+
183
+ To retrieve the page we have to pass the page `slug` to the entry options.
184
+ If the page slug is the same of the entry one, we can avoid passing the options.
185
+
186
+ ```rb
187
+ posts = SolidusContent::EntryType.create(
188
+ name: 'posts',
189
+ provider_name: 'solidus_static_content'
190
+ )
191
+
192
+ entry = SolidusContent::Entry.create!(
193
+ slug: '2020-03-27-hello-world',
194
+ entry_type: posts,
195
+ options: { slug: 'XXX' } # Can be omitted if the page slug is the same of the entry
196
+ )
197
+ ```
198
+
199
+ _Be sure to have added `gem "solidus_static_content"` to your Gemfile._
200
+
201
+ ### Contentful
202
+
203
+ To fetch the data we have to create a connection with Contentful passing the
204
+ `contentful_space_id` and the `contentful_access_token` to the entry-type options.
205
+
206
+ Will fetch the data from Contentful passing the `entry_id` entry option.
207
+
208
+ ```rb
209
+ posts = SolidusContent::EntryType.create(
210
+ name: 'posts',
211
+ provider_name: 'contentful',
212
+ options: {
213
+ contentful_space_id: 'XXX',
214
+ contentful_access_token: 'XXX'
215
+ }
216
+ )
217
+
218
+ entry = SolidusContent::Entry.create!(
219
+ slug: '2020-03-27-hello-world',
220
+ entry_type: posts,
221
+ options: { entry_id: 'XXX' }
222
+ )
223
+ ```
224
+
225
+ _Be sure to have added `gem "contentful"` to your Gemfile._
226
+
227
+ ### Prismic
228
+
229
+ To fetch the data we have to create a connection with Prismic passing the
230
+ `api_entry_point` to the entry-type options.
231
+
232
+ If the repository is private, you have to also pass the `api_token` to the entry-type options.
233
+
234
+ Will fetch the data from Prismic passing the `id` entry option.
235
+
236
+ ```rb
237
+ posts = SolidusContent::EntryType.create(
238
+ name: 'posts',
239
+ provider_name: 'prismic',
240
+ options: {
241
+ api_entry_point: 'XXX',
242
+ api_token: 'XXX' # Only if the repository is private
243
+ }
244
+ )
245
+
246
+ entry = SolidusContent::Entry.create!(
247
+ slug: '2020-03-27-hello-world',
248
+ entry_type: posts,
249
+ options: { id: 'XXX' }
250
+ )
251
+ ```
252
+
253
+ _Be sure to have added `gem "prismic.io"` to your Gemfile._
254
+
255
+ ### Renderful
256
+
257
+ The [Renderful](https://github.com/nebulab/renderful) provider works a bit differently from other
258
+ providers because of how Renderful is configured.
259
+
260
+ The provider is not registered by default, and you'll have to register it manually by passing your
261
+ Renderful instance:
262
+
263
+ ```ruby
264
+ # [RAILS_ROOT]/config/initializers/solidus_content.rb
265
+
266
+ require 'solidus_content/providers/renderful'
267
+
268
+ renderful = Renderful::Client.new(...)
269
+
270
+ SolidusContent.config.register_provider(
271
+ :renderful_contentful,
272
+ SolidusContent::Providers::Renderful.new(renderful),
273
+ )
274
+ ```
275
+
276
+ Once configured, you'll be able to use it like all other providers:
277
+
278
+ ```ruby
279
+ posts = SolidusContent::EntryType.create(
280
+ name: 'posts',
281
+ provider_name: 'renderful_contentful',
282
+ )
283
+
284
+ entry = SolidusContent::Entry.create!(
285
+ slug: '2020-03-27-hello-world',
286
+ entry_type: posts,
287
+ options: { id: 'XXX' }
288
+ )
289
+ ```
290
+
291
+ *Unlike other providers,* however, Renderful will not pass the raw entity fields to your view.
292
+ Instead, you will get a `:render_in` proc that you should call with your view context. The call
293
+ will be forwarded to Renderful, which will render your content:
294
+
295
+ ```erb
296
+ <%= @entry.data[:render_in].(self) %>
297
+ ```
298
+
299
+ ### Registering a content provider
300
+
301
+ To register a content-provider, add a callable to the configuration under the
302
+ name you prefer. The
303
+
304
+ ```rb
305
+ SolidusContent.config.register_provider :json, ->(input) {
306
+ dir = Rails.root.join(input.dig(:type_options, :path))
307
+ file = dir.join(input[:slug] + '.json')
308
+ data = JSON.parse(file.read, symbolize_names: true)
309
+
310
+ input.merge(data: data)
311
+ }
312
+ ```
313
+
314
+ The `input` passed to the content-provider will have the following keys:
315
+
316
+ - `slug`: the slug of the content-entry
317
+ - `type`: the name of the content-type
318
+ - `provider`: the name of the content-provider
319
+ - `options`: the entry options
320
+ - `type_options`: the content-type options
321
+
322
+ The `output` of the content-provider is the `input` hash augmented with the
323
+ following keys:
324
+
325
+ - `data`: the content itself
326
+ - `provider_client`: (optional) the client of the external service
327
+ - `provider_entry`: (optional) the object retrieved from the external service
328
+
329
+ In both the input and output all keys should be symbolized.
330
+
331
+ ## Connecting Webhooks
332
+
333
+ Many content providers such as Contentful or Prismic can send payloads via webhooks when content changes, those can be very useful in a number of ways.
334
+
335
+ We suggest using the [`solidus_webhooks`](http://github.com/solidusio-contrib/solidus_webhooks#readme) extension to get the most out of `solidus_content`, let's see some examples.
336
+
337
+ Add this to your Gemfile:
338
+
339
+ ```rb
340
+ gem "solidus_webhooks"
341
+ ```
342
+
343
+ ### Using Webhooks to Auto-Create entries
344
+
345
+ In this example we setup a webhook that will create or update Contentful entries whenever they're changed or created.
346
+
347
+ ```rb
348
+ # config/initializers/webhooks.rb
349
+
350
+ SolidusWebhooks.config.register_webhook_handler :contentful, -> payload {
351
+ next unless payload.dig(:sys, :Type) == "Entry"
352
+ entry_type = SolidusContent::EntryType.find_or_create_by(
353
+ name: payload.dig(:sys, :ContentType, :sys, :id),
354
+ provider_name: :raw
355
+ )
356
+ entry = entry_type.entries.find_or_initialize_by(slug: payload.dig(:sys, :id))
357
+ entry.options = payload.fetch(:fields)
358
+ }
359
+ ```
360
+
361
+ ### Using Webhooks to expire caches
362
+
363
+ When caching the content of `app/views/spree/home/index.html.erb` as in this example:
364
+
365
+ ```erb
366
+ <% cache(@entry) do %>
367
+ <h1><%= @entry.data[:title] %></h1>
368
+ <% end %>
369
+ ```
370
+
371
+ You may want to setup a webhook that will touch the entry every time it's modified:
372
+
373
+ ```rb
374
+ # config/initializers/webhooks.rb
375
+
376
+ SolidusWebhooks.config.register_webhook_handler :prismic, -> payload {
377
+ prismic_entry_types = SolidusContent::EntryType.where(provider_name: :prismic)
378
+
379
+ # Prismic doesn't give much informations about which entries have been changed,
380
+ # so we're touching them all.
381
+ SolidusContent::Entry.where(entry_type: prismic_entry_types).touch_all
382
+ }
383
+ ```
384
+
385
+ *NOTE: `touch_all` was introduced in Rails 6, for earlier versions use `find_each(&:touch)`.*
386
+
387
+ ## Development
388
+
389
+ ### Testing the extension
390
+
391
+ First bundle your dependencies, then run `bin/rake`. `bin/rake` will default to building the dummy
392
+ app if it does not exist, then it will run specs. The dummy app can be regenerated by using
393
+ `bin/rake extension:test_app`.
394
+
395
+ ```shell
396
+ bundle
397
+ bin/rake
398
+ ```
399
+
400
+ To run [Rubocop](https://github.com/bbatsov/rubocop) static code analysis run
401
+
402
+ ```shell
403
+ bundle exec rubocop
404
+ ```
405
+
406
+ When testing your application's integration with this extension you may use its factories.
407
+ Simply add this require statement to your spec_helper:
408
+
409
+ ```ruby
410
+ require 'solidus_content/factories'
411
+ ```
412
+
413
+ ### Running the sandbox
414
+
415
+ To run this extension in a sandboxed Solidus application, you can run `bin/sandbox`. The path for
416
+ the sandbox app is `./sandbox` and `bin/rails` will forward any Rails commands to
417
+ `sandbox/bin/rails`.
418
+
419
+ Here's an example:
420
+
421
+ ```shell
422
+ $ bin/rails server
423
+ => Booting Puma
424
+ => Rails 6.0.2.1 application starting in development
425
+ * Listening on tcp://127.0.0.1:3000
426
+ Use Ctrl-C to stop
427
+ ```
428
+
429
+ ### Releasing new versions
430
+
431
+ Your new extension version can be released using `gem-release` like this:
432
+
433
+ ```shell
434
+ bundle exec gem bump -v VERSION --tag --push --remote upstream && gem release
435
+ ```
436
+
437
+ ## License
438
+
439
+ Copyright (c) 2020 Nebulab, released under the New BSD License