' . t('About') . ''; $output .= '
' . t('The Responsive Image module provides an image formatter and breakpoint mappings to output responsive images using the HTML5 picture tag. For more information, see the online documentation for the Responsive Image module.', array( '!responsive_image' => 'https://drupal.org/documentation/modules/responsive_image')) . '
'; $output .= '' . t('A responsive image mapping associates an image style with each breakpoint defined by your theme.') . '
'; break; } return $output; } /** * Implements hook_menu(). */ function responsive_image_menu() { $items = array(); $items['admin/config/media/responsive-image-mapping'] = array( 'title' => 'Responsive image mappings', 'description' => 'Manage responsive image mappings', 'weight' => 10, 'route_name' => 'responsive_image.mapping_page', ); $items['admin/config/media/responsive-image-mapping/%responsive_image_mapping'] = array( 'title' => 'Edit responsive image mapping', 'route_name' => 'entity.responsive_image_mapping.edit_form', ); $items['admin/config/media/responsive-image-mapping/%responsive_image_mapping/duplicate'] = array( 'title' => 'Duplicate responsive image mapping', 'route_name' => 'entity.responsive_image_mapping.duplicate_form', ); return $items; } /** * Implements hook_theme(). */ function responsive_image_theme() { return array( 'responsive_image' => array( 'variables' => array( 'style_name' => NULL, 'uri' => NULL, 'width' => NULL, 'height' => NULL, 'alt' => '', 'title' => NULL, 'attributes' => array(), 'mapping_id' => array(), ), 'function' => 'theme_responsive_image', ), 'responsive_image_formatter' => array( 'variables' => array( 'item' => NULL, 'path' => NULL, 'image_style' => NULL, 'mapping_id' => array(), ), 'function' => 'theme_responsive_image_formatter', ), 'responsive_image_source' => array( 'variables' => array( 'src' => NULL, 'srcset' => NULL, 'dimensions' => NULL, 'media' => NULL, ), 'function' => 'theme_responsive_image_source', ), ); } /** * Returns HTML for a responsive image field formatter. * * @param array $variables * An associative array containing: * - item: An ImageItem object. * - image_style: An optional image style. * - path: An optional array containing the link 'path' and link 'options'. * - mapping_id: The ID of the responsive image mapping. * * @ingroup themeable */ function theme_responsive_image_formatter($variables) { $item = $variables['item']; if (!isset($variables['mapping_id']) || empty($variables['mapping_id'])) { $image_formatter = array( '#theme' => 'image_formatter', '#item' => $item, '#image_style' => $variables['image_style'], '#path' => $variables['path'], ); return drupal_render($image_formatter); } $responsive_image = array( '#theme' => 'responsive_image', '#width' => $item->width, '#height' => $item->height, '#style_name' => $variables['image_style'], '#mapping_id' => $variables['mapping_id'], ); if (isset($item->uri)) { $responsive_image['#uri'] = $item->uri; } elseif ($entity = $item->entity) { $responsive_image['#uri'] = $entity->getFileUri(); $responsive_image['#entity'] = $entity; } $responsive_image['#alt'] = $item->alt; if (Unicode::strlen($item->title) != 0) { $responsive_image['#title'] = $item->title; } // @todo Add support for route names. if (isset($variables['path']['path'])) { $path = $variables['path']['path']; $options = isset($variables['path']['options']) ? $variables['path']['options'] : array(); $options['html'] = TRUE; return \Drupal::l($responsive_image, Url::fromUri($path, $options)); } return drupal_render($responsive_image); } /** * Returns HTML for a responsive image. * * @param $variables * An associative array containing: * - uri: Either the path of the image file (relative to base_path()) or a * full URL. * - width: The width of the image (if known). * - height: The height of the image (if known). * - alt: The alternative text for text-based browsers. * - title: The title text is displayed when the image is hovered in some * popular browsers. * - style_name: The name of the style to be used as a fallback image. * - mapping_id: The ID of the responsive image mapping. * * @ingroup themeable */ function theme_responsive_image($variables) { // Make sure that width and height are proper values // If they exists we'll output them // @see http://www.w3.org/community/respimg/2012/06/18/florians-compromise/ if (isset($variables['width']) && empty($variables['width'])) { unset($variables['width']); unset($variables['height']); } elseif (isset($variables['height']) && empty($variables['height'])) { unset($variables['width']); unset($variables['height']); } $sources = array(); // Fallback image, output as source with media query. $sources[] = array( 'src' => _responsive_image_image_style_url($variables['style_name'], $variables['uri']), 'dimensions' => responsive_image_get_image_dimensions($variables), ); $responsive_image_mapping = ResponsiveImageMapping::load($variables['mapping_id']); // All breakpoints and multipliers. $breakpoints = \Drupal::service('breakpoint.manager')->getBreakpointsByGroup($responsive_image_mapping->getBreakpointGroup()); foreach ($responsive_image_mapping->getKeyedMappings() as $breakpoint_id => $multipliers) { if (isset($breakpoints[$breakpoint_id])) { $breakpoint = $breakpoints[$breakpoint_id]; $new_sources = array(); foreach ($multipliers as $multiplier => $image_style) { $new_source = $variables; $new_source['style_name'] = $image_style; $new_source['#multiplier'] = $multiplier; $new_sources[] = $new_source; } // Only one image, use src. if (count($new_sources) == 1) { $sources[] = array( 'src' => _responsive_image_image_style_url($new_sources[0]['style_name'], $new_sources[0]['uri']), 'dimensions' => responsive_image_get_image_dimensions($new_sources[0]), 'media' => $breakpoint->getMediaQuery(), ); } else { // Multiple images, use srcset. $srcset = array(); foreach ($new_sources as $new_source) { $srcset[] = _responsive_image_image_style_url($new_source['style_name'], $new_source['uri']) . ' ' . $new_source['#multiplier']; } $sources[] = array( 'srcset' => implode(', ', $srcset), 'dimensions' => responsive_image_get_image_dimensions($new_sources[0]), 'media' => $breakpoint->getMediaQuery(), ); } } } if (!empty($sources)) { $output = array(); $output[] = '