Historically, a problem with API-first or headless content management systems has been a lack of in-place preview. That's because the content management system doesn't have any reference to preview the content - displaying it is the job of the site or application which consumes the content.
We've found a way to make preview work as you and your users expect. They get to see the content of their site or application, on the site or application.
Here's how it works:
- The user hits 'preview' on a post or page in Rooftop
- Their browser sends a POST request to a predefined endpoint on your site or application
3. Your application retrieves the preview content from the Rooftop API and displays it in context
Here's a sequence diagram to show the steps in the process:
Preview Mode is an optional plugin, which you can turn on for your site under the
Before using preview, you need to configure Rooftop with the endpoint where you want to receive the POST .
Unpublished content might be sensitive, so it's important that only the person doing the previewing can see it. This is done by sharing a 'preview key' with the endpoint you configure. This preview key is also available when you hit the preview endpoint on the Rooftop API, so you can compare them.
Every post or page has a preview endpoint, for example:
This will always show the latest revision of a post, even if it's in draft. The JSON structure is identical to the normal endpoint to retrieve a post or page:
except that it includes a
preview key and value. This preview key is the one which was POSTed to your endpoint.
Make sure you add the include-drafts header to your request
The content being previewed might be in draft mode. You need to make sure you include a header with your API request called 'include-drafts', with a value of 'true'. See the reference page for draft mode.
Your site or application needs to do the following:
- Have a single endpoint to receive a POST request with the following parameters:
id: the ID of the post
post_type: the post type to preview (e.g.
preview_key: an MD5 hash of various parameters of the page. This changes each time the preview button is pressed.
- Retrieve the preview content and compare the preview keys - it's up to you to make sure this comparison happens
- Redirect to or render the post or page in the context of the site, showing the preview content.
We've written a reference implementation of the client-side aspect of preview mode into the rooftop-ruby and rooftop-rails gems.
The approach we take is as follows:
- the POST is received in the PreviewController - https://github.com/rooftopcms/rooftop-rails/blob/master/app/controllers/rooftop/rails/preview_controller.rb
Rooftop.include_draftsis set to true, the controller requests the draft content and compares the preview keys
- If they match, an SHA of the preview key, and the key itself, is stored in the browser session.
- The route to the content is resolved from the post type (e.g. 'page') and ID, and the user is redirected to the right place on the site with the SHA appended as a querystring
- The controller on the site responsible for e.g. PagesController has the
Rooftop::Rails::Previewmixin included, so can check for
preview?()and return the preview content if true.
preview?()does the job of checking the SHA on the querystring parameter matches the one in the session.
Why we SHA the preview key before redirecting to the real content
We could pass the preview key directly as a querystring parameter, and not have to mess about with the SHA. But in doing that, there's a chance that someone could share the URL to the preview page and it would work in another user's browser. Our implementation will only work in the browser which pressed 'preview'.
Updated less than a minute ago