🏠 Spike plugin for integrating RooftopCMS with a static site
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
lib
test
.editorconfig
.env
.gitignore
.npmignore
.travis.yml
LICENSE.md
README.md
contributing.md
package.json
yarn.lock

README.md

Spike Rooftop Plugin

npm tests dependencies coverage

Rooftop CMS plugin for spike

Note: This project is in early development, and versioning is a little different. Read this for more details.

Why should you care?

If you are using the lovely Rooftop CMS and want to pull your API values in and compile them into a spike static site, this plugin will do some good work for you 😁

Installation

npm install spike-rooftop -S

Usage

This is a standard webpack plugin, but is built for and intended to be used with spike. You can include it in your spike project like this:

// app.js
const Rooftop = require('spike-rooftop')
const htmlStandards = require('reshape-standard')
const locals = {}

module.exports = {
  plugins: [
    new Rooftop({ addDataTo: locals, url: 'xxx', apiToken: 'xxx' })
  ],
  reshape: htmlStandards({ locals: () => locals })
}

Since Spike uses reshape, you can use a variety of different plugins to expose local variables to your html. We are using spike html standards here because it's the plugin provided in spike's default template, and also is currently the only plugin that provides the ability to run complex loops through objects.

In order to pass the data correctly, you must pass spike-rooftop an object, which it will load the data onto when the compile begins under a rooftop key. If you also pass the same object to whatever posthtml plugin you are using in whatever manner it requires to make the data available in your html templates, the data will be present on that object before they start compiling. This is a slightly unconventional pattern for javascript libraries, but in this situation is allows for maximum flexibility and convenience.

Once included, it will expose a rooftop local to your jade files, which you can use to iterate through your posts. By default, it will only pull the post content type, which can be accessed through rooftop.posts, as such:

//- a template file
ul
  for post in rooftop.posts
    li= JSON.stringify(post)

If you want to access other content types, you can easily have us grab them by customizing the contentTypes option, as such:

const locals = {}

new Rooftop({
  addDataTo: locals,
  url: 'xxx',
  apiToken: 'xxx',
  contentTypes: ['posts', 'case_studies']
})

This would pull any case_studies and add it to rooftop.case_studies in your jade files.

Now let's say you want to get a little more granular in which posts you are pulling, what order they are in, etc. Rather than passing a string through the contentTypes array, you can pass an object instead with some extra options under a params key. For example:

const locals = {}

new Rooftop({
  addDataTo: locals,
  url: 'xxx',
  apiToken: 'xxx',
  contentTypes: [{
    name: 'posts',
    params: {
      order: 'asc',
      search: 'hello'
    }
  }]
})

This would pull back any posts whose content matches "hello" somewhere, in ascending rather than descending order. For a full list of possible parameters you can pass in here, check the 'list posts' arguments list here.

Now it is true that rooftop doesn't return the cleanest and nicest-formatted json. So you can also pass a transform option to each content type, where you can transform the data however you'd like before it goes into your views.

const locals = {}

new Rooftop({
  addDataTo: locals,
  url: 'xxx',
  apiToken: 'xxx',
  contentTypes: [{
    name: 'posts',
    transform: (post) => {
      // do your transformation here...
      return post
    }
  }]
})

We run a default transform function that cleans up response objects for you, out of the box. However, if you'd like to disable this and get back the raw response directly from rooftop, if you pass false as the value of transform, it will come back untouched.

const locals = {}

new Rooftop({
  addDataTo: locals,
  url: 'xxx',
  apiToken: 'xxx',
  contentTypes: [{
    name: 'posts',
    transform: false // disable our standard transform function
  }]
})

Using the template option allows you to write objects returned from Rooftop to single page templates. For example, if you are trying to render a blog as static, you might want each post returned from the API to be rendered as a single page by itself.

The template option is an object with path and output keys. path is an absolute or relative path to a template to be used to render each item, and output is a function with the currently iterated item as a parameter, which should return a string representing a path relative to the project root where the single view should be rendered. For example:

const locals = {}

new Rooftop({
  addDataTo: locals,
  url: 'xxx',
  apiToken: 'xxx',
  contentTypes: [{
    name: 'posts',
    template: {
      path: 'templates/post.html',
      output: (post) => { return `posts/${post.slug}.html` }
    }
  }]
})

Your template must use the item variable as seen below. Note you also will need to prevent Spike from attempting to render your template file normally by adding your templates to Spike's ignore option, or adding an underscore to the file name.

<p>{item.title}</p>

Finally, if you'd like to have the output written locally to a JSON file so that it is effectively cached locally, you can pass the name of the file, resolved relative to your project's output, as a json option to the plugin. For example:

const locals = {}

new Rooftop({
  addDataTo: locals,
  url: 'xxx',
  apiToken: 'xxx',
  contentTypes: ['posts'],
  json: 'data.json'
})

If you'd like to use our default transform outside of the library, this is also available as an export. For example, you could include it and use it with client-side js responses.

const Rooftop = require('spike-rooftop')
console.log(Rooftop.transform)

Hooks

If you've read this far down, you're ready to unlock some true power over your rooftop content.

postTransform

This function allows you to modify all posts & your locals AFTER you've modified your content in your contentTypes - transform, and BEFORE you the templates are compiled. You must return an array with the first index containing the posts object and the second index containing the locals object.

NOTE: We have written tests to verify if nothing is passed in here, the data will not be modified in anyway. If you've added a postTransform hook and you have an error, start debugging here 😄

const locals = {}

new Rooftop({
  addDataTo: locals,
  url: 'xxx',
  apiToken: 'xxx',
  hooks: {
    postTransform: (posts, locals) => {
      // posts = { posts: {} }
      // locals = {}
      return [posts, locals]
    }
  },
  contentTypes: ['posts'],
  json: 'data.json'
})

Testing

This project uses the rooftop-seeds project, which is a hosted rooftop instance with a public read-only key used specifically for testing OSS products that rely on rooftop. Please do not abuse this free service.

If any changes are needed to the test data in order to properly test a new feature, please file an issue and we will make the changes as required!

License & Contributing