' . t('About') . ''; $output .= '
' . t('The Picture module provides an image formatter and breakpoint mappings to output responsive images using the HTML5 picture tag.') . '
'; $output .= '' . t('A picture mapping associates an image style with each breakpoint defined by your theme.') . '
'; break; } return $output; } /** * Implements hook_permission(). */ function picture_permission() { return array( 'administer pictures' => array( 'title' => t('Administer Pictures'), 'description' => t('Administer Pictures'), ), ); } /** * Implements hook_menu(). */ function picture_menu() { $items = array(); $items['admin/config/media/picturemapping'] = array( 'title' => 'Picture Mappings', 'description' => 'Manage picture mappings', 'weight' => 10, 'route_name' => 'picture.mapping_page', ); $items['admin/config/media/picturemapping/%picture_mapping'] = array( 'title' => 'Edit picture mapping', 'route_name' => 'picture.mapping_page_edit', ); $items['admin/config/media/picturemapping/%picture_mapping/edit'] = array( 'title' => 'Edit', 'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10, ); $items['admin/config/media/picturemapping/%picture_mapping/duplicate'] = array( 'title' => 'Duplicate picture mapping', 'route_name' => 'picture.mapping_page_duplicate', ); return $items; } /** * Implements hook_library_info(). */ function picture_library_info() { $libraries['picturefill'] = array( 'title' => t('Picturefill'), 'website' => 'http://drupal.org/node/1775530', 'version' => \Drupal::VERSION, 'js' => array( drupal_get_path('module', 'picture') . '/picturefill/picturefill.js' => array('type' => 'file', 'weight' => -10, 'group' => JS_DEFAULT), ), 'dependencies' => array( array('system', 'matchmedia'), ), ); return $libraries; } /** * Load one picture by its identifier. * * @param int $id * The id of the picture mapping to load. * * @return \Drupal\picture\Picture * The entity object, or NULL if there is no entity with the given id. * * @todo Needed for menu_callback * * @see http://drupal.org/node/1798214 * */ function picture_mapping_load($id) { return entity_load('picture_mapping', $id); } /** * Implements hook_theme(). */ function picture_theme() { return array( 'picture' => array( 'variables' => array( 'style_name' => NULL, 'uri' => NULL, 'width' => NULL, 'height' => NULL, 'alt' => '', 'title' => NULL, 'attributes' => array(), 'breakpoints' => array(), ), ), 'picture_formatter' => array( 'variables' => array( 'item' => NULL, 'path' => NULL, 'image_style' => NULL, 'breakpoints' => array(), ), ), 'picture_source' => array( 'variables' => array( 'src' => NULL, 'srcset' => NULL, 'dimensions' => NULL, 'media' => NULL, ), ), ); } /** * Returns HTML for a picture field formatter. * * @param array $variables * An associative array containing: * - item: An array of image data. * - image_style: An optional image style. * - path: An optional array containing the link 'path' and link 'options'. * - breakpoints: An array containing breakpoints. * * @ingroup themeable */ function theme_picture_formatter($variables) { if (!isset($variables['breakpoints']) || empty($variables['breakpoints'])) { $image_formatter = array( '#theme' => 'image_formatter', '#item' => $variables['item'], '#image_style' => $variables['image_style'], '#path' => $variables['path'], ); return drupal_render($image_formatter); } $picture = array( '#theme' => 'picture', '#width' => $variables['item']['width'], '#height' => $variables['item']['height'], '#style_name' => $variables['image_style'], '#breakpoints' => $variables['breakpoints'], ); if (isset($variables['item']['uri'])) { $picture['#uri'] = $variables['item']['uri']; } elseif (isset($variables['item']['entity'])) { $picture['#uri'] = $variables['item']['entity']->getFileUri(); $picture['#entity'] = $variables['item']['entity']; } if (isset($variables['item']['alt'])) { $picture['#alt'] = $variables['item']['alt']; } if (isset($variables['item']['title']) && drupal_strlen($variables['item']['title']) != 0) { $picture['#title'] = $variables['item']['title']; } if (isset($variables['path']['path'])) { $path = $variables['path']['path']; $options = isset($variables['path']['options']) ? $variables['path']['options'] : array(); $options['html'] = TRUE; return l($picture, $path, $options); } return drupal_render($picture); } /** * Returns HTML for a picture. * * @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. * - breakpoints: An array containing breakpoints. * * @ingroup themeable */ function theme_picture($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(); $output = array(); // Fallback image, output as source with media query. $sources[] = array( 'src' => entity_load('image_style', $variables['style_name'])->buildUrl($variables['uri']), 'dimensions' => picture_get_image_dimensions($variables), ); // All breakpoints and multipliers. foreach ($variables['breakpoints'] as $breakpoint_name => $multipliers) { $breakpoint = breakpoint_load($breakpoint_name); if ($breakpoint) { $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' => entity_load('image_style', $new_sources[0]['style_name'])->buildUrl($new_sources[0]['uri']), 'dimensions' => picture_get_image_dimensions($new_sources[0]), 'media' => $breakpoint->mediaQuery, ); } else { // Multiple images, use srcset. $srcset = array(); foreach ($new_sources as $new_source) { $srcset[] = entity_load('image_style', $new_source['style_name'])->buildUrl($new_source['uri']) . ' ' . $new_source['#multiplier']; } $sources[] = array( 'srcset' => implode(', ', $srcset), 'dimensions' => picture_get_image_dimensions($new_sources[0]), 'media' => $breakpoint->mediaQuery, ); } } } if (!empty($sources)) { $attributes = array(); foreach (array('alt', 'title') as $key) { if (isset($variables[$key])) { $attributes[$key] = $variables[$key]; } } $output[] = '