embedding map mashups

Using Google Maps in WordPress

Once you've created a map, Google Maps presents a "Link" button, which presents two fields:

  1. Link to map
  2. Embed map

Standard Google Maps link fields

If you're working with a standard/static web site, you can simply copy the provided "embed" code to the clipboard and paste it anywhere in your HTML document. The map is embedded by using the HTML <iframe> tag, which creates a virtual frame in the middle of a web page, into which is inserted content (such as a map) from another site.

That's all well and good for a site that you have 100% control over, but many content management systems allow posting of content by anonymous, semi-anonymous, or less-trusted users. It would be trivial for a shady user to embed malicious code from another site into the middle of an iframe. In other words, if you run a content management system where there is a possibility that untrusted users might be posting, you could unwittingly end up hosting malicious code on your web site.

For this reason, WordPress has some security restrictions in place to prevent this from happening. Those security restrictions appear in two places in the WordPress codebase, and you need to be aware of them so you can take steps to let your authors and editors post maps in iframes.

In the Visual Editor:  WordPress provides two ways to create a new Post or Page: HTML mode, and Visual mode.

Visual-HTML modes
Toggling between the Visual and HTML editing modes in WordPress.

 HTML mode is your standard web form (but with helpful formatting buttons), while Visual mode provides a graphical view that hides the HTML from you. This makes things more comfortable for people who don't like looking at HTML code. If you switch to HTML mode, paste in the iframe code provided by Google, and then switch back to Visual mode, you'll find that most of your iframe code has been stripped out. You can get around this in one of two ways: 1) You can disable the Visual mode entirely by going to your profile in WordPress and deselecting the checkbox "Use Visual Editor." However, you will no longer have access to the visual editor in WordPress; 2) Modify the source code of WordPress itself to make the visual editor (aka "TinyMCE") stop stripping out your iframes. Here's a good guide on how to do that. 

In the HTML Editor:  Even after you've prevented the visual editor from stripping out iframes, you may or may not find that WordPress itself still strips them out after you hit the Save button. Remember what we said above about trusted users? When you click Save, WordPress checks to see what your "role" is on the site. If you're an Administrator or an Editor, you're allowed to save iframe content. But if you're a normal Author or Contributor, you're not allowed to. Makes sense when you think about, though it's certainly frustrating. 

At this point you have several possible ways to solve this problem. Any of these will work, but with different upsides and downsides:

  • Make all of your Authors into Editors, and have them all disable the Visual Editor. This may mean handing out more permission than needed (seldom a good idea), and most people really like the Visual Editor.
  • Leave everyone as Authors and have them disable the Visual Editor, but modify the internal rules for the author role.  You can do this with the Role Manager plugin. But again, most people really like the Visual Editor, so this may not be a great solution.
  • Use a shortcode solution. Shortcodes are little strings of text that users can put right into the post body that do special things. Shortcodes are usually provided by plugins. By using a shortcode solution, users can still have the Visual Editor. And since the string "iframe" is never actually typed into the text field, it won't be stripped out. There is an embed iframe plugin available that lets users create iframes with a shortcode, but in our testing, it did not work with Google Maps content. A more sophisticated shortcode solution is needed (see next option).
  • Use a dedicated mapping plugin. There are quite a few of them out there, but the one we really like is the XML Google Maps WordPress plugin. While it's a bit overkill for simple map embeds, this plugin contains a ton of hidden power, and never requires the string "iframe" to be typed into a text field. It works in one of two ways:
  1. In its simplest usage, the plugin can transform any link that points to a KML file on the web into a perfectly working Google Map. To make this work, you'll need to extract a different kind of link from your Google Map. First, make sure you're in My Maps mode in Google Maps. Select the map you want to link to. Now, rather than using the "Link" button in Google Maps, look for the link that says "View this map in Google Earth." That link points to what's known as a "KML" file (we won't cover the meaning of that term here). Don't click on that link! Instead, right-click it and select "Copy link location" to put its URL on your clipboard.
    Google Earth link
    Now create some text in the post body, such as "Map Here" and link it to the URL on your clipboard. When you save the page, you'll find that a perfectly rendered Google Map will magically take the place of the link you created. Pretty cool. See the plugin's settings for additional options.
  2. If you want more control over exactly how your map is embedded, you can use the shortcode solution that comes with the plugin. The shortcode is documented in detail here, but the short version is that you can insert something like this in either the HTML or Visual editor:
[xmlgm {http://www.xyz.com/text.kml} width=400;height=300]
...replacing the URL shown there with the URL to the KML version of the map you want to embed. Again, the shortcode is capable of accepting many different arguments, so have a look at the documentation.
And there you have it - a seemingly simple problem made ridiculously complicated by security requirements. But with a little knowledge and the right tools in your toolbelt, it's not hard to have a whole team of journalists happily inserting maps into your site.