Markdown, Images, and Drupal's Image Styles

Markdown editor for BUEditor

Generally speaking, there is no reason for me to use a WYSIWYG editor in Drupal when I’m using Markdown. Unfortunately, I needed an easy way to add images to my content as well, using a file browser/uploader.

Fortunately, the best image/file uploader and browser for Drupal is, in my opinion, IMCE. It integrates with textareas in Drupal without the need for a WYSIWYG editor

Unfortunately, however, it inserts HTML code for images, which kind of defeats the purpose of Markdown.

Fortunately, after looking for a bit I found that BUEditor (the editor used on Drupal.org) has a Markdown editor plugin that integrates with IMCE and inserts the images with proper Markdown syntax.

Unfortunately, there’s no way to add image styles (Drupal 7’s image derivatives) to images inserted by IMCE. For that matter, I’m not aware of any module that supports this; although it’s possible to use image formatters with image fields, if you want to do this for inserted images you’ll need to modify the image URLs by hand.

Fortunately, my plan was to apply the same image style to each inserted image, so I could write an input filter that would change the URL of the image when it was displayed. Now I wouldn’t have to change every image URL.

Unfortunately, due to a change in Drupal 7.201, Drupal 7 now appends a token to automatic image derivative URLs as a query string. No security token? You’ll get a 404 if your browser requests an image that would ordinarily be created by D7’s image styles.

Fortunately, it’s possible to add the token in the image filter; here’s the basic function you’ll need in your custom module:

function MYMODULE_filter_html($text, $filter, $format) {
  // Apply an image style to every image.
  if (preg_match_all('/<img.+?src="((?:http:\/\/example\.com)?(\/path\/to\/files\/and\/more.*?))".+?>/', $text, $matches)) {
    foreach($matches[0] as $k => $v) {
      $path_to_image = str_replace('/path/to/files/', '', $matches[2][$k]);
      $uri_to_image = file_build_uri($path_to_image);
      $url_to_image = image_style_url('image_style', $uri_to_image);
      $text = str_replace($matches[1][$k], $url_to_image, $text);
    }
  }

  return $text;
}

A couple notes:

  • My regex could undoubtably be better—for example, making it more generic
  • I was only looking to do this to images in the “and/more” subdirectory of the public files directory
  • I should probably change this so that it’s only done to images that I add an “image-style-” class to

  1. See the d.o Security Advisory, 7.20 Release Notes, and 7.21 Release Notes. I know that people much smarter than I made this change, but it doesn’t seem to be as big a deal as they are making it. And it’s creating havoc when styles are updated and with SEO