The official Pinterest engineering blog.

Updated: good news, everyone! It looks like Tumblr is now allowing data attributes past their editor. Please try your Pinterest widgets without our hacky fix.

The Problem

As you may have noticed, Tumblr’s post editor is very enthusiastic about stripping “nonstandard” tags and attributes, including many that are standard in HTML5.

Unfortunately, Pinterest widgets are all built around links with configuration instructions—including the ones that tell the widget script that this is a widget, and any special configuration options—passed as data attributes.

To make widgets work on Tumblr, we’ll hide our data attributes somewhere the editor won’t look, and then convert them to widgets with JavaScript. For this example we’ll stash our data in the rev attribute, which is rarely used any more but still perfectly good HTML.

Pin It Button

Here’s the generated code for a Pin It button, hot off the Widget Builder:

<a href="//pinterest.com/pin/create/button/?url=http%3A%2F%2Fwww.flickr.com%2Fphotos%2Fkentbrew%2F6851755809%2F&media=http%3A%2F%2Ffarm8.staticflickr.com%2F7027%2F6851755809_df5b2051c9_z.jpg&description=Next%20stop%3A%20Pinterest" 
data-pin-do="buttonPin" 
data-pin-config="above">
<img src="//assets.pinterest.com/images/pidgets/pin_it_button.png" />
</a>

Here it is translated for a Tumblr post:

<a class="pinterestWidget" 
rev="data-pin-do=buttonPin data-pin-config=above" 
href="//pinterest.com/pin/create/button/?url=http%3A%2F%2Fwww.flickr.com%2Fphotos%2Fkentbrew%2F6851755809%2F&media=http%3A%2F%2Ffarm8.staticflickr.com%2F7027%2F6851755809_df5b2051c9_z.jpg&description=Next%20stop%3A%20Pinterest"><img src="//assets.pinterest.com/images/pidgets/pin_it_button.png" /></a>

See the difference? We are adding class name pinterestWidget and moving the data attributes and values into the rev attribute. Here’s what that button looks like:

image

Embedded Pin

Here’s what an embedded pin looks like straight from the Widget Builder:

<a data-pin-do="embedPin" href="http://pinterest.com/pin/99360735500167749/">
</a>

Here it is translated for a Tumblr post:

<a class="pinterestWidget" 
rev="data-pin-do=embedPin" href="http://pinterest.com/pin/99360735500167749/">
</a>

Here’s what it looks like on the page:

Embedded Board

Here’s a more complicated example, an embedded board with configuration options:

<a data-pin-do="embedBoard" href="http://pinterest.com/pinterest/pin-pets/"
data-pin-scale-width="115"
data-pin-scale-height="400"
data-pin-board-width="720">
</a>

Here it is translated for a Tumblr post:

<a class="pinterestWidget"
rev="data-pin-do=embedBoard data-pin-scale-width=115 data-pin-scale-height=400 data-pin-board-width=720" 
href="http://pinterest.com/pinterest/pin-pets/">
</a>

In this example we took all three data attributes and moved them into the rev attribute. To be super clear: we are removing the quotes around “115,” “400,” and “720,” concatenating all the data-pin key/value pairs into a single string, and putting quotes around it to make it the value of the rev tag.

Here’s what our embedded board widget looks like on Tumblr:

The Script

To make Tumblr work, you’ll need to edit your template. Copy this script and paste it in at the very end, just before the closing </body> tag:

<script>
// be sure this script doesn't mess up anything else on this page
(function (d, att) {
  // declare some variables
  var link, pair, part, i, j, k, n, hazWidget, script;
  // find all the links on the page
  link = d.getElementsByTagName('A');
  // go through them one at a time
  for (i = 0, n = link.length; i < n; i = i + 1) {
    // do we have a rev and a class name that matches our pattern?
    if (link[i][att]) {
      // split the attribute into individual directives
      pair = link[i][att].split(' ');
      // loop through each directive
      for (j = 0, k = pair.length; j < k; j = j + 1) {
        // split into parts: first is key, second is value
        part = pair[j].split('=');
        // do we have two parts?
        if (part[0] && part[1]) {
          // set the attribute on the link
          link[i].setAttribute(part[0], part[1]);
          // after this is all done, build a widget
          if (part[0] === 'data-pin-do') {
            hazWidget = true;
          }
        }
      }
    }
  }
  // do we need to build a widget?
  if (hazWidget === true) {
    // make a script
    script = d.createElement('SCRIPT');
    // set the type
    script.setAttribute('type', 'text/javascript');
    // set the character set
    script.setAttribute('charset', 'utf-8');
    // set the source
    script.setAttribute('src', '//assets.pinterest.com/js/pinit.js');
    // carefully append it to the body
    d.getElementsByTagName('BODY')[0].appendChild(script);
  }
// if you would like to use some other attribute instead of rev, change it here
}(document, 'rev'));
</script>

Have fun with this, and please leave any comments or pull requests on GitHub.