If you read NewsCut, Updraft, or any of the other MPR News blogs, you may have noticed a facelift in the last couple months. Our blogs have been moved from Movable Type to WordPress. A large component of this change was a new front-end theme that is responsive and works on many devices.
A big challenge for making sites responsive is media: any content that’s not text. Text is easy to reflow to different screen sizes. Images, video, and interactive content are trickier. This is especially pronounced in blogging, where it’s typically anything goes in the body field of your favorite blogging platform. An object/embed or an iframe from some random source on the web that an author want to drop in can really wreak havoc on a responsive layout. Similarly, images with lots of layout positioning and/or are low resolution can come across poorly.
Part one, below, looks at how we addressed non-image, non-audio media. In part two, we’ll look at how we deal with images and some of the frontend performance implications.
On our blogging system, we restrict the HTML that content authors can use in posts. Specifically, we strip the script, object, iframe, and embed tags from posts. This presents an issue, since these tags are what make the embed buttons on most sites work. There is another less known but infinitely more cool way of doing embeds, and that is oEmbed. Instead of copying in emebd code, authors paste in the canonical URL for the media object, and due to to magic in wordpress, the oEmbeds get turned into the proper embed code. This gets us closer to working media.
Embed.ly saves the day
WordPress comes with support for about 15 different oEmbed providers. However, our bloggers tend to use more than just the simple built-in ones. Unfortunately, not every content provider that doles out embed tags is an oEmbed provider. To make up for this deficit, we call upon the Embed.ly to act as a provider for about 600 additional services. Emebed.ly provides a plugin to add these providers into wordpress, but it is not friendly to a multisite installation. To fix that, We reverse engineered their plugin and and added it to our theme. The embed.ly plugin gives buttons in the post creation GUI that we didn’t want… Oembeds are supposed to be simple, adding buttons makes it more complicated.
Here’s how it works: We have a flat file in our theme that contains, on each line, a regex for the URL pattern that wordpress should look for. We then have a little function in functions.php that loads this file up, and loops through calling wp_oembed_add_provider to bake it in. This is the gist on github.
The sneaky bit in this was getting the oembed patterns from Embed.ly. We installed the embed.ly plugin, looked at the DB tables with patterns that it created, extracted them, and hard-coded them into this file. Then we disabled and uninstalled their plugin. This means we have to manually update the patterns when they change, but so far this hasn’t been an issue.
As awesome as embed.ly is, it doesn’t work for everything. A few things we’ve found it doesn’t support well: DocumentCloud, Google Fusion Tables, and Github Gists. To work around this, we created a system we call FauxEmbeds. In essence, it works just like oEmbeds to a content author, but there’s no oEmbed provider to call back to. Instead, support is baked into our theme. Here’s how we do it for google fusion tables, and here’s DocumentCloud. For DocumentCloud, we borrowed and simplified some code from the NPR Argo Project, and kept the shortcode support.
Code we get back from oEmbed providers or from our fauxEmbeds is generally not responsive. For instance, the iframe embed that Youtube gives you has a size set on it. If you plop this in a responsive site without doing some fixups, it will look lousy on non-desktop devices. To work around this, we wrap every oEmbed with the flex-video wrapper in Foundation. This overrides the height/width properties on the iframe/object/embed (most of the time) and makes it 100% width and auto height.
Most video embeds deal with this gracefully. Some things like google docs or document cloud don’t, so in those cases we set the height to 500px. Sometimes this leads to extra white space or horizontal scrolling, but it’s a middle ground we’re satisfied with.
You can see on lines 26-32 of this gist how we do it: We add on a filter for oEmbeds that looks for object/iframe/embed tags, and adds the wrapper. If flex-video is already there, we don’t add the wrapper.
A responsive site should support most screen sizes and device capabilities. Most non-desktop devices don’t support Adobe Flash, which leads to problems when an embed hands you a flash based video. Some of the bigger providers (YouTube, Vimeo, etc) auto-detect this and serve html5-based video in their iframe, but not all. Sadly, we haven’t figured out a way to gracefully deal with this situation. We cannot force non-compliant providers to update their stuff. The best we can do is advise our content authors to be aware of this situation and try to avoid flash-only embeds when they can. Hopefully this is a situation that gets better as time goes on and flash dies out.