IDEAS | BLOG

Styling inline images with Drupal’s WYSIWYG and Media modules

Controlling the styling of inline images inserted via a WYSIWG editor can be challenging. Generally, unless content creators want to write their own HTML, they are limited to the basics: aligning an image left or right, applying a border, or constraining the image size.

Recently, we worked on a site where content creators needed to display images inserted via WYSIWYG with captions. They also wanted to be able to float the images and their captions left or right, and they wanted the captions to appear in a smaller font than the rest of the text. In order to meet this requirement, we had three challenges:

  1. Collect the caption text in a logical workflow of inserting an image.

  2. Wrap the image and its caption in markup so it could be styled with CSS as a unit.

  3. Apply classes to the wrapper markup when the content creator used the WYSIWYG “Styles” selection tool to align an image left or right.

Step One – Creating a new display mode for file entities.

We accomplished this by invoking hook_entity_info_alter() within a custom module.

/**
 * Implements hook_entity_info_alter()
 * Add custom view mode for images with captions
*/
function MODULE_general_entity_info_alter(&$entity_info) {
  $entity_info['file']['view modes'] += array(
    'img_caption' => array(
      'label' => t('Image with caption'),
      'custom settings' => FALSE,
    ),
  );
}

Step Two – Configuring the new display mode

In order to configure the new display mode we begin by navigating to Structure -> File Types -> Image -> Manage Display. Next, we enabled the “Image with Caption” view mode under “Custom Display Settings” and then finally enabled the “Alt” text field to be displayed underneath the image as shown in the following screenshot.

Configure Display

Now, when content creators clicked on the media button in the WYSIWYG editor, they had the option to display as “Image with caption.” The caption was determined by whatever text they entered into the Alt Text field on that same form.

Image with Caption field

It is important to note that the new display mode isn’t used in WYSIWYG editor itself, so content creators won’t see their caption displayed until after they save and view the node.

By default, images and captions were now wrapped in an HTML div with classes “media media-element-container media-img_caption” and captions were wrapped in their own div with field-specific classes so we could easily apply CSS.

Step Three – Altering markup

The last requirement was to be able to float the container if the content creator opted to apply a float with the Styles tool within CKEditor. The tool’s default behavior is to add an align attribute to the img element. This would obviously work to float just the image, but we wanted to float the image and its caption. This led us to the Media module’s API, which provides a hook that we can use to alter markup.

/**
* Implements hook_media_token_to_markup_alter()
* Makes images with captions float-able
*/
function MODULE_media_token_to_markup_alter(&$element, $tag_info, $settings) {
	if (($element['content']['#bundle'] == 'image') && ($element['content']['file']['#view_mode'] == 'img_caption')) {
		// Check to see if there's a float on the image
		if (isset($element['content']['file']['#item']['attributes']['align'])) {
			$float = $element['content']['file']['#item']['attributes']['align'];
			// Take the float off of the image
			unset($element['content']['file']['#item']['attributes']['align']);
			// Add the float to the containing div
			array_push($element['content']['#attributes']['class'], $float);
		}
	}
}

Our code checks to see if there’s an align attribute on an image, and if so moves it to the containing wrapper. With a little CSS magic, the end result looks like the following screenshot.

end results

Summary

While there are always several solutions to any request in Drupal, having the knowledge of how to hook into the API of both core and modules allows for a flexible approach. In our case, it allowed us to create a new view mode for the file entity which allows our end user to configure how they want an image with caption to be displayed. Finally, we were able to hook into the media module to allow for altering the markup for aligning the image and caption based on the user’s selection.

More good ideas we think you'll enjoy