README.md in wcc-contentful-1.3.2 vs README.md in wcc-contentful-1.4.0.rc1
- old
+ new
@@ -30,11 +30,11 @@
11. [License](#license)
## Why did you rewrite the Contentful ruby stack?
-We started working with Contentful almost 3 years ago. Since that time, Contentful's ruby stack has improved, but there are still a number of pain points that we feel we have addressed better with our gem. These are:
+We started working with Contentful almost 5 years ago. Since that time, Contentful's ruby stack has improved, but there are still a number of pain points that we feel we have addressed better with our gem. These are:
* [Low-level caching](#low-level-caching)
* [Better integration with Rails & Rails models](#better-rails-integration)
* [Automatic pagination and Automatic link resolution](#automatic-pagination-and-link-resolution)
* [Automatic webhook management](#automatic-webhook-management)
@@ -158,27 +158,39 @@
The following examples show how to use this API to find entries of the `page`
content type:
```ruby
+# app/models/page.rb
+class Page < WCC::Contentful::Model::Page
+
+ # You can add additional methods here
+end
+
# Find objects by id
-WCC::Contentful::Model::Page.find('1E2ucWSdacxxf233sfa3')
-# => #<WCC::Contentful::Model::Page:0x0000000005c71a78 @created_at=2018-04-16 18:41:17 UTC...>
+Page.find('1E2ucWSdacxxf233sfa3')
+# => #<Page:0x0000000005c71a78 @created_at=2018-04-16 18:41:17 UTC...>
# Find objects by field
-WCC::Contentful::Model::Page.find_by(slug: '/some-slug')
-# => #<WCC::Contentful::Model::Page:0x0000000005c71a78 @created_at=2018-04-16 18:41:17 UTC...>
+Page.find_by(slug: '/some-slug')
+# => #<Page:0x0000000005c71a78 @created_at=2018-04-16 18:41:17 UTC...>
# Use operators to filter by a field
# must use full notation for sys attributes (except ID)
-WCC::Contentful::Model::Page.find_all('sys.created_at' => { lte: Date.today })
-# => [#<WCC::Contentful::Model::Page:0x0000000005c71a78 @created_at=2018-04-16 18:41:17 UTC...>, ... ]
+Page.find_all('sys.created_at' => { lte: Date.today })
+# => [#<Page:0x0000000005c71a78 @created_at=2018-04-16 18:41:17 UTC...>, ... ]
# Nest queries to mimick joins
-WCC::Contentful::Model::Page.find_by(subpages: { slug: '/some-slug' })
-# => #<WCC::Contentful::Model::Page:0x0000000005c71a78 @created_at=2018-04-16 18:41:17 UTC...>
+Page.find_by(subpages: { slug: '/some-slug' })
+# => #<Page:0x0000000005c71a78 @created_at=2018-04-16 18:41:17 UTC...>
+# Fetch an entry in a different locale
+spanish_homepage = Page.find_by(slug: '/', options: { locale: 'es-US' })
+# => #<Page:0x0000000005c71a78 @created_at=2018-04-16 18:41:17 UTC...>
+spanish_homepage.title
+# => Esta es la página principal
+
# Pass the preview flag to use the preview client (must have set preview_token config param)
preview_redirect = WCC::Contentful::Model::Redirect.find_by({ slug: 'draft-redirect' }, preview: true)
# => #<WCC::Contentful::Model::Redirect:0x0000000005d879ad @created_at=2018-04-16 18:41:17 UTC...>
preview_redirect_object.href
# => 'http://www.somesite.com/slug-for-redirect'
@@ -222,10 +234,22 @@
# => #<Enumerator::Lazy: ...>
query.result.force
# => [{"sys"=> ...}, {"sys"=> ...}, ...]
```
+The store layer, while superficially similar to the Contentful API, tries to present a different "View" over the data
+which is more compatible with the Model layer. It resolves includes by actually replacing the in-memory `Link` objects
+with their linked `Entry` representations. This lets you traverse the links naturally using `#dig` or `#[]`:
+
+```ruby
+# Include to a depth of 3 to make sure it's included
+homepage = store.find_by(slug: '/', include: 3)
+# Traverse through the top nav menu => menu button 0 => about page
+about_page = homepage.dig('fields', 'nav_menu', 'fields', 'buttons', 0, 'fields', 'page')
+```
+
+
See the {WCC::Contentful::Store} documentation for more details.
### Direct CDN API (SimpleClient)
The SimpleClient is the bottom layer, and is used to get raw data directly from
@@ -392,16 +416,41 @@
newest version of an entry, or delete an entry out of the hash.
#### Store Middleware
The store layer is made up of a base store (which implements {WCC::Contentful::Store::Interface}),
-and optional middleware. The middleware
-allows custom transformation of received entries via the `#select` and `#transform`
-methods. To create your own middleware simply include {WCC::Contentful::Middleware::Store}
-and implement those methods, then call `use` when configuring the store:
+and some required middleware. The list of default middleware applied to each store is found in
+{WCC::Contentful::Store::Factory.default_middleware}
+To create your own middleware simply include {WCC::Contentful::Middleware::Store}. Then you can optionally implement
+the `#transform` and `#select?` methods:
+
```ruby
+class MyMiddleware
+ include WCC::Contentful::Middleware::Store
+
+ # Called for each entry that is requested out of the backing store. You can modify the entry and return it to the
+ # next layer.
+ def transform(entry, options)
+ # Do something with the entry...
+ # Make sure you return it at the end!
+ entry
+ end
+
+ def select?(entry, options)
+ # Choose whether this entry should exist or not. If you return false here, then the entry will act as though it
+ # were archived in Contentful.
+ entry.dig('fields', 'hide_until') > Time.zone.now
+ end
+end
+```
+
+You can also override any of the standard Store methods.
+
+To apply the middleware, call `use` when configuring the store:
+
+```ruby
config.store :direct do
use MyMiddleware, param1: 'xxx'
end
```
@@ -412,9 +461,27 @@
This is the global top layer where your Rails app looks up content similarly to
ActiveModel. The models are namespaced under the root class {WCC::Contentful::Model}.
Each model's implementation of `.find`, `.find_by`, and `.find_all` simply call
into the configured Store.
+
+Models can be initialized directly with the `.new` method, by passing in a hash:
+```ruby
+entry = { 'sys' => ..., 'fields' => ... }
+Page.new(entry)
+```
+
+**The initializer must receive a localized entry**. An entry found using a `locale=*` query
+must be transformed to a localized entry using the {WCC::Contentful::EntryLocaleTransformer} before
+passing it to your model:
+
+```ruby
+entry = client.entry('1234', locale: '*').raw
+localized_entry = WCC::Contentful::EntryLocaleTransformer.transform_to_locale(entry, 'en-US')
+Page.new(localized_entry)
+```
+
+The Store layer ensures that localized entries are returned using the {WCC::Contentful::Middleware::Store::LocaleMiddleware}.
The main benefit of the Model layer is lazy link resolution. When a model's
property is accessed, if that property is a link that has not been resolved
yet (for example using the `include: n` parameter on `.find_by`), the model
will automatically call `#find` on the store to resolve that linked entry.