1 filter.module | _filter_image_caption($text) |
Implements callback_filter_process().
Replace img data-caption attributes with figure and figcaption elements.
Related topics
File
- core/
modules/ filter/ filter.module, line 2589 - Framework for handling the filtering of content.
Code
function _filter_image_caption($text) {
// If no captions, immediately return.
if (stristr($text, 'data-caption') === FALSE) {
return $text;
}
// Load the text as a DOM object for manipulation.
$dom = filter_dom_load($text);
$xpath = new DOMXPath($dom);
foreach ($xpath->query('//*[@data-caption]') as $node) {
// Read the data-caption attribute's value, then delete it.
$caption = $node->getAttribute('data-caption');
$node->removeAttribute('data-caption');
// Sanitize caption: decode HTML encoding, limit allowed HTML tags; only
// allow inline tags that are allowed by default, plus <br>.
$caption = filter_xss($caption, array('a', 'em', 'strong', 'cite', 'code', 'br'));
// The caption must be non-empty.
if (backdrop_strlen($caption) === 0) {
continue;
}
// Given the updated node and caption: re-render it with a caption, but
// bubble up the value of the class attribute of the captioned element,
// this allows it to collaborate with e.g. the filter_align filter.
$attributes = array();
$tag = $node->tagName;
$classes = $node->getAttribute('class');
$node->removeAttribute('class');
$node = ($node->parentNode->tagName === 'a') ? $node->parentNode : $node;
if ($classes) {
$attributes['class'] = explode(' ', $classes);
}
$attributes['class'][] = 'caption';
$attributes['class'][] = 'caption-' . $node->tagName;
$theme_parameters = array(
'item' => $node->ownerDocument->saveXML($node),
'tag' => $tag,
'caption' => $caption,
'attributes' => $attributes,
);
// In order to test this filter without a database connection, we
// may directly call theme_filter_caption() to generate output.
if (Database::isActiveConnection()) {
$filter_caption = theme('filter_caption', $theme_parameters);
}
else {
module_load_include('inc', 'filter', 'filter.theme');
$filter_caption = theme_filter_caption($theme_parameters);
}
// Load the altered HTML into a new DOMDocument and retrieve the element.
$updated_node = filter_dom_load($filter_caption)
->getElementsByTagName('body')
->item(0)
->firstChild;
// Import the updated node from the new DOMDocument into the original
// one, importing also the child nodes of the updated node.
$updated_node = $dom->importNode($updated_node, TRUE);
// Finally, replace the original node with the new node.
$node->parentNode->replaceChild($updated_node, $node);
}
return filter_dom_serialize($dom);
}