Pym.js Embeds version Now with AMP ⚡️ support!

It's hard to do truly custom interactives work within WordPress. INN Labs' Pym.js Embeds plugin is built to make it easier for your newsroom to embed your latest data project, with help from NPR's Pym.js library.

Other solutions often involve pasting JavaScript into the post editor, disabling or bypassing parts of WordPress' security filters, or using interactive-builder plugins that limit your creative freedom.

All that Pym.js Embeds requires is a place to host your interactive as a standalone HTML page, and that you use NPR's Pym.js library in your interactive to make it resizable. Our plugin provides the seamless WordPress integration. Take the URL of your interactive and embed it in posts using the Block Editor or shortcodes. We handle the rest!

For the first time, thanks to the efforts of Claudiu Lodromanean and Weston Ruter, the Pym.js Embeds plugin supports the official WordPress AMP ⚡️ plugin. With both plugins installed, your Pym.js-based iframes will now be displayed as <amp-iframe> tags when your site is viewed through AMP.

Since amp-iframe now includes Pym.js's messages as a supported protocol, your embedded content is now more likely to work in AMP sites than it was before. As Google drives more content to your AMP pages, your readers will continue to have the same first-class experience they'd have if the reader viewed your full site.

This release also fixes some minor documentation issues, and we've improved this plugin's contribution guidelines on GitHub for external contributors.

Connect with the INN Labs Team

If you're using this plugin, let us know how you're using it! Send us links to cool things you've done with it; we'd love to include them in our weekly newsletter.

If you'd like to learn more about INN Labs' open-source WordPress plugins and tools for publishers or how we can work together on your next project, send us an email or join us at one of our weekly Office Hours.

NewsMatch Pop Up Best Practices

There have been some changes since our last blog post around Pop Up best practices for NewsMatch and other special campaigns, so we're releasing an updated guide.

Here are some general recommendations and best practices for using popups as part of NewsMatch, year-round campaigns, or special campaigns on your site. 

Installing the plugin

We recommend using Popup Maker plugin for setting up donation and newsletter signup popups on your site. 

Instructions for installing the plugin and creating a popup.

Recommended Pop Up Settings

Your popup should:

  • Be size “Large” or smaller from Popup Maker’s settings
  • Appear at the center of the bottom of the reader’s screen
  • Appear by sliding up from the bottom of the screen, over 350 milliseconds
  • Have an obvious “Close” button
  • Allow readers to interact with the rest of the page (do not use a full-page overlay)
  • Automatically open after 25 seconds (or more) on the page, because immediate popup appearances can be jarring. It can also be set to open after scrolling down a percentage of the page.
  • Be configured to not appear again for 2 weeks or more once dismissed by a reader
  • Be configured to not show on your donation page

You'll need to configure which pages the popup appears on, using the built-in conditionals feature. For disabling the popup on certain pages or in certain cases, read on in this blog post, or check out Popup Maker's paid extensions.

You'll also probably want to review the Popup Maker themes available and modify them to suit your own site's appearances. Once you've modified or created a theme, edit your popup to make it use your theme.

In addition to using Popup Maker themes, you can style popups using your site's WordPress theme's CSS, Jetpack’s Custom CSS Editor, or any other tool that allows you to define custom styles on your site.

What goes in a popup?

NewsMatch will provide calls to action, images, and gifs to be used leading up to and during the campaign. 

Here are some examples:

Non-NewsMatch popups should have an engaging, short call to action along with an eye-catching button.

Need help?

There is a ton of additional information on the WP Popup Maker support pages:

If you have questions, sign up for one of INN Labs’ NewsMatch technical support sessions or email the INN Labs team at

New Plugin Launch: Republication Tracker Tool

INN Labs is happy to announce our newest plugin, the Republication Tracker Tool.

The Republication Tracker Tool allows publishers to share their stories by other websites and then track engagement of those shared stories with Google Analytics. The technology behind this tracking is similar to ProPublica’s PixelPing.

Why Might You Want to Use This Plugin?

  • Grow your audience and pageviews: Other publishers and readers acquire and re-distribute your content with a Creative-Commons license.
  • Better republishing reporting: View what publishers that are republishing your content and analyze engagement.
  • Foster collaborations: Gather supporting data to build relationships with other publishers who may be republishing your content.

How Publishers Republish Your Content

A simple “Republish This Story” button is added to your posts through a WordPress widget. This enables your stories to be republished by other sites who may want to use it and then to track engagement of those republished stories via Google Analytics

Sample republication button (style can be customized).

