WCC::Contentful

Installation

Add this line to your application's Gemfile:

gem 'wcc-contentful', require: 'wcc/contentful/rails'

And then execute:

$ bundle

Or install it yourself as:

$ gem install wcc-contentful

Configure

WCC::Contentful.configure do |config|
  config.access_token = <CONTENTFUL_ACCESS_TOKEN>
  config.space = <CONTENTFUL_SPACE_ID>
end

WCC::Contentful.init!

Usage

WCC::Contentful::Model API

The WCC::Contentful::Model API exposes Contentful data as a set of dynamically generated Ruby objects. These objects are based on the content types in your Contentful space. All these objects are generated by WCC::Contentful.init!

The following examples show how to use this API to find entries of the page content type:

# Find objects by id
WCC::Contentful::Model::Page.find('1E2ucWSdacxxf233sfa3')
# => #<WCC::Contentful::Model::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...>

# 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...>, ... ]

# 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...>

# 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'

Store API

The Store layer is used by the Model API to access Contentful data in a raw form. The Store layer returns entries as hashes parsed from JSON, conforming to the object structure returned from the Contentful CDN.

See the WCC::Contentful::Store documentation for more details.

The following examples show how to use the Store API to retrieve raw data from the store:

store = WCC::Contentful::Services.instance.store
# => #<WCC::Contentful::Store::CDNAdapter:0x00007fb92a221498

store.find('5FsqsbMECsM62e04U8sY4Y')
# => {"sys"=>
#  ...
# "fields"=>
# ...}

store.find_by(content_type: 'page', filter: { slug: '/some-slug' })
# => {"sys"=>
#  ...
# "fields"=>
# ...}

query = store.find_all(content_type: 'page').eq('group', 'some-group')
# => #<WCC::Contentful::Store::CDNAdapter::Query:0x00007fa3d40b84f0
query.first
# => {"sys"=>
#  ...
# "fields"=>
# ...}
query.result
# => #<Enumerator::Lazy: ...>
query.result.force
# => [{"sys"=> ...}, {"sys"=> ...}, ...]

Direct CDN API (SimpleClient)

The SimpleClient is the bottom layer, and is used to get raw data directly from the Contentful CDN. It handles response parsing and paging, but does not resolve links or transform the result into a Model class.

See the WCC::Contentful::SimpleClient documentation for more details.

The following examples show how to use the SimpleClient to retrieve data directly from the Contentful CDN:

client = WCC::Contentful::Services.instance.client
# => #<WCC::Contentful::SimpleClient::Cdn:0x00007fa3cde89310

response = client.entry('5FsqsbMECsM62e04U8sY4Y')
# => #<WCC::Contentful::SimpleClient::Response:0x00007fa3d103a4e0
response.body
# => "{\n  \"sys\": {\n ...
response.raw
# => {"sys"=>
#  ...
# "fields"=>
# ...}

client.asset('5FsqsbMECsM62e04U8sY4Y').raw
# => {"sys"=>
#  ...
# "fields"=>
# ...}

response = client.entries('fields.group' => 'some-group', 'limit' => 5)
# => #<WCC::Contentful::SimpleClient::Response:0x00007fa3d103a4e0
response.count
# => 99
response.first
# => {"sys"=>
#  ...
# "fields"=>
# ...}
response.items
=> #<Enumerator::Lazy: ...>
response.items.count  # Careful! This evaluates the lazy iterator and gets all pages
# => 99

response.includes
# => {"4xNnFJ77egkSMEogE2yISa"=>
#   {"sys"=> ...}
#  "6Fwukxxkxa6qQCC04WCaqg"=>
#   {"sys"=> ...}
#   ...}

The client handles Paging automatically within the lazy iterator returned by #items. This lazy iterator does not respect the limit param - that param is only passed through to the API to set the page size.

Entries included via the include parameter are made available on the #includes field. This is a hash of <entry ID> => <raw entry> and makes it easy to grab links. This hash is added to lazily as you enumerate the pages.

Accessing the APIs within application code

The Model API is best exposed by defining your own model classes in the app/models directory which inherit from the WCC::Contentful models.

# app/models/page.rb
class Page < WCC::Contentful::Model::Page

  # You can add additional methods here
end

# app/controllers/pages_controller.rb
class PagesController < ApplicationController
  def show
    @page = Page.find_by(slug: params[:slug])
    raise Exceptions::PageNotFoundError, params[:slug] unless @page
  end
end

The WCC::Contentful::Services singleton gives access to the other configured services. You can also include the WCC::Contentful::ServiceAccessors concern to define these services as attributes in a class.

class MyJob < ApplicationJob
  include WCC::Contentful::ServiceAccessors

  def perform
    Page.find(...)

    store.find(...)

    client.entries(...)
  end
end

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/watermarkchurch/wcc-contentful. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.

License

The gem is available as open source under the terms of the MIT License.

Code of Conduct

Everyone interacting in the WCC::Contentful project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.