https://rawgithub.com/The-Politico/src/master/images/logo/badge.png

generator-politico-interactives

Why this

At POLITICO we sometimes build custom webpages outside our CMS to showcase a special visual presentation or nonlinear story. We call these pages interactives, which is a metonym for pages that offer our readers a richer experience with our content.

This app helps us build those pages.

At its simplest, this app is a Yeoman generator, which means it simply sets up folders and files in a directory on a developer’s computer. But its real value is those files, which include a complete build and publishing system for our interactives and enforce our house styles and conventions through templates.

The rest of these docs describe how to work with the build system contained within this generator.

Principles

The build system creates projects that are...

Decentralized

Every project is an independent application. This keeps our builds lean. It gives us the flexibiltiy to use whatever front-end technology we need for the project at hand and to integrate easily with backends in a decoupled way.

Treating our projects as independent apps means we intentionally skip several conventions that are normally part of content management systems, like centralized revision control and release management.

Batteries included

An app’s development environment is built from the command line with a complete set of templates and scripts to build and publish the project, all of which can be overwritten within an individual project.

Flat

Every project is represented through flat files, making them very easy to reason about. File transformations like processing scripts, stylesheets and images are handled through background tasks that simply translate a flat file in the source directory to one in the built directory. The development server serves flat files from the built directory just as they will be served on S3.

What it does

  • Scaffolds your project’s development directory.
  • Compiles SCSS and bundles JS written in either ES5 or ES2015 using your choice of browserify or webpack.
  • Renders HTML templates with custom context.
  • Creates responsive image sets optimized for mobile devices.
  • Publishes your project to an Amazon S3 bucket.

What’s in it

The build pipeline uses:

Installing the generator

Dependencies

Make sure you have the latest version of node installed on your machine as well as the yarn package manager.

NPM

Install the package’s dependencies globally.

$ npm install -g gulp-cli yo generator-politico-interactives

Starting an interactive

From scratch

  1. Create a fresh directory for your project and move into it in your terminal.
$ mkdir my-project
$ cd my-project
  1. Now run the generator and answer the questions it asks to build your development environment.
$ yo politico-interactives
  1. Once the generator finishes, you can simply run gulp to start the development server.
$ gulp

From GitHub

  1. Clone the project and cd into the project directory.
  2. Run the passphrase subgenerator to create a new .env file:
$ yo politico-interactives:passphrase
  1. Install dependencies.
$ yarn
  1. If your project is using ArhcieML, run the archie subgenerator to reconfigure the integration.
$ yo politico-interactives:archie

Note

If you’re cloning a project to use as a template for a new project, delete the .git folder in your project root and then initialize a new git repo for the new project.

$ rm -rf .git
$ git init

Building an interactive

Working with templates

Templates are rendered using Nunjucks templating syntax. See Nunjucks’ template inheritance, tags and builtin filters for details on using the syntax to its full effect.

Template context

You can put data in templates/data.json and it will be rendered as context with your templates.

For example:

{ "headline": "My headline" }
<h1>{{headline}}</h1>

Markdown

There is a custom filter included for rendering template context formatted in Markdown:

<!-- Render context data with markdown -->
{{someText|markdown}}

<!-- Remove the outer paragraph tags with the strip option -->
<h1>{{sectionTitle|markdown(strip=true)}}</h1>

Responsive images

To make responsive images that load more quickly on smaller devices, drop a high-res jpg image into the src/images directory, the run the img task.

$ gulp img

This is will create four optimized images from your source at 400, 800, 1200 and 1600 pixels width.

srcset macro

You can easily include these images in your template with our custom jpg nunjucks macro.

<figure>
    {{ jpg('cat', alt='A cat!') }}
    <figcaption>A pretty cat</figcaption>
</figure>

Renders as:

<figure>
    <img src="images/cat-1800.jpg" srcset="images/cat-400.jpg 400w, images/cat-800.jpg 800w, images/cat-1200.jpg 1200w, images/cat-1800.jpg 1800w" alt="A cat!">
    <figcaption>A pretty cat</figcaption>
</figure>

ArchieML

Optionally, there is a gulp task available which allows you to use ArchieML and Google Docs to render content into your templates.

You will be asked if you want to use ArchieML when you start the generator. You can also add it to a project later by running:

$ yo politico-interactives:archie

You will need to provide the ID for the Google doc you wish to use, which you can get from the URL of your doc:

https://docs.google.com/document/d/yourGoogleIDhere/edit

Note

Your document must have access set at least to Anyone with the link can view to use this task.

The archie gulp task will access your Google doc and overwrite templates/data.json with ArchieML data. To run it:

$ gulp archie

Note

On first running the task, you will need to authorize access to the document through Google. The task will open the authorization dialogue in your browser. Follow the prompts and then copy and paste the code returned by Google.

This access token will be saved in archie-token.json so that you can run the task subsequently without needing to re-authorize.

Note

If you’ve added ArchieML after the project was already created, you’ll also need to add the task to your gulpfile. Simply edit it into the array of other tasks in gulpfile.js:

const gulp = require('./gulp')([
  'aws',
  'archie', // Add this line
  // ...
]);

Publishing

  1. Complete the meta information in meta.json
  2. Run the gulp’s publish task.
$ gulp publish

Note

If you need to invalidate files you’ve previously published in CloudFront’s cache, add the --invalidate flag:

$ gulp publish --invalidate

Your dist folder will be synced to the directory specified under publishPath in meta.json, which means files in AWS at that location that are not in your dist directory will be deleted.

The publish task will also version and gzip CSS and JS assets.

Developing

Subgenerators

The generator is split into several subgenerators which are called in sequence (and may be called by other generators). Read up on generator composability. These can be called individually:

$ yo politico-interactives:<subgenerator>

app

The main subgenerator called by defauly when you run the generator.

archie

Sets up an ArchieML integration for the project, if requested.

bundler-browserify

Sets up a browserify-based bundler system.

bundler-webpack

Sets up a webpack-based bundler system (depricated).

github

Generates a GitHub repository for the project, if requested.

gulp

Sets up major gulp tasks.

keys

Will write a set of keys encrypted with a passphrase to a path in the user’s directory, ~/.politico/interactives.json. Writes the following keys:

  • AWS access key
  • AWS secret key
  • Google client ID
  • Google client secret key
  • GitHub personal access token
  • Slack token
  • Ngrok token

linters

Sets up ESLint linter config.

meta

Writes meta file.

passphrase

Uses your passphrase to try to decrypt keys file.

styles

Writes scss directory.

templates

Writes HTML directories.