Track Republished Posts in WordPress

Once one of your stories has been republished, you will easily be able to see how many times it has been republished, how many republished views it has, who has republished it, and the URL of where it was republished, all from the WordPress edit screen for that story.

Example of republication data in the edit screen of a WordPress post.

Track Republished Posts in Google Analytics

Another valuable feature of the Republication Tracker Tool is all of your republished post data is also tracked in your Google Analytics account. Once you have your Google Analytics ID configured in the Republication Tracker Tool settings, you will be able to log into Google Analytics and view who has republished your stories, who is republishing most of your stories, and more.

Example of republication data within Google Analytics.

More Information and Feedback

For more information about how the plugin works:

You can download the Republication Tracker Tool from the plugin repository or through your website’s WordPress plugin page.

The initial release of this plugin was made possible by valuable INN member testing and feedback. If your organization uses the plugin, please let us know and continue sending us suggestions for improvement. Thank you!

The Republication Tracker Tool is one of the many WordPress plugins maintained by INN Labs, the tech and product team at the Institute for Nonprofit News.

Announcing Version 1.0 of the Link Roundups Plugin

INN Labs is pleased to announce an important update to the Link Roundups plugin!

If you run a daily or weekly newsletter collecting headlines from around the state, region, or within a particular industry, the Link Roundups plugin will make it easier to build and feed your aggregation posts into MailChimp.

The Link Roundups plugin helps editors aggregate links from around the web and save them in WordPress as “Saved Links”. You can publish these curated links in a Link Roundup (more below), display Saved Links and Link Roundups in widgets and posts in your WordPress site, or push Link Roundups directly to subscribers via MailChimp. It's designed to replace scattered link-gathering workflows that may span email, Slack, Google Docs and spreadsheets and streamlines collaborations between different staffers.

Why might you want to use this plugin? Here are a few reasons:

  • It creates a single destination for collecting links and metadata
  • On sites that publish infrequently, it provides recently published (curated) content for your readers
  • Weekly roundup newsletters or posts are a great way to recap your own site's coverage and build and diversify your audience, which can increase donations

Saved Links

The central function of the Link Roundups plugin is the Saved Link. It's a way of storing links in your WordPress database, alongside metadata such as the link's title, source site, and your description of the link's contents.

A screenshot of the Saved Links interface, showing many saved links and their respective metadata: authors, links, descriptions, and tags.

Save to Site Bookmarklet

When WordPress 4.9 removed the "Press This" functionality, this plugin's bookmarklet broke. This release's updates to the Saved Links functionality include a renewal of the "Save to Site" bookmarklet, based off of the canonical Press This plugin's functions. If your site has the WordPress-maintained Press This plugin active, your site users will be able to generate new bookmarklets. We include instructions on how to use the bookmarklet in the latest release.

A screenshot of the "Save to Site" button and its copy button

Once you've accumulated a few Saved Links, you can display them on your site using the Saved Links Widget or start to create Link Roundups (see next).

Saved Links Widget

Common uses of this widget include "coverage from around the state" or "recommended reads" or "from our partners" links.

It's a good way to point your to expert coverage from newsrooms you partner with. With the ability to sort Saved Links by tag, you can easily filter a widget to only show a selection of all the links saved on your site. Here's how Energy News Network uses the widget:

A screenshot of the widget as it appears at Energy News Network, showing a selection of links from the last day.
A screenshot of the widget as it appears at Energy News Network, showing a selection of links from the last day.

Link Roundups

Link Roundups are one of the best ways to present Saved Links to your readers. Collect links with Saved Links, then create a Link Roundup post with the week's curated links. The person who assembles the Link Roundup doesn't have to deal with messy cut-and-paste formatting or composing blurbs — when your users create Saved Links, they're already adding headlines, blurbs, and sources.

Add some opening and closing text, and you're most of the way to having composed a morning or weekly news roundup.

Link Roundups are a custom post type with all the Classic Editor tools and an easy interface for creating lists of Saved Links. As a separate post type, they can be integrated into your site's standard lists of posts or kept separate in their own taxonomies. You don't have to integrate the roundups with your standard posts flow; it's why we provide a Link Roundups widget to fulfill your widget area needs.

MailChimp Integration

Link Roundups don't have to stay on your site. If you configure your site to connect to the MailChimp API and create a newsletter template with editable content areas, you can send a Link Roundup directly to MailChimp from WordPress.

From the Link Roundup editor, you can choose a mailing list, and create MailChimp campaign drafts, send test emails, and send drafted campaigns directly. If you'd rather open a draft campaign in MailChimp to finalize the copy, there's a handy link to your draft campaign.

