diff --git a/core/modules/picture/picture.module b/core/modules/picture/picture.module index e2902ce..af76dd0 100644 --- a/core/modules/picture/picture.module +++ b/core/modules/picture/picture.module @@ -150,6 +150,7 @@ function picture_theme() { 'attributes' => array(), 'breakpoints' => array(), ), + 'template' => 'picture', ), 'picture_formatter' => array( 'variables' => array( @@ -158,20 +159,24 @@ function picture_theme() { 'image_style' => NULL, 'breakpoints' => array(), ), + 'template' => 'picture-formatter', ), 'picture_source' => array( 'variables' => array( 'src' => NULL, 'srcset' => NULL, - 'dimension' => NULL, + 'dimensions' => array(), 'media' => NULL, ), + 'template' => 'picture-source', ), ); } /** - * Returns HTML for a picture field formatter. + * Prepares variables for picture formatter templates. + * + * Default template: picture-formatter.html.twig. * * @param array $variables * An associative array containing: @@ -179,53 +184,66 @@ function picture_theme() { * - 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) { +function template_preprocess_picture_formatter(&$variables) { if (!isset($variables['breakpoints']) || empty($variables['breakpoints'])) { - return theme('image_formatter', $variables); + $variables['image'] = array( + '#theme' => 'image_formatter', + '#item' => $variables['item'], + '#image_style' => $variables['image_style'], + '#path' => $variables['path'], + ); } + else { + $item = $variables['item']; - $item = $variables['item']; + // Do not output an empty 'title' attribute. + if (isset($item['title']) && drupal_strlen($item['title']) == 0) { + unset($item['title']); + } - // Do not output an empty 'title' attribute. - if (isset($item['title']) && drupal_strlen($item['title']) == 0) { - unset($item['title']); - } - - $item['style_name'] = $variables['image_style']; - $item['breakpoints'] = $variables['breakpoints']; - - if (!isset($item['uri']) && isset($item['entity'])) { - $item['uri'] = $item['entity']->getFileUri(); - } - $output = theme('picture', $item); + if (!isset($item['uri']) && isset($item['entity'])) { + $item['uri'] = $item['entity']->getFileUri(); + } + $variables['image'] = array( + '#theme' => 'picture', + '#style_name' => $variables['image_style'], + '#path' => $item['uri'], + '#width' => $item['width'], + '#height' => $item['height'], + '#breakpoints' => $variables['breakpoints'], + '#alt' => isset($item['alt']) ? $item['alt'] : NULL, + '#title' => isset($item['title']) ? $item['title'] : NULL, + '#attributes' => isset($item['attributes']) ? $item['attributes'] : NULL, + ); - if (isset($variables['path']['path'])) { - $path = $variables['path']['path']; - $options = isset($variables['path']['options']) ? $variables['path']['options'] : array(); - $options['html'] = TRUE; - $output = l($output, $path, $options); + if (isset($variables['path']['path'])) { + $variables['path']['attributes'] = isset($variables['path']['options']['attributes']) ? new Attribute($variables['path']['options']['attributes']) : new Attribute(); + $options = isset($variables['path']['options']) ? $variables['path']['options'] : array(); + $variables['path']['path'] = url($variables['path']['path'], $options); + } } - return $output; } /** - * Returns HTML for a picture. + * Prepares variables for picture templates. + * + * Default template: picture.html.twig. * * @param $variables * An associative array containing: - * - uri: Either the path of the image file (relative to base_path()) or a + * - path: 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). + * - breakpoints: An array containing breakpoints. * - alt: The alternative text for text-based browsers. - * - breakpoints: An array containing breakpoints. - * - * @ingroup themeable + * - title: The title text is displayed when the image is hovered in some + * popular browsers. + * - attributes: Attributes for the picture element. + * - style_name: The name of the style to be used to alter the original image. */ -function theme_picture($variables) { +function template_preprocess_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/ @@ -238,13 +256,13 @@ function theme_picture($variables) { unset($variables['height']); } - $sources = array(); - $output = array(); + $variables['sources'] = array(); // Fallback image, output as source with media query. - $sources[] = array( - 'src' => image_style_url($variables['style_name'], $variables['uri']), - 'dimensions' => picture_get_image_dimensions($variables), + $variables['sources'][] = array( + '#theme' => 'picture_source', + '#src' => image_style_url($variables['style_name'], $variables['path']), + '#dimensions' => picture_get_image_dimensions($variables), ); // All breakpoints and multipliers. @@ -261,50 +279,54 @@ function theme_picture($variables) { // Only one image, use src. if (count($new_sources) == 1) { - $sources[] = array( - 'src' => image_style_url($new_sources[0]['style_name'], $new_sources[0]['uri']), - 'dimensions' => picture_get_image_dimensions($new_sources[0]), - 'media' => $breakpoint->mediaQuery, + $variables['sources'][] = array( + '#theme' => 'picture_source', + '#src' => image_style_url($new_sources[0]['style_name'], $new_sources[0]['path']), + '#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[] = image_style_url($new_source['style_name'], $new_source['uri']) . ' ' . $new_source['#multiplier']; + $srcset[] = image_style_url($new_source['style_name'], $new_source['path']) . ' ' . $new_source['#multiplier']; } - $sources[] = array( - 'srcset' => implode(', ', $srcset), - 'dimensions' => picture_get_image_dimensions($new_sources[0]), - 'media' => $breakpoint->mediaQuery, + $variables['sources'][] = array( + '#theme' => 'picture_source', + '#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]; - } + // Prepare picture tag attributes. + $attributes = array(); + foreach (array('alt', 'title') as $key) { + if (isset($variables[$key])) { + $attributes[$key] = $variables[$key]; } - $output[] = ''; - - // Add source tags to the output. - foreach ($sources as $source) { - $output[] = theme('picture_source', $source); - } - - // Output the fallback image. - $output[] = ''; - $output[] = ''; - return implode("\n", $output); } + $variables['attributes'] = new Attribute($attributes); + + // Prepare noscript fallback image. + $variables['fallback'] = array( + '#theme' => 'image_style', + '#uri' => $variables['path'], + '#width' => $variables['width'], + '#height' => $variables['height'], + '#style_name' => $variables['style_name'], + '#alt' => isset($variables['alt']) ? $variables['alt'] : NULL, + '#title' => isset($variables['title']) ? $variables['title'] : NULL, + ); } /** - * Returns HTML for a source tag. + * Prepares variables for source tag templates. + * + * Default template: picture-source.html.twig. * * @param type $variables * An associative array containing: @@ -313,27 +335,24 @@ function theme_picture($variables) { * URL and optionally multipliers. * - src: Either the path of the image file (relative to base_path()) or a * full URL. - * - dimensions: The width and height of the image (if known). - * - * @ingroup themeable + * - dimensions: An array containing the width and height of the image (if + * known). */ -function theme_picture_source($variables) { - $output = array(); - if (isset($variables['media']) && !empty($variables['media'])) { - if (!isset($variables['srcset'])) { - $output[] = ''; - $output[] = ''; +function template_preprocess_picture_source(&$variables) { + $attributes = array(); + foreach (array('media', 'src', 'srcset') as $attribute) { + if (!empty($variables[$attribute])) { + $attributes[$attribute] = $variables[$attribute]; + unset($variables[$attribute]); } - elseif (!isset($variables['src'])) { - $output[] = ''; - $output[] = ''; - } - } - else { - $output[] = ''; - $output[] = ''; } - return implode("\n", $output); + $attributes += $variables['dimensions']; + unset($variables['dimensions']); + + $variables['attributes'] = new Attribute($attributes); + // Create a duplicate attributes variable to allow printing the attributes + // twice. + $variables['attributes_copy'] = new Attribute($attributes); } /** diff --git a/core/modules/picture/templates/picture-formatter.html.twig b/core/modules/picture/templates/picture-formatter.html.twig new file mode 100644 index 0000000..6ef6288 --- /dev/null +++ b/core/modules/picture/templates/picture-formatter.html.twig @@ -0,0 +1,23 @@ +{# +/** + * @file + * Default theme implementation to display a picture field formatter. + * + * Available variables: + * - image: Picture element, if picture has breakpoint sources, otherwise img + * element. + * - path: (optional) Contains information about the link. + * - path: The URL the image links to. + * - attributes: HTML attributes for the link tag. + * + * @see template_preprocess() + * @see template_preprocess_picture_formatter() + * + * @ingroup themeable + */ +#} +{% if path %} + {{ image }} +{% else %} + {{ image }} +{% endif %} diff --git a/core/modules/picture/templates/picture-source.html.twig b/core/modules/picture/templates/picture-source.html.twig new file mode 100644 index 0000000..a0287cf --- /dev/null +++ b/core/modules/picture/templates/picture-source.html.twig @@ -0,0 +1,28 @@ +{# +/** + * @file + * Default theme implementation to display a picture source tag. + * + * Available variables: + * - attributes: HTML attributes for the source tag, including: + * - media: The media query to use. + * - width: The width of the image (if known). + * - height: The width of the image (if known). + * One of the following two attributes will also be set: + * - src: Either the path of the image file (relative to base_path()) or a + * full URL. + * - srcset: A group of image sources/resolutions used to display different + * image resolutions at different breakpoints. + * - attributes_copy: A copy of the 'attributes' variable to allow for printing + * the attributes a second time for the commented source tags. Drupal's + * Attribute object keeps track of which attributes have been printed and will + * only print an attribute once. + * + * @see template_preprocess() + * @see template_preprocess_picture_source() + * + * @ingroup themeable + */ +#} + + diff --git a/core/modules/picture/templates/picture.html.twig b/core/modules/picture/templates/picture.html.twig new file mode 100644 index 0000000..c8fff2f --- /dev/null +++ b/core/modules/picture/templates/picture.html.twig @@ -0,0 +1,24 @@ +{# +/** + * @file + * Default theme implementation to display a picture tag. + * + * Available variables: + * - sources: Source elements. + * - attributes: HTML attributes for the picture tag. + * - fallback: Fallback image tag for non-JS browsers. + * + * @see template_preprocess() + * @see template_preprocess_picture() + * + * @ingroup themeable + */ +#} +{% if sources %} + + {% for source in sources %} + {{ source }} + {% endfor %} + + +{% endif %}