Features:

Stealing the NPR App Template for Fun and (Non-)Profit

What we learned building an election app for INN members with the NPR visuals app template


This month, just in time for the election, our team at the Investigative News Network (INN) launched Power Players—a state-by-state exploration of campaign finance and top political donors across the country. The project is a collaboration between thirteen INN member organizations who did their own reporting and analysis of the data we provided to them. To support this reporting, our team built a national app with easy to embed components.

As this was one of the first editorial projects we built as a team, we decided to start things off on a solid foundation by creating an app template—something that contains a library of components we might want to reuse for future projects and allows us to create those projects more easily.

Fortunately for us, NPR’s Visuals team has generously open sourced their app template, which we used as the foundation for our own. We shamelessly stole NPR’s code and set up an INN-specific template by following the steps outlined in Tyler Fisher’s excellent post “How to Setup the NPR App Template for You and Your News Org.”

It was a (mostly) painless experience but we learned some things along the way and wanted to share our experience to help others who might tackle this process in the future.

Why Use NPR’s App Template?

For one, we didn’t want to build our own toolkit for deploying news apps from the ground up.

When someone (or some team) builds and open sources a tool that addresses a problem you’re facing, using it will almost certainly save you time, money, blood, sweat, tears and heartbreak. Do yourself a favor and try really hard to seek out and use stuff that other smart people have already built.

The other motivating factor was that we’ve never had the chance to use NPR’s app template and a number of us have been curious. Being that this was INN’s first news app and we had a short amount of time to get something up and running, we thought this might make the perfect opportunity to take it for a test drive.

Setting Up the Template for INN

Tyler acknowledges in his post that the process “seems like a lot.” But we discovered it’s just a matter of knowing where to find all the NPR bits so you can make the template your own.

In fact, it took just seven commits to completely scrub NPR specific stuff from the app template.

For your reference, here is our fork of the NPR app template and the code for the Power Players app itself.

Building with the Template

Our project concept was relatively simple. There are a total of five views and their corresponding templates.

They consist of:

One of the goals for us was to create a resource that any of our member organizations could use to bolster their coverage of the elections—either by hosting information for an entire state, or including individual power player cards in articles covering campaign finance and the election.

a power player card

An embeddable power player card

Thus the embeddable versions of the state and power player pages. These are essentially the same as the normal templates, with a simple full-width layout and simplified INN branding (a credit link at the bottom of each embed).

The Kentucky Center for Investigative Reporting is one INN member making great use of the app.

The entire project is responsive (thanks to pym.js, yet another NPR project), made to look great no matter what size container the embeddable elements get placed in.

Snags and Snafus

In working with the NPR app template, we encountered some things that aren’t well documented (yet).

CSS and JS Pseudo-Tags

Tyler covers this briefly in another blog post on the app template.

What wasn’t clear at first was how the JS and CSS pseudo-tags interact across templates.

I ran into a problem where, in separate templates, I “pushed” or queued different sets of javascript files to be rendered. In both templates, I was passing the same file name to the render function, which resulted in the second file overwriting the first when deploying.

Here’s what NOT to do:

 {# Template file no. 1 #}
 {{ JS.push('js/lib/jquery.js') }}
 {{ JS.push('js/lib/underscore.js') }}
 {{ JS.push('js/lib/bootstrap.js') }}
 {{ JS.push('js/lib/template_1.js') }}
 {{ JS.render(**'js/app-footer.min.js**') }}
 {# Template file no. 2 #}
 {{ JS.push('js/lib/jquery.js') }}
 {{ JS.push('js/lib/bootstrap.js') }}
 {{ JS.push('js/lib/template_2.js') }}
 {{ JS.render('**js/app-footer.min.js'**) }}

Once you realize that JS.render outputs a file, the contents of which are determined by preceding calls to JS.push, you realize that having different calls to JS.push before rendering to the same file just won’t work.

In this case, if template 2 is rendered after template 1, “js/app-footer.min.js” will be missing “underscore.js,” potentially breaking functionality in template 1.

Do this instead:

 {# Template file no. 1 #}
 {{ JS.push('js/lib/jquery.js') }}
 {{ JS.push('js/lib/underscore.js') }}
 {{ JS.push('js/lib/bootstrap.js') }}
 {{ JS.push('js/lib/template_1.js') }}
 {{ JS.render(**'js/app-footer-1.min.js'**) }}
 {# Template file no. 2 #}
 {{ JS.push('js/lib/jquery.js') }}
 {{ JS.push('js/lib/bootstrap.js') }}
 {{ JS.push('js/lib/template_2.js') }}
 {{ JS.render(**'js/app-footer-2.min.js**') }}

By making the filename passed to JS.render unique to each template, we can be sure we’re not clobbering any JavaScript files.

Flask’s url_for Function and Your Project’s Path Prefix

Another issue we encountered was that the app template, using Flask’s default url_for function, doesn’t take into consideration your project’s path. That is, when you deploy your app to S3, it is meant to live at something like http://apps.yourdomainname.org/project-slug/ whereas the development server uses something like http://localhost:8000/ without the project slug.

For example:

<a href="{{ url_for(‘some_view’) }}”>Hey, a link to a page</a>

Renders as:

<a href="/some-view/”>Hey, a link to a page</a>

What we want is an URL that includes the project slug:

<a href="/project-slug/some-view/”>Hey, a link to a page</a>

To remedy this, we created an app_template_url_for function to replace Flask’s standard url_for. The app_template_url_for figures out the current target environment (i.e. development, staging or production) and inserts the project slug as necessary.

View the source code here and here.

Another change we made to INN’s version of the app template is modifying the Flask app’s static_folder:

app = Flask(__name__, static_folder='www/assets')

View this change in context here.

What this does is allow you to use url_for to build urls for static assets kept in www/assets.

<link rel="shortcut icon" href="{{ url_for(‘static’, filename='icons/favicon.ico') }}" />

This provides the flexibility to include assets outside of the CSS and JS pseudo-tag framework if you find yourself with the need or desire to do so.

In Conclusion

We learned a lot in the process of building our first app, both about the NPR app template and also what it takes to manage a complex project working with so many partner organizations.

Will we use our fork of the NPR app template for everything? Probably not. We’ll continue to experiment and try out different things before settling on our default set of tools and templates. For projects where it’s a good fit or where we need to deploy something quick and easy, we definitely plan to use it as a solid starting point in building future apps.

Since this is our first app and we’re still learning, we’d love to hear your thoughts and feedback. You can find our team on Twitter @INNnerds or send us email at nerds@investigativenewsnetwork.org.

People

Organizations

Credits

  • Kaeti Hinck

    Kaeti Hinck is an editor at The Washington Post, where she leads an award-winning visual journalism team and explores the intersection of technology, design, and narrative. Before joining the Post in 2016, she worked as design director of the Institute of Nonprofit News. At INN, she helped design and build open source products to support independent publishers. For more than a decade she has been exploring the power of visual communication and technology in newsrooms. Outside of work, you’ll likely find her reading under a blanket, searching for the perfect breakfast sandwich, and spending as much time in the woods as possible.

  • Denise Malan

    Training director at @IRE_NICAR. Runner, author of @runbucketlist, Razorback, fan of baseball everywhere, but mostly KC.

  • Ryan Nagle

    I’m listening. Member of @AdHocTeam. Previously @BreakingNews, @INN, @tribapps.

  • Adam Schweigert

    Patriot. Dog person. Banjo player. Also, Director of User Experience, @MotherJones. Organizer, @wcpublishers. RTs = my team will get back to you.

Recently

Current page