Creating a Pageflow plugin

One of our products is Scrollytelling, which is built on top of the open source Pageflow publication tool. Pageflow knows the concept of Plugins, with which you can change or enhance the built-in functionality.

Yesterday we released a Plugin to swap the default navigation for the Scrollytelling-style navigation. Here’s how we did it. There are direct links to each individual commit on we made in the GitHub repo.

A Ruby gem

Pageflow Plugins are Ruby gems so that’s what we’ll create:

$ bundle gem scrollytelling-pageflow-navigation

This will generate an awesome gem skeleton, complete with a README, contributor convenant, Rake tasks for publishing the gem and MIT license.

Relevant commit on GitHub:

With that out of the way it’s time to replace the generated TODOs with actual information, and remove anything we don’t use.

Relevant commit on GitHub:

Big stuff

Now for the actual code.

Since we had this functionality working already, I just copied everything over at once from the existing application. This is called an extraction and it’s actually a great way to develop software.

This is the relevant commit:

But I’ll walk you through each step with inline examples.

The entry point for every Ruby gem is it’s gemspec. I started by adding two dependencies, namely Pageflow itself and Rails.

spec.add_runtime_dependency ‘pageflow’, ‘>= 0.7’
spec.add_runtime_dependency ‘rails’, ‘>= 3.0’

Next up, still automatically loaded by Ruby, is the gem’s main file in the lib folder. This one is also automatically generated in the previous step. In our case it’s lib/scrollytelling/pageflow/navigation.rb.

Our Plugin has a main plugin file, a WidgetType and a Rails Engine. We have to require all these files:

require “scrollytelling/pageflow/navigation/plugin”
require “scrollytelling/pageflow/navigation/widget_type”
require “scrollytelling/pageflow/navigation/engine”

While we’re in here we can add a class method to load the WidgetType. This is just following the Pageflow guidelines.

module Scrollytelling
module Pageflow
module Navigation
def self.widget_type

The Plugin’s components

So this Pageflow Plugin has three main components: a plugin class, a Pageflow WidgetType and a Rails Engine. These will differ for every type of plugin. Since ours is a WidgetType this is all we need.

Pageflow Plugin

Following the documentation we see that we can use the Plugin to hook into the Pageflow initialization process. This makes life easier for folks using our gem, since they have just one entry point.

We hook into the initializer like so:

require 'pageflow/plugin'
module Scrollytelling
module Pageflow
module Navigation
class Plugin < ::Pageflow::Plugin
def configure(config)
default: true

Now on to what actually renders HTML; the WidgetType.

Pageflow WidgetType

If you read the documentation you see that Pageflow exposes some built-in roles for WidgetTypes. One of these is navigation which is the one we wish to override.

If you want to add functionality to Pageflow you don’t use any of the built-in roles but invent your own.

Here’s the code:

require ‘pageflow/widget_type’
module Scrollytelling
module Pageflow
module Navigation
class WidgetType < ::Pageflow::WidgetType
def name
        def roles
        def render(template, entry)
entry: entry

As you can see it will render a view partial. The code is here:

In order to actually use Rails view partials we have to start a Rails Engine which is the last piece of the puzzle.

Rails Engine

These are beautiful little machines that give any Rails app superpowers. We use them a lot, for all kinds of tasks. This one here will give the plugin the ability to use Rails views and the asset pipeline.

The code is tiny:

require 'rails/engine'
module Scrollytelling
module Pageflow
module Navigation
class Engine < ::Rails::Engine
isolate_namespace Scrollytelling::Pageflow::Navigation

With that out of the way all the Ruby code is in place. We still need to style the HTML and add JavaScript. Since we have a Rails engine we can put them into its asset pipeline and add this to the README.

The code isn’t that interesting so I will just link to the JavaScript:

and CSS:

Wrapping up

Everything is in place now.

Obviously while developing you would have to have an actual Rails application laying around that has Pageflow configured. During development you would bundle this gem by referencing its path in the Gemfile. After the gem is done you’ll push it to which will come next.

First we write usage instructions for devs who want to use it:

# config/initializers/pageflow.rb
# app/assets/javascripts/pageflow/application.js
//= require scrollytelling/pageflow/navigation
# app/assets/stylesheets/pageflow/application.css.scss
@import “scrollytelling/pageflow/navigation”;

Then commit the whole thing and we’re about ready to go!

Releasing the gem

Since we generated the gem skeleton all the tasks to actually publish the gem are built in. Type this in the terminal:

$ rake release

Yep, it actually is that simple. Oh, it does imply you have an account at and you’re logged in.


We push this live and are hit with an error.

It turns out our JavaScript won’t minify in the production asset pipeline since it had a syntax error.

It’s easily fixed by a new commit.

Now it works and we can use it in production.

Adding final touches

Seeing it in our Pageflow editor we notice that, when we use this navigation type in a story, there is a label that needs a localization string.

From experience we know that these localization strings need a server-side forced refresh as well. We add everything and call the plugin done, version 1.0.0 and SHIP IT!

If you want to use our plugin for your Pageflow application, follow the instructions in the README. And don’t hesitate to open an issue or pull request if something doesn’t work for you.