It has been a long time in the making, but today we are happy to announce the release of a Ruby Gem for working with our Content Management API (CMA). The Management API is used for creating and editing your content on the Contentful platform, while the Delivery API is used to publish that content to a variety of devices.
This post will illustrate how to use the Ruby Gem in practice, by walking you through the process of building a simple blog system with posts, authors, assets and categories linked to the posts. Of course, the Contentful platform is capable of managing any content model you can dream up, blogs are just an easy to understand example.
The management library is still under heavy development and we are working hard to add more and more features, but we hope that this basic version will give you a taste of things to come as well as encourage you to experiment with integrating Contentful into your Ruby-run projects.
Please note that all code samples can be used in an Interactive Ruby Session (IRB)
Let's start with mapping out the type of items we need to publish a blog. A cursory glance will reveal that a standard blog post contains the following fields:
In order to keep things manageable, we will create separate content types for author and category entries. Categories are simple, each blog category has two fields:
and each author entry will have the following fields:
- profile picture
It is always a good idea to plan ahead when designing the model for your content types, since changing it after creating entries can be a lot of work. For a better understanding of how to structure your data, I recommend our earlier Webinar on advanced Content Modeling.
When using media assets in Contentful keep in mind a simple rule of thumb: a single asset does not require a separate content type, since it is handled through the built-in asset type. All assets have a title and description field by default.
However, if you would like to organize assets into a gallery or need to display additional meta information beyond title and description, then we recommended creating a wrapper content type (e.g. a "gallery" content type) for your media assets and linking an entry of that type to your blog post.
Now let's install the RubyGem. You can either install it system-wide
gem install contentful-management
or add it to your Gemfile
Depending on how you use it you might want to require the library.
The gem is compatible with all major Ruby versions including jRuby 1.9.
Creating Content Types
After you successfully installed the library you need to create a client object. For this you need to obtain a Management API token. A token can easily be obtained through the Documentation.
client = Contentful::Management::Client.new('access_token')
We are creating a new space to start from scratch:
space = Contentful::Management::Space.create(name: 'Blog')
If you happen to be in more than one organization you need to specify an organization ID. The ID can be found in your account settings in the url once you selected the organization.
Before we can create Posts we need to create the content types. A content type consists of an optional custom id, a name, a type and more fields that can be found in the documentation.
For the blog post itself we add the following fields:
1 2 3
post = space.content_types.create(name: 'Post') post.fields.create(id: 'post_title', name: 'Post Title', type: 'Text') post.fields.create(id: 'post_body', name: 'Post Body', type: 'Text')
'post_title' will cause the value of
'post_title' to be shown when listing entries on the contentful.com user interface.
We follow the same procedure to create a content type for category entry:
1 2 3 4
category = space.content_types.create(name: 'Category') category.fields.create(id: 'category_name', name: 'Category Name', type: 'Text') category.fields.create(id: 'category_description', name: 'Category Description', type: 'Text') category.update(displayField: 'category_name')
Last but not least, we add a content type for author entry:
1 2 3 4
author = space.content_types.create(name: 'Author') author.fields.create(id: 'author_name', name: 'Author Name', type: 'Text') author.fields.create(id: 'author_bio', name: 'Author Biography', type: 'Text') author.update(displayField: 'author_name')
Now we want to create a relation between blog posts and categories, authors and assets. To model one-to-many relationships we will be adding
Array fields to our content types, and the items in those arrays will be a special Link type.
First we need to create standalone
Link fields for categories and assets that will be linked to a post:
1 2 3 4 5 6 7
category_link = Contentful::Management::Field.new category_link.type = 'Link' category_link.link_type = 'Entry' asset_link = Contentful::Management::Field.new asset_link.type = 'Link' asset_link.link_type = 'Asset'
The type specifies that we are dealing with a link, the link_type describes what we are linking to. In this case we are linking to other entries and assets. Then we add
Array fields to post content type:
post.fields.create(id: 'post_categories', name: 'Post Categories', type: 'Array', items: category_link) post.fields.create(id: 'post_assets', name: 'Post Assets', type: 'Array', items: asset_link)
Finally, we add a field that links from the post to its author, because the author is not an array we can create the field directly through the content type.
post.fields.create(id: 'post_author', name: 'Post Author', type: 'Link', link_type: 'Entry')
At this point we have created the basic structure for our blog, but before we start creating entries we need to activate our content types:
1 2 3
post.activate category.activate author.activate
If you now take a look at the Contentful web interface you will see your newly prepared space, with the well-defined post, category and author content types.
Now lets get down to creating some categories:
1 2 3 4
categories =  categories << category.entries.create(category_name: 'Misc', category_description: 'Misc stuff') categories << category.entries.create(category_name: 'ContentManagement', category_description: 'Basics and principles about content.') categories.map(&:publish)
And lets add an author whose name will appear in the blog post:
post_author = author.entries.create(author_name: 'Janine McKay ', author_bio: 'Technical writer and twitter ninja.') post_author.publish
Now to create an actual post linked to the Misc and ContentManagement category:
1 2 3
post_entry = post.entries.create( post_title: 'First Post', post_body: 'Letterpress sustainable authentic, disrupt semiotics actually kitsch. Direct trade Cosby sweater Austin, Pitchfork flexitarian small batch authentic roof party 8-bit YOLO literally Neutra pour-over American Apparel dreamcatcher. High Life distillery cliche YOLO, flexitarian four loko put a bird on it plaid Marfa Shoreditch seitan Echo Park bicycle rights Pinterest PBR. Drinking vinegar Banksy gastropub, stumptown occupy farm-to-table Blue Bottle tattooed Truffaut single-origin coffee iPhone locavore pug. Blue Bottle cray quinoa farm-to-table Bushwick tousled. beard Kitschgit tousled, American Apparel XOXO vegan readymade Pitchfork church-key 3 wolf moon direct trade lo-fi. Food truck try-hard deep v salvia raw denim.')
Then link our categories array to our freshly created post:
To complete the post we want to upload an asset, create a link to it, and add an author:
1 2 3 4 5 6 7
image_file = Contentful::Management::File.new image_file.properties[:contentType] = 'image/jpeg' image_file.properties[:fileName] = 'example.jpg' image_file.properties[:upload] = 'https://farm9.staticflickr.com/8144/6974761828_493d4dc28d_k_d.jpg' asset = space.assets.create(title: "Unter den Linden", description: "A nice shot of the TV-Tower in Berlin", file: image_file) asset.publish
If we want to update an existing entry with additional links we have to include all of the existing links:
post_entry.update(post_categories: categories, post_assets: [asset], post_author: author)
The last step now is to publish the entry so we can fetch it through the Delivery API or view it in the web interface. Please note that entries in 'draft' state will not show up in the Delivery API.
You are invited to use the Delivery API Gem to fetch your first entries.
Once you have created your content types, publishing new entries and assets is fairly simple. For an example of setting up a more complex content model from scratch, we have built a script that imports the Open Beer Database, creating a structure with breweries, beers and beer styles and automatically linking them to each other.
You can find the script to try out and study on our Github account.
- Content Management API Documentation
- contentful-management.rb on Github
- Ruby Documentation
- Example Script using the Open Beer Database to create a space with multiple content types and entries.