function ResponsiveImageThemeHooks::preprocessResponsiveImage

Prepares variables for a responsive image.

Default template: responsive-image.html.twig.

Parameters

array $variables: An associative array containing:

  • uri: The URI of the image.
  • width: The width of the image (if known).
  • height: The height of the image (if known).
  • attributes: Associative array of attributes to be placed in the img tag.
  • responsive_image_style_id: The ID of the responsive image style.

File

core/modules/responsive_image/src/Hook/ResponsiveImageThemeHooks.php, line 119

Class

ResponsiveImageThemeHooks
Theme hooks for responsive_image.

Namespace

Drupal\responsive_image\Hook

Code

public function preprocessResponsiveImage(array &$variables) : void {
  // Make sure that width and height are proper values, if they exist we'll
  // output them.
  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']);
  }
  $responsive_image_style = ResponsiveImageStyle::load($variables['responsive_image_style_id']);
  // If a responsive image style is not selected, log the error and stop
  // execution.
  if (!$responsive_image_style) {
    $variables['img_element'] = [];
    ($this->loggerClosure)()
      ->error('Failed to load responsive image style: “@style“ while displaying responsive image.', [
      '@style' => $variables['responsive_image_style_id'],
    ]);
    return;
  }
  // Retrieve all breakpoints and multipliers and reverse order of
  // breakpoints. By default, breakpoints are ordered from smallest weight to
  // largest:
  // the smallest weight is expected to have the smallest breakpoint width,
  // while the largest weight is expected to have the largest breakpoint
  // width. For responsive images, we need largest breakpoint widths first, so
  // we need to reverse the order of these breakpoints.
  $breakpoints = array_reverse($this->breakpointManager
    ->getBreakpointsByGroup($responsive_image_style->getBreakpointGroup()));
  foreach ($responsive_image_style->getKeyedImageStyleMappings() as $breakpoint_id => $multipliers) {
    if (isset($breakpoints[$breakpoint_id])) {
      $variables['sources'][] = $this->responsiveImageBuilder
        ->buildSourceAttributes($variables, $breakpoints[$breakpoint_id], $multipliers);
    }
  }
  if (isset($variables['sources']) && count($variables['sources']) === 1 && !isset($variables['sources'][0]['media'])) {
    // There is only one source tag with an empty media attribute. This means
    // we can output an image tag with the srcset attribute instead of a
    // picture tag.
    $variables['output_image_tag'] = TRUE;
    foreach ($variables['sources'][0] as $attribute => $value) {
      if ($attribute != 'type') {
        $variables['attributes'][$attribute] = $value;
      }
    }
    $variables['img_element'] = [
      '#theme' => 'image',
      '#uri' => $this->responsiveImageBuilder
        ->getImageStyleUrl($responsive_image_style->getFallbackImageStyle(), $variables['uri']),
      '#attributes' => [],
    ];
  }
  else {
    $variables['output_image_tag'] = FALSE;
    // Prepare the fallback image. We use the src attribute, which might cause
    // double downloads in browsers that don't support the picture tag.
    $variables['img_element'] = [
      '#theme' => 'image',
      '#uri' => $this->responsiveImageBuilder
        ->getImageStyleUrl($responsive_image_style->getFallbackImageStyle(), $variables['uri']),
      '#attributes' => [],
    ];
  }
  // Get width and height from fallback responsive image style and transfer
  // them to img tag so browser can do aspect ratio calculation and prevent
  // recalculation of layout on image load.
  $dimensions = $this->responsiveImageBuilder
    ->getImageDimensions($responsive_image_style->getFallbackImageStyle(), [
    'width' => $variables['width'],
    'height' => $variables['height'],
  ], $variables['uri']);
  $variables['img_element']['#width'] = $dimensions['width'];
  $variables['img_element']['#height'] = $dimensions['height'];
  if (isset($variables['attributes'])) {
    if (isset($variables['attributes']['alt'])) {
      $variables['img_element']['#alt'] = $variables['attributes']['alt'];
      unset($variables['attributes']['alt']);
    }
    if (isset($variables['attributes']['title'])) {
      $variables['img_element']['#title'] = $variables['attributes']['title'];
      unset($variables['attributes']['title']);
    }
    if (isset($variables['img_element']['#width'])) {
      $variables['attributes']['width'] = $variables['img_element']['#width'];
    }
    if (isset($variables['img_element']['#height'])) {
      $variables['attributes']['height'] = $variables['img_element']['#height'];
    }
    $variables['img_element']['#attributes'] = $variables['attributes'];
  }
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.