A screenshot of a settings metabox: choose a campaign type of regular or text. Choose a list to send to: the Link Roundups Mailchimp Tools Test list, with the group "are they Ben" option chosen: "Ben". The campaign title will be "Test Title Three Title", the test subject will be "Test Title Three Subject", and the template will be "Link Roundups Test 2"
Here's the MailChimp settings for the Link Roundups campaign editor: Many of the controls that you'd want to use to create and send a draft campaign.

More information

For more information about how the plugin works, see the Largo guide for administrators, the plugin's documentation on GitHub, or drop by one of our weekly open office hours sessions with your questions. You can also reach us by email at

If you already have the Link Roundups plugin installed, keep an eye out for an update notice in your WordPress dashboard. If you'd like to install it, download it from the plugin repository or through your site dashboard's plugin page.

This update was funded in part by Energy News Network and Fresh Energy, with additional funding thanks to the generous support of the Democracy Fund, Ethics and Excellence in Journalism Fund, Open Society Foundation, and the John S. and James L. Knight Foundation.

Link Roundups is one of the many WordPress plugins maintained by INN Labs, the tech and product team at the Institute for Nonprofit News.

Guest Post: Publishing elections results on the cheap

Caitlin Ostroff is the Miami Herald's data reporter and a graduate of the University of Florida. Mike Stucka is the data dork at the Palm Beach Post and is a graduate of Northeastern University, Loyola University Chicago, and a great IRE bootcamp a decade ago. Today, they contribute a guest post to INN Labs about the elections software they built.

Want to get live election results on a shoestring budget? We did. The result is a multi-component package of election reporting tools that ease the way for newsrooms to build their own scrapers, output them in a semi-standardized format and optionally use a frontend for display.

Python code parses through several pipe-delimited text files published by Florida’s Secretary of State to get statewide results, and also scrapes local results for several counties. The key was to adopt pseudo-standards from software created by The New York Times and National Public Radio, who worked together to process election results from The Associated Press.

By building scrapers against the CSV format of the Elex package, it became easy to combine multiple levels of results that could be handled and processed by a single system. You can combine your own scrapers and AP's data — or just your own scrapers, or just AP's data — to get results for your pages. The Miami-Dade County scraper was easily adapted for Kentucky, and Palm Beach County's scraper easily became West Virginia's.

The Palm Beach Post built a front end by baking out the pages using Flask. Three scrapers ran on Election Night and were beaten into more than 500 different widget embeds for 11 newspapers, with each complete scrape-parse-build run taking about 40 seconds total.

The Miami Herald used JavaScript to parse out the results from a JSON file and render them to the Herald’s static media server, using fixed-size iframes of different breakwidths to bring them into its proprietary content management system. The Herald enabled cross-origin sharing, which allowed it to control caching in an .htaccess file.

Part of the Miami Herald's election results page, showing the ballot initiative results for Florida Amendment 13, which would end dog racing.
Part of the Miami Herald's election results page, showing the ballot initiative results for Florida Amendment 13, which would end dog racing.

There's a lot of flexibility: one of us un-called a race from a cell phone while waiting to pick up a kid from school, because the open-sourced publishing tool uses a Google Sheet to allow edits of race names, candidate names, parties, winners and runoffs.

In addition to rendering live election results, this setup also allowed both papers’ newsrooms easy access to data, from the margins between candidates to live vote count changes from newly-tallied votes. The data structures and workflow helped on election night and through a recount process that stretched more than a week. The Miami Herald and The Palm Beach Post used the code to render the current tallies as Florida inched closer to a recount after the election, as well as to drive analysis for reporting.

A screenshot of a line chart, showing that DeSanis, Scott, and Caldwell had high initial leads in the vote count, but their leads declined as more votes came in. Caldwell's lead disappeared entirely, ending up several thousand votes behind the competition.
Chris Persaud and Mike Stucka built a Datawrapper chart of Republican candidates' lead in vote counts, using data from their election handling tool.

Existing widgets ran with stories, and new widgets were fed in near-real-time from the data we'd pulled. The code for whole-election results gave both publications a framework for pulling precinct-level results.

How cheaply done was this? We think we might have gotten about five weeks total to work on this. A much more ambitious project is Politico's open-sourced Civic, on which a development team of five focused for about five weeks each to add improvements. Our effort is far more limited, but likely also a lighter lift to get started with. Weigh your options and see what fits your organization.

