solidus_content 0.1.0

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