Using Iframes With Drupal’s WYSIWYG Module And TinyMCE

Impatient? Skip the pre-amble and go straight to the solution.

Despite it’s considerable, Drupal has become the main tool used for this blog and at work. Despite the power under the hood, it sill lags behind WordPress for user experience.

In previous versions, Drupal editor was fiddly to set up with lots of niggles that made life awkward, especially for occassional bloggers used to the friendly WordPress interface.

Fortunately, the new Wysiwyg module dramatically changes this picture providing Drupal users access to a wide range of editors (FCKeditor 2.6, TinyMCE 3, TinyMCE 2, Whizzywig 55, YUI editor
2.7 amongst others). Add in some rather nifty picture handling using IMCE and suddenly Drupal as a blogging platform doesn’t feel like WordPress’ poor relation.

However, there are still niggles. One that’s been driving me nuts for the last few weeks has been the problem with adding Google Maps to blog posts, or any other type of page edited with TinyMCE (the flavour of editor we’ve decided to use at Chinwag).

What about the brilliant Google Maps (GMAP) module, I hear you cry? Good point, well made. It does have a very handy input filter to defined Google Maps using a macro.

But for something more fancy including, say a list of locations that need to be added to a map, like this one created using Audioboo on the Digital Mission to LA & San Francisco. Or what about other widgets using iframes to show themselves on your pages.

Try copying/pasting iframe code into a blog post, then enable TinyMCE and, hey presto, your code is gone. Not very useful. TinyMCE, quite rightly, strips out the iframe code, because, and I can’t stress this enough, it’s a potentially huge security hole.

The Solution

Caveat: This opens a potential security hole on your site. Only enable to the smallest number of privileged users on your site. Under no circumstances enable this for Anonymous users, or you are asking for trouble. You have been warned!

The plugin infrastructure provided by TinyMCE is easily accessible using the Wyisywyg module’s hooks. This gives a neat solution without having to tinker either with any core files and also allows to add other extensions, if you’re comfortable coding.

Ideally, someone in the future will turn this into a fully-featured module that allows further customisation without coding. It’s clearly an issues that’s annoying a few users.

The solution (props to Jonathan Hedstrom) uses the Wysiwyg’s hook_wysiwyg_plugin() and TinyMCE’s extended_valid_elements plugin to persuade TinyMCE to stop stripping out the iframe tags. The hook passes an array to TinyMCE that creates a TinyMCE plugin, that can be enabled on the editors profile page.

This code has been tested with:

  • Drupal 6.15 (and works with at least 3 previous releases)
  • Wysiwyg 6.x-2.x-dev (and last 3 release versions)
  • TinyMCE 3.2.5

and is dependent on the following modules being installed and configured:

  • Wysiwyg
  • TinyMCE library installe
  • TinyMCE profile enabled

Installation

The code used is listed below and there’s also a download, which you can install as a stand-alone module. It shouldn’t break anything else, but use at your own risk. There’s two options:

function yourmodulename_wysiwyg_plugin($editor, $version) {
  switch($editor) {
    case 'tinymce':
      return array(
        'iframe' => array(
          'extensions' => array('iframe' => t('Iframe Fix')),
          'extended_valid_elements' =>
array('iframe[src|width|height|frameborder|scrolling]'),
          'load' => FALSE,
          'internal' => TRUE,
          ),
      );
  }
}

 

Assuming you’ve downloaded the module, here’s the instructions to get it up and running (this’ll all sound very familiar if you’re used to installing Drupal modules):

1) Copy the tinymce_extended folder to the modules folder in your installation.

2) Enable the module using Administer -> Site building -> Modules  (/admin/build/modules).

3) Enable the function in wysiwyg’s TinyMCE profile. Go to Administer -> Site Configuration -> Wysiwyg and click ‘Edit’ for the TinyMCE profile that you want to access <iframe> tags. Expand the ‘Buttons and plugins’ option and tick the option for ‘Iframe Fix’, which should be near the bottom.

4) If your site has heavy caching, it might be worth clearing the cache, to make sure it’s all working. Go to Administer -> Site Configuration -> Performance and click on the ‘Clear cached data’ button near the bottom of the page.

Security

Use this module (of a fix if you’re using the code directly) with care. Iframes can be a security blackhole, so only expose this option to user’s that need it.

I’d suggest creating a specific TinyMCE profile using the Wysiwyg module that is purely for admins and enable the iFrame fix plugin for this module only. That should limit your exposure, but please note, you’re using this at your own risk!

Picture courtesy of aburt. Some rights reserved.


Comments from the original blog

These comments were left on the original WordPress version of this post and are kept for reference. Comments are closed.

Jeff Geerling · 24 September 2010

Thanks for the code! It works great on one of my sites, stlouisreview.com and it’s simple enough for almost anyone to grok. I wouldn’t mind this someday being an option in WYSIWYG core… especially since sites like Vimeo and YouTube are now using iframes exclusively.

Sam Michel (author) · 25 September 2010

Thanks Jeff, it’d be great to have it in the WYSIWYG module. Not sure why it hasn’t been, although perhaps it’s something that TinyMCE will integrate directly. It’d be great to have Drupal’s WYSIWYG interface finally catch-up with WordPress.

Johndescs · 19 January 2011

Many thanks! This is a long-time annoying issue now easly fixed for me! Great!

I used to merely disable rich text editor on the nodes which needed iframes, but this is clealy far better.

Sebas · 30 March 2011

Thanks man!!

I just added a style attribute on the iframe tag.

Cheers!

greenman · 7 July 2011

You Rock! It works.

Roger · 6 September 2011

Thank you so much!

That annoying issue now has been easly fixed for me!