Would you like to use our code? The front-end is available now and you can check out the scrapers here and here, and all are released under the MIT License. You can use this code as-is or contribute improvements. We have a sample widget collection here, and implementations at the Herald and the Post. Want to improve the project? We'd welcome that; send a pull request, drop us an email, find us in News Nerdery, call us by phone.

Announcing: Pym.js Embeds version

The INN Labs team is issuing a major, Gutenberg-friendly update to the Pym.js Embeds WordPress plugin, formerly known as the Pym Shortcode plugin, which improves presentations of data journalism.

The Pym.js Embeds plugin creates a better experience for the reader with responsive embeds that scale to fit the story, reduces workflows for data journalists, and removes the need for tricky embed workarounds.

For more details, see our latest announcement. You can also learn more about the latest release on GitHub and download the plugin from

Some New Tools for News Orgs from NICAR 2018

Chicago skyline from Lincoln Park

The INN Labs team spent a few days in Chicago for the NICAR conference earlier this month. We came back with plenty of inspiration and a long list of tools for journalism on the web. (Many more links can be found in Chrys Wu's annual NICAR roundup.)


  • Coolors: a fun generator to help build color schemes
  • ColorBrewer: find accessible color schemes for maps and other data visualizations.
  • Colorsafe: another color and accessibility tool, this time focused on proper contrast.





  • notes for voice conversations.
  • Temi: fast speech to text transcription.
  • Cassette: more transcription and search.



  • Amper: an AI composer for soundtrack music.
  • Take: an iOS app for recording and collaborating on musical ideas.
  • Figure: make beats and music on iOS.


Social Video and Images

  • This by Tinrocket: annotate images for social media use.
  • Legend: create text-based animations on iOS.
  • Spark Post: fast graphics for social media from Adobe.
  • Quik: create quick and simple videos on mobile devices.



  • publicly available style guides for code, design and content with plenty of ideas to crib from.
  • Dropmark: visual organization for links and files, like Pinterest meets Google Drive meets Delicious.
  • Mural: digital, virtual whiteboarding tool.

How We Made a Shared Inventory for Public Broadcast Stations

We recently had an organization come to us with a unique challenge: a group of public broadcast stations needed a way to see what other stations were working on. They wanted an easy way to spark collaboration, avoid any programming duplication, and see opportunities for cross-promotion.

We had to figure out the best way to go about creating a private, easily-accessible, and friction-less shared inventory (what we were also calling a pipeline) of programs for TV and radio stations scattered across the state.

Here’s how we did it:

First, we started by identifying the basic needs of the programmers and those who would be maintaining the inventory/pipeline. Remember, we wanted to keep it as friction-less as easy to use as possible! Then, we focused on finding existing tools which would offer the necessary features for the workflow while being easy to adopt and use. Below you’ll find an overview of the workflow we built. We hope that sharing this with you will spark ideas for ways to improve your own workflows - whether it be a shared pipeline or another use case.

As always, feel free to reach out to us if you have a unique challenge that we can help you solve!

Our workflow uses a private (password protected) page in WordPress, Google Forms, Google Sheets, a script for said spreadsheet, and Google Drive. Here’s how it all comes together:

Step 1: Limit access to the shared inventory/pipeline

A WordPress page became the hub for the private access to all the shared information. We created a password-protected page which has direct access to the form (more below), as well as a direct link to the spreadsheet (again, more below) which contains all the shared information.

Here’s how to create a password protected page in WordPress and how it looked to users:

The workflow we created relies heavily on Google tools, so a Google login for each contributor to the inventory/pipeline is necessary.

For example, the Google Form that's embedded in the private page requires you to log in to submit your responses. A login is also required to access the spreadsheet. This allows for another layer of restricting access and creates a history of track changes for each user.

Next, you’ll see how we created the form.

Step 2: Build a form to collect information for the shared inventory

We built our form using Google Forms. They’re easy to create, allow for collaborators, and seamlessly connect with other Google Tools, which in our case are Google Sheets, Google Drive and of course, the Google login for restricting access.

The fields we decided to use are the following:

Step 3: Funnel the form submissions to a spreadsheet

Once responses to the form are submitted, the user has an option to edit their submission or submit an additional form response. The submissions are automatically sent to a connected Google Sheet. Each form question has its own column in the Google Sheet and the responses are added as cells under each column. This is the case for all columns except two. The exceptions:

Program Upload

If a program is uploaded as a .pdf file, for example, then the file is saved in a Google Drive folder and a link to the file is automatically added to the spreadsheet.

Link to Edit the Form Submission

Since every form submission has a unique URL, we needed to find a way had to populate the special link to edit the submission alongside its corresponding set of responses. We were able to do that by using Google Apps Script.

Check out next week's blog post ("Fun with Google Apps Script!") for more information on how we did this.

Want to know more about how we did this? Get in touch!

How to use News Match Donation Shortcode

As part of INN's support for the 2017 News Match campaign, we've released two WordPress plugins to help sites convert readers. News Match Donation Shortcode provides a donation form for your site to ease donations through the News Revenue Hub as part of the News Match campaign.

Prefer a video walkthrough? Watch this tutorial on youtube.

Installing the plugin

On your WordPress site, click on "Plugins" in the Dashboard menu. If you see an "Add New" button at the top of the page, click that.

If you don't see the "Add New" button or the "Plugins" menu, your user might not have permission to manage plugins on the site; you should contact your technical support and ask them to install News Match Donation Shortcode for you. Your site might require downloading the plugin ZIPs and uploading them via FTP instead of using WordPress' built-in plugin installation tools.

Configuring the plugin

A screenshot of the plugin's locaiton in the wordpress settings menuThe plugin's settings are at Settings > News Match Shortcode in the WordPress admin.

When you first enable the plugin, you'll want to configure it with your organization's name, your News Revenue Hub ID, the default donation amount, and the live and staging URLs of your News Revenue Hub form.

The settings is where you configure the donation levels to match your organization's membership levels. While the plugin comes with 4 default donation levels, you can easily define your own labels and donation levels. The defaults are: $0-$5 Friend, $5-$50 Ally, $50-$500 Champion, and $500+ Ambassador. If you want fewer donation levels, set the third level's upper donation amount to a very high amount, such as your org's dream budget, and make sure that the fourth level is more than that.

A screenshot of the level 1 donation level settings.
Here's an example of non-default configuration of the first donation level out of four.

If you use Salesforce to track campaigns, you can set a default Salesforce campaign ID for the plugin in the plugin's settings. This can be overridden on a per-form basis by setting the sf_campaign_id attribute of the shortcode, like so: [newsmatch_donation_form sf_campaign_id="foo" amount="25"]

A screenshot of the WordPress admin dashboard shows the setting for the Salesforce Campaign ID
This is the Salesforce campaign ID setting in the plugin admin.

The shortcode in use

The default form of the shortcode uses buttons to select the donation level:

a screenshot of the donation form
By adding type="select" to the shortcode, it appears like this:

a screenshot of the dropdown donation form
[newsmatch_donation_form type="select"]
A full list of shortcode arguments and examples can be found in the plugin's entry, but they're basically one-off overrides for your Salesforce campaign ID, your default donation amount, and the type of form.

The above screenshots use the plugin's default styles with non-default configuration. You can style the donation form using your site's theme's CSS, Jetpack’s Custom CSS Editor, or any other tool that allows you to define custom styles on your site. Guidance for these custom styles can be found in the FAQ section of the plugin's entry.

Need support?

If you have questions about this plugin and integrating it with your WordPress site, contact

If you have questions about the News Revenue Hub, visit their contact page.

If you have questions about the News Match program, visit their website for donornonprofit and funding partner information.

Pym Shortcode plugin update: version 1.3.1

Last week, NPR released Pym.js version 1.3.0, and earlier this week released 1.3.1. These feature releases introduced optional scroll tracking, allowing the child iframe to know where the browser is on the parent page. You can read more about how that's implemented, and how it can be used, on the NPR Visuals Team blog post announcing Pym 1.3.0. Pym.js version 1.3.1 added a function getParentPositionInfo to the Pym child.

Pym Shortcode version 1.3.1 brings you the latest version of Pym.js, as well as the following improvements:

  • Adds an id="" attribute to allow setting of custom IDs on embeds, for Github issue #21. The id="" attribute is useful if you want to load a new embedded page inside the iframe and maintain Pym functionality.
  • Adds a class="" attribute to allow setting custom of classes on embeds, for Github issues #22 and #23. The class="" attribute allows you to, among other things, add layout classes to embeds so they take a different shape on your page.
  • Adds a default class name pym to all embed-containing <div> elements output by this plugin, and a filter pym_shortcode_default_class to allow changing the default class or removing it.

You can download the new version of the Pym Shortcode plugin through your WordPress dashboard, on the plugin repository, or on Github.

If you have feedback on the plugin or would like to contribute to development of the Pym Shortcode plugin, check out our contributor guidelines and join the conversation in the plugin's GitHub issues or in our Slack.