diff --git a/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php b/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php
index e23dbc5..a8427b7 100644
--- a/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php
+++ b/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php
@@ -193,7 +193,7 @@ public function _testPictureFieldFormatters($scheme) {
$this->drupalGet($large_style->buildUrl($image_uri));
$image_style = array(
'#theme' => 'image_style',
- '#uri' => $image_uri,
+ '#path' => $image_uri,
'#width' => 480,
'#height' => 240,
'#style_name' => 'large',
diff --git a/core/modules/picture/picture.module b/core/modules/picture/picture.module
index a15e06a..8088cab 100644
--- a/core/modules/picture/picture.module
+++ b/core/modules/picture/picture.module
@@ -132,6 +132,7 @@ function picture_theme() {
'attributes' => array(),
'breakpoints' => array(),
),
+ 'template' => 'picture',
),
'picture_formatter' => array(
'variables' => array(
@@ -140,20 +141,24 @@ function picture_theme() {
'image_style' => NULL,
'breakpoints' => array(),
),
+ 'template' => 'picture-formatter',
),
'picture_source' => array(
'variables' => array(
'src' => NULL,
'srcset' => NULL,
- 'dimensions' => 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:
@@ -161,65 +166,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'])) {
- $image_formatter = array(
+ $variables['image'] = array(
'#theme' => 'image_formatter',
'#item' => $variables['item'],
'#image_style' => $variables['image_style'],
'#path' => $variables['path'],
);
- return drupal_render($image_formatter);
}
+ else {
+ $item = $variables['item'];
- $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);
- }
+ // Do not output an empty 'title' attribute.
+ if (isset($item['title']) && drupal_strlen($item['title']) == 0) {
+ unset($item['title']);
+ }
- return drupal_render($picture);
+ 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'])) {
+ $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);
+ }
+ }
}
/**
- * 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).
- * - alt: The alternative text for text-based browsers.
* - breakpoints: An array containing breakpoints.
- *
- * @ingroup themeable
+ * - alt: The alternative text for text-based browsers.
+ * - 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/
@@ -232,13 +238,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' => entity_load('image_style', $variables['style_name'])->buildUrl($variables['uri']),
- 'dimensions' => picture_get_image_dimensions($variables),
+ $variables['sources'][] = array(
+ '#theme' => 'picture_source',
+ '#src' => entity_load('image_style', $variables['style_name'])->buildUrl($variables['uri']),
+ '#dimensions' => picture_get_image_dimensions($variables),
);
// All breakpoints and multipliers.
@@ -255,10 +261,11 @@ function theme_picture($variables) {
// 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,
+ $variables['sources'][] = array(
+ '#theme' => 'picture_source',
+ '#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 {
@@ -267,60 +274,41 @@ function theme_picture($variables) {
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,
+ $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];
- }
- }
- $output[] = '';
- return implode("\n", $output);
}
+ $variables['attributes'] = new Attribute($attributes);
+
+ // Prepare noscript fallback image.
+ $variables['fallback'] = array(
+ '#theme' => 'image_style',
+ '#uri' => $variables['uri'],
+ '#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:
@@ -329,27 +317,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..aec0ba6
--- /dev/null
+++ b/core/modules/picture/templates/picture-formatter.html.twig
@@ -0,0 +1,22 @@
+{#
+/**
+ * @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_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..774fea1
--- /dev/null
+++ b/core/modules/picture/templates/picture-source.html.twig
@@ -0,0 +1,27 @@
+{#
+/**
+ * @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_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..b052b6c
--- /dev/null
+++ b/core/modules/picture/templates/picture.html.twig
@@ -0,0 +1,23 @@
+{#
+/**
+ * @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_picture()
+ *
+ * @ingroup themeable
+ */
+#}
+{% if sources %}
+
+{% endif %}