Use Refinery CMS as a headless API-first CMS
In this article, i will explain how to use Refinery CMS with its Rest API to manage the content of a Middleman static website hosted on the Netlify platform.
The final goal for me is to have one headless CMS app for multiple clients and one Middleman website hosted on Netlify for each customer.
In order to achieve this, we will:
- Bootstrap a new Refinery CMS 3.0.x app with a blog
- Install and configure the Rest API extension
- Create a new middleman app with a blog
- Install and configure the middleman-refinery extension
- Deploy the middleman website on Netlify
- Set the Webhook on your Refinery CMS app
BONUS: I have worked on a refinerycms-multisites extension in order to allow us to create one Refinery CMS app and host multiples customers on it.
1. Bootstrap a new Refinery CMS 3.0.x app with a blog
Follow the Heroku official Refinery CMS guide: Creating a new Refinery application on Heroku
Add the refinerycms-blog extension :
gem 'refinerycms-blog', git: 'https://github.com/refinery/refinerycms-blog', branch: 'master'
2. Install and configure the Rest API extension
Add the refinerycms-api extension at the bottom of your newly created Gemfile
gem 'refinerycms-api', git: 'https://github.com/refinerycms-contrib/refinerycms-api', branch: 'master'
Run bundle install, then
$ rails g refinery:api
$ rake db:migrate
Generate your first API Token with your admin user
$ rake refinery_api:user:api_token:generate EMAIL=refinery@example.org
Great! You can now start using the Rest API
$ curl --header "X-Refinery-Token: YOUR_API_TOKEN" http://localhost:3000/api/v1/pages
3. Create a new middleman app with a blog
Follow these guides:
Now you should have a working middleman website with a blog extension.
4. Install and configure the middleman-refinery extension
Add the middleman-refinery extension in the Gemfile of your Middleman app:
gem 'middleman-refinery' git: 'https://github.com/refinerycms-contrib/middleman-refinery', branch: 'master'
Run bundle install, then activate the extension with the blog content_type given by Refinery CMS:
activate :refinery do |f|
f.api_url = 'http://localhost:3000'
f.api_token = ENV['REFINERY_API_TOKEN']
f.content_types = [
{
content_type: 'Blog::Posts',
node: 'posts',
destination: 'source/blog/data',
format: '.html.md',
mapper: MiddlemanRefinery::BlogPostMapper
}
]
end
Now you can run this command to import Blog posts in your middleman folder and rebuild the app
$ bundle exec middleman refinery --rebuild
5. Deploy the middleman website on Netlify
- Create an account on Netlify
- Sync the repo of your app to perform automatic deploys on git push
- Change the build command by
$ middleman refinery --rebuild
- Set the API token ENV variable
- Generate a webhook URL
6. Set the Webhook on your Refinery CMS app
Create the publish event interactor.
You will need interactor
and httparty
gems in your Gemfile.
# app/interactors/refinery/publish_event.rb
require 'httparty'
module Refinery
class PublishEvent
include Interactor
def call
current_account = Refinery::Multisites::Account.find_by(subdomain: Apartment::Tenant.current)
if current_account.present? && current_account.webhook_url.present?
if response = HTTParty.post(current_account.webhook_url)
return true
else
context.fail!(message: "refinery.publish_event.failure")
end
else
context.fail!(message: "refinery.publish_event.failure")
end
end
end
end
Create the blog posts controller decorator
# app/decorators/controllers/refinery/blog/admin/posts_controller_decorator.rb
module RefineryBlogAdminPostsControllerPublishEventDecorator
def self.prepended(base)
base.prepend_after_action :publish_event, only: [:create, :update, :destroy]
end
def publish_event
result = Refinery::PublishEvent.call
if result.success?
flash.now[:notice] << t("refinery.publish_event.success")
else
flash.now[:notice] << t(result.message)
end
end
end
Refinery::Blog::Admin::PostsController.send :prepend, RefineryBlogAdminPostsControllerPublishEventDecorator
Conclusion
We have seen that in few steps and extensions we are able to use this classic CMS like a headless API-first CMS.
In a future post, i will explain how to use the Rest API of Refinery to receive form entries.
Possibilities are endless and it’s already works in production.