diff --git a/core/modules/image/image.admin.inc b/core/modules/image/image.admin.inc
index 1f43cf8..e991989 100644
--- a/core/modules/image/image.admin.inc
+++ b/core/modules/image/image.admin.inc
@@ -4,7 +4,9 @@
* @file
* Administration pages for image settings.
*/
+
use Drupal\Component\Utility\String;
+
/**
* Returns HTML for a listing of the effects within a specific image style.
*
@@ -70,113 +72,100 @@ function theme_image_style_effects($variables) {
}
/**
- * Returns HTML for a preview of an image style.
+ * Prepares variables for image style preview templates.
*
- * @param $variables
+ * Default template: image-style-preview.html.twig.
+ *
+ * @param array $variables
* An associative array containing:
* - style: \Drupal\image\ImageStyleInterface image style being previewed.
- *
- * @ingroup themeable
*/
-function theme_image_style_preview($variables) {
+function template_preprocess_image_style_preview(&$variables) {
+
+ // Style information.
$style = $variables['style'];
+ $variables['style_id'] = String::checkPlain($style->id());
+ $variables['style_name'] = String::checkPlain($style->label());
+
+ // Cache bypass token.
+ $variables['cache_bypass'] = REQUEST_TIME;
- $sample_image = \Drupal::config('image.settings')->get('preview_image');
+ // Sample image info.
$sample_width = 160;
$sample_height = 160;
+ $image_factory = \Drupal::service('image.factory');
// Set up original file information.
- $original_path = $sample_image;
- $image_factory = \Drupal::service('image.factory');
+ $original_path = \Drupal::config('image.settings')->get('preview_image');
$original_image = $image_factory->get($original_path);
- $original_image = array(
+ $variables['original_url'] = file_create_url($original_path);
+ $variables['original'] = array(
'width' => $original_image->getWidth(),
'height' => $original_image->getHeight(),
);
- if ($original_image['width'] > $original_image['height']) {
- $original_width = min($original_image['width'], $sample_width);
- $original_height = round($original_width / $original_image['width'] * $original_image['height']);
+ if ($original_image->getWidth() > $original_image->getHeight()) {
+ $variables['preview']['original']['width'] = min($original_image->getWidth(), $sample_width);
+ $variables['preview']['original']['height'] = round($variables['preview']['original']['width'] / $original_image->getWidth() * $original_image->getHeight());
}
else {
- $original_height = min($original_image['height'], $sample_height);
- $original_width = round($original_height / $original_image['height'] * $original_image['width']);
+ $variables['preview']['original']['height'] = min($original_image->getHeight(), $sample_height);
+ $variables['preview']['original']['width'] = round($variables['preview']['original']['height'] / $original_image->getHeight() * $original_image->getWidth());
}
- $original_image['style'] = 'width: ' . $original_width . 'px; height: ' . $original_height . 'px;';
+ $variables['original']['style'] = 'width: ' . $variables['preview']['original']['width'] . 'px; height: ' . $variables['preview']['original']['height'] . 'px;';
// Set up preview file information.
$preview_file = $style->buildUri($original_path);
+ // Create derivative if necessary.
if (!file_exists($preview_file)) {
$style->createDerivative($original_path, $preview_file);
}
$preview_image = $image_factory->get($preview_file);
- $preview_image = array(
+ $variables['derivative_url'] = file_create_url($preview_file);
+ $variables['derivative'] = array(
'width' => $preview_image->getWidth(),
'height' => $preview_image->getHeight(),
);
- if ($preview_image['width'] > $preview_image['height']) {
- $preview_width = min($preview_image['width'], $sample_width);
- $preview_height = round($preview_width / $preview_image['width'] * $preview_image['height']);
+ if ($preview_image->getWidth() > $preview_image->getHeight()) {
+ $variables['preview']['derivative']['width'] = min($preview_image->getWidth(), $sample_width);
+ $variables['preview']['derivative']['height'] = round($variables['preview']['derivative']['width'] / $preview_image->getWidth() * $preview_image->getHeight());
}
else {
- $preview_height = min($preview_image['height'], $sample_height);
- $preview_width = round($preview_height / $preview_image['height'] * $preview_image['width']);
+ $variables['preview']['derivative']['height'] = min($preview_image->getHeight(), $sample_height);
+ $variables['preview']['derivative']['width'] = round($variables['preview']['derivative']['height'] / $preview_image->getHeight() * $preview_image->getWidth());
}
- $preview_image['style'] = 'width: ' . $preview_width . 'px; height: ' . $preview_height . 'px;';
-
- // In the previews, timestamps are added to prevent caching of images.
- $output = '
';
+ $variables['derivative']['style'] = 'width: ' . $variables['preview']['derivative']['width'] . 'px; height: ' . $variables['preview']['derivative']['height'] . 'px;';
// Build the preview of the original image.
- $original_url = file_create_url($original_path);
- $image = array(
+ $variables['original']['rendered'] = array(
'#theme' => 'image',
'#uri' => $original_path,
'#alt' => t('Sample original image'),
'#title' => '',
- '#attributes' => $original_image,
+ '#attributes' => $variables['original'],
);
- $output .= '
';
- $output .= t('original') . ' (' . l(t('view actual size'), $original_url) . ')';
- $output .= '
';
- $output .= '
' . drupal_render($image) . '';
- $output .= '
' . $original_image['height'] . 'px
';
- $output .= '
' . $original_image['width'] . 'px
';
- $output .= '
'; // End preview-image.
- $output .= '
'; // End preview-image-wrapper.
+ // In the preview, timestamps are added to prevent caching of images.
// Build the preview of the image style.
- $preview_url = file_create_url($preview_file) . '?cache_bypass=' . REQUEST_TIME;
- $image = array(
+ $variables['derivative']['rendered'] = array(
'#theme' => 'image',
- '#uri' => $preview_url,
+ '#uri' => $variables['derivative_url'] . '?cache_bypass=' . $variables['cache_bypass'],
'#alt' => t('Sample modified image'),
'#title' => '',
- '#attributes' => $preview_image,
+ '#attributes' => $variables['derivative'],
);
- $output .= '
';
- $output .= String::checkPlain($style->label()) . ' (' . l(t('view actual size'), file_create_url($preview_file) . '?' . time()) . ')';
- $output .= '
';
- $output .= '
' . drupal_render($image) . '';
- $output .= '
' . $preview_image['height'] . 'px
';
- $output .= '
' . $preview_image['width'] . 'px
';
- $output .= '
'; // End preview-image.
- $output .= '
'; // End preview-image-wrapper.
-
- $output .= '
'; // End image-style-preview.
- return $output;
}
/**
- * Returns HTML for a 3x3 grid of checkboxes for image anchors.
+ * Prepares variables for image anchor templates.
*
- * @param $variables
- * An associative array containing:
- * - element: A render element containing radio buttons.
+ * Default template: image-anchor.html.twig.
*
- * @ingroup themeable
+ * @param array $variables
+ * An associative array containing:
+ * - element: An associative array containing the image.
*/
-function theme_image_anchor($variables) {
+function template_preprocess_image_anchor(&$variables) {
$element = $variables['element'];
$rows = array();
@@ -184,86 +173,21 @@ function theme_image_anchor($variables) {
foreach (element_children($element) as $n => $key) {
$element[$key]['#attributes']['title'] = $element[$key]['#title'];
unset($element[$key]['#title']);
- $row[] = drupal_render($element[$key]);
+ $row[] = array(
+ 'data' => $element[$key],
+ );
if ($n % 3 == 3 - 1) {
$rows[] = $row;
$row = array();
}
}
- $table = array(
+ $variables['table'] = array(
'#type' => 'table',
'#header' => array(),
'#rows' => $rows,
- '#attributes' => array('class' => array('image-anchor')),
- );
- return drupal_render($table);
-}
-
-/**
- * Returns HTML for a summary of an image resize effect.
- *
- * @param $variables
- * An associative array containing:
- * - data: The current configuration for this resize effect.
- *
- * @ingroup themeable
- */
-function theme_image_resize_summary($variables) {
- $data = $variables['data'];
-
- if ($data['width'] && $data['height']) {
- return String::checkPlain($data['width']) . 'x' . String::checkPlain($data['height']);
- }
- else {
- return ($data['width']) ? t('width @width', array('@width' => $data['width'])) : t('height @height', array('@height' => $data['height']));
- }
-}
-
-/**
- * Returns HTML for a summary of an image scale effect.
- *
- * @param $variables
- * An associative array containing:
- * - data: The current configuration for this scale effect.
- *
- * @ingroup themeable
- */
-function theme_image_scale_summary($variables) {
- $image_resize_summary = array(
- '#theme' => 'image_resize_summary',
- '#data' => $variables['data'],
- );
- return drupal_render($image_resize_summary) . ' ' . ($variables['data']['upscale'] ? '(' . t('upscaling allowed') . ')' : '');
-}
-
-/**
- * Returns HTML for a summary of an image crop effect.
- *
- * @param $variables
- * An associative array containing:
- * - data: The current configuration for this crop effect.
- *
- * @ingroup themeable
- */
-function theme_image_crop_summary($variables) {
- $image_resize_summary = array(
- '#theme' => 'image_resize_summary',
- '#data' => $variables['data'],
+ '#attributes' => array(
+ 'class' => array('image-anchor'),
+ ),
);
- return drupal_render($image_resize_summary);
-}
-
-/**
- * Returns HTML for a summary of an image rotate effect.
- *
- * @param $variables
- * An associative array containing:
- * - data: The current configuration for this rotate effect.
- *
- * @ingroup themeable
- */
-function theme_image_rotate_summary($variables) {
- $data = $variables['data'];
- return ($data['random']) ? t('random between -@degrees° and @degrees°', array('@degrees' => str_replace('-', '', $data['degrees']))) : t('@degrees°', array('@degrees' => $data['degrees']));
}
diff --git a/core/modules/image/image.field.inc b/core/modules/image/image.field.inc
index 5462520..9ffb179 100644
--- a/core/modules/image/image.field.inc
+++ b/core/modules/image/image.field.inc
@@ -8,39 +8,35 @@
use Drupal\Component\Utility\NestedArray;
/**
- * Returns HTML for an image field widget.
+ * Prepares variables for image widget templates.
+ *
+ * Default template: image-widget.html.twig.
*
* @param array $variables
* An associative array containing:
* - element: A render element representing the image field widget.
- *
- * @ingroup themeable
*/
-function theme_image_widget($variables) {
+function template_preprocess_image_widget(&$variables) {
$element = $variables['element'];
- $output = '';
- $output .= '';
- return $output;
+ $variables['data'] = $element;
+ $variables['attributes'] = $element['#attributes'];
}
/**
- * Returns HTML for an image field formatter.
+ * Prepares variables for image formatter templates.
+ *
+ * Default template: image-formatter.html.twig.
*
* @param array $variables
* An associative array containing:
@@ -52,51 +48,45 @@ function theme_image_widget($variables) {
*
* @ingroup themeable
*/
-function theme_image_formatter($variables) {
+function template_preprocess_image_formatter(&$variables) {
if ($variables['image_style']) {
- $image = array(
+ $variables['image'] = array(
'#theme' => 'image_style',
'#style_name' => $variables['image_style'],
);
}
else {
- $image = array(
+ $variables['image'] = array(
'#theme' => 'image',
);
}
- $image['#attributes'] = $variables['item_attributes'];
+ $variables['image']['#attributes'] = $variables['item_attributes'];
$item = $variables['item'];
// Do not output an empty 'title' attribute.
if (drupal_strlen($item->title) != 0) {
- $image['#title'] = $item->title;
+ $variables['image']['#title'] = $item->title;
}
if (($entity = $item->entity) && empty($item->uri)) {
- $image['#uri'] = $entity->getFileUri();
+ $variables['image']['#uri'] = $entity->getFileUri();
}
else {
- $image['#uri'] = $item->uri;
+ $variables['image']['#uri'] = $item->uri;
}
foreach (array('width', 'height', 'alt') as $key) {
- $image["#$key"] = $item->$key;
+ $variables['image']["#$key"] = $item->$key;
}
// The link path and link options are both optional, but for the options to be
// processed, the link path must at least be an empty string.
// @todo Add support for route names.
+ $variables['url'] = NULL;
if (isset($variables['path']['path'])) {
$path = $variables['path']['path'];
$options = isset($variables['path']['options']) ? $variables['path']['options'] : array();
- // When displaying an image inside a link, the html option must be TRUE.
- $options['html'] = TRUE;
- $output = l($image, $path, $options);
+ $variables['url'] = url($path, $options);
}
- else {
- $output = drupal_render($image);
- }
-
- return $output;
}
diff --git a/core/modules/image/image.module b/core/modules/image/image.module
index 472cad4..7dfeb72 100644
--- a/core/modules/image/image.module
+++ b/core/modules/image/image.module
@@ -125,6 +125,7 @@ function image_theme() {
'title' => NULL,
'attributes' => array(),
),
+ 'template' => 'image-style',
),
// Theme functions in image.admin.inc.
@@ -135,36 +136,40 @@ function image_theme() {
'image_style_preview' => array(
'variables' => array('style' => NULL),
'file' => 'image.admin.inc',
+ 'template' => 'image-style-preview',
),
'image_anchor' => array(
'render element' => 'element',
'file' => 'image.admin.inc',
+ 'template' => 'image-anchor',
),
'image_resize_summary' => array(
- 'variables' => array('data' => NULL),
- 'file' => 'image.admin.inc',
+ 'variables' => array('data' => NULL, 'effect' => array()),
+ 'template' => 'image-resize-summary',
),
'image_scale_summary' => array(
- 'variables' => array('data' => NULL),
- 'file' => 'image.admin.inc',
+ 'variables' => array('data' => NULL, 'effect' => array()),
+ 'template' => 'image-scale-summary',
),
'image_crop_summary' => array(
- 'variables' => array('data' => NULL),
- 'file' => 'image.admin.inc',
+ 'variables' => array('data' => NULL, 'effect' => array()),
+ 'template' => 'image-crop-summary',
),
'image_rotate_summary' => array(
- 'variables' => array('data' => NULL),
- 'file' => 'image.admin.inc',
+ 'variables' => array('data' => NULL, 'effect' => array()),
+ 'template' => 'image-rotate-summary',
),
// Theme functions in image.field.inc.
'image_widget' => array(
'render element' => 'element',
'file' => 'image.field.inc',
+ 'template' => 'image-widget',
),
'image_formatter' => array(
'variables' => array('item' => NULL, 'item_attributes' => NULL, 'path' => NULL, 'image_style' => NULL),
'file' => 'image.field.inc',
+ 'template' => 'image-formatter',
),
);
}
@@ -295,18 +300,17 @@ function image_style_options($include_empty = TRUE) {
}
/**
- * Returns HTML for an image using a specific image style.
+ * Prepares variables for image style templates.
+ *
+ * Default template: image-style.html.twig.
*
- * @param $variables
+ * @param array $variables
* An associative array containing:
- * - style_name: The name of the style to be used to alter the original image.
- * - uri: The path of the image file relative to the Drupal files directory.
- * This function does not work with images outside the files directory nor
- * with remotely hosted images. This should be in a format such as
- * 'images/image.jpg', or using a stream wrapper such as
- * 'public://images/image.jpg'.
- * - width: The width of the source image (if known).
- * - height: The height of the source image (if known).
+ * - width: The width of the image.
+ * - height: The height of the image.
+ * - style_name: The name of the image style to be applied.
+ * - attributes: Additional attributes to apply to the image.
+ * - uri: URI of the source image before styling.
* - alt: The alternative text for text-based browsers. HTML 4 and XHTML 1.0
* always require an alt attribute. The HTML 5 draft allows the alt
* attribute to be omitted in some cases. Therefore, this variable defaults
@@ -320,12 +324,8 @@ function image_style_options($include_empty = TRUE) {
* - title: The title text is displayed when the image is hovered in some
* popular browsers.
* - attributes: Associative array of attributes to be placed in the img tag.
- *
- * @ingroup themeable
*/
-function theme_image_style($variables) {
- // @todo Image style loading will be moved outside theme in
- // https://drupal.org/node/2029649
+function template_preprocess_image_style(&$variables) {
$style = entity_load('image_style', $variables['style_name']);
// Determine the dimensions of the styled image.
@@ -333,28 +333,21 @@ function theme_image_style($variables) {
'width' => $variables['width'],
'height' => $variables['height'],
);
-
$style->transformDimensions($dimensions);
// Add in the image style name as an HTML class.
$variables['attributes']['class'][] = 'image-style-' . drupal_html_class($variables['style_name']);
- $image = array(
+ $variables['image'] = array(
'#theme' => 'image',
'#width' => $dimensions['width'],
'#height' => $dimensions['height'],
'#attributes' => $variables['attributes'],
'#uri' => $style->buildUrl($variables['uri']),
+ '#alt' => isset($variables['alt']) ? $variables['alt'] : NULL,
+ '#title' => isset($variables['title']) ? $variables['title'] : NULL,
+ '#style' => $style,
);
-
- if (isset($variables['alt']) || array_key_exists('alt', $variables)) {
- $image['#alt'] = $variables['alt'];
- }
- if (isset($variables['title']) || array_key_exists('title', $variables)) {
- $image['#title'] = $variables['title'];
- }
-
- return drupal_render($image);
}
/**
diff --git a/core/modules/image/lib/Drupal/image/ImageEffectBase.php b/core/modules/image/lib/Drupal/image/ImageEffectBase.php
index e915206..76e85ce 100644
--- a/core/modules/image/lib/Drupal/image/ImageEffectBase.php
+++ b/core/modules/image/lib/Drupal/image/ImageEffectBase.php
@@ -50,6 +50,11 @@ public function transformDimensions(array &$dimensions) {
public function getSummary() {
return array(
'#markup' => '',
+ '#effect' => array(
+ 'id' => $this->pluginDefinition['id'],
+ 'label' => $this->label(),
+ 'description' => $this->pluginDefinition['description'],
+ ),
);
}
diff --git a/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/CropImageEffect.php b/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/CropImageEffect.php
index 8b1857b..efb4f1c 100644
--- a/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/CropImageEffect.php
+++ b/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/CropImageEffect.php
@@ -38,10 +38,13 @@ public function applyEffect(ImageInterface $image) {
* {@inheritdoc}
*/
public function getSummary() {
- return array(
+ $summary = array(
'#theme' => 'image_crop_summary',
'#data' => $this->configuration,
);
+ $summary += parent::getSummary();
+
+ return $summary;
}
/**
diff --git a/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/ResizeImageEffect.php b/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/ResizeImageEffect.php
index da9b176..b184705 100644
--- a/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/ResizeImageEffect.php
+++ b/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/ResizeImageEffect.php
@@ -46,10 +46,14 @@ public function transformDimensions(array &$dimensions) {
* {@inheritdoc}
*/
public function getSummary() {
- return array(
+ $summary = parent::getSummary();
+ unset($summary['#markup']);
+ $summary += array(
'#theme' => 'image_resize_summary',
'#data' => $this->configuration,
);
+
+ return $summary;
}
/**
diff --git a/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/RotateImageEffect.php b/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/RotateImageEffect.php
index b0e6bf3..65ee957 100644
--- a/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/RotateImageEffect.php
+++ b/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/RotateImageEffect.php
@@ -74,10 +74,13 @@ public function transformDimensions(array &$dimensions) {
* {@inheritdoc}
*/
public function getSummary() {
- return array(
+ $summary = array(
'#theme' => 'image_rotate_summary',
'#data' => $this->configuration,
);
+ $summary += parent::getSummary();
+
+ return $summary;
}
/**
diff --git a/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/ScaleImageEffect.php b/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/ScaleImageEffect.php
index 4316bd0..62d92a0 100644
--- a/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/ScaleImageEffect.php
+++ b/core/modules/image/lib/Drupal/image/Plugin/ImageEffect/ScaleImageEffect.php
@@ -45,10 +45,13 @@ public function transformDimensions(array &$dimensions) {
* {@inheritdoc}
*/
public function getSummary() {
- return array(
+ $summary = array(
'#theme' => 'image_scale_summary',
'#data' => $this->configuration,
);
+ $summary += parent::getSummary();
+
+ return $summary;
}
/**
diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageDimensionsTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageDimensionsTest.php
index 04c6303..f609590 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageDimensionsTest.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageDimensionsTest.php
@@ -34,7 +34,7 @@ public static function getInfo() {
/**
* Test styled image dimensions cumulatively.
*/
- function testImageDimensions() {
+ public function testImageDimensions() {
$image_factory = $this->container->get('image.factory');
// Create a working copy of the file.
$files = $this->drupalGetTestFiles('image');
@@ -48,15 +48,16 @@ function testImageDimensions() {
$url = $style->buildUrl($original_uri);
$variables = array(
- 'style_name' => 'test',
- 'uri' => $original_uri,
- 'width' => 40,
- 'height' => 20,
+ '#theme' => 'image_style',
+ '#style_name' => 'test',
+ '#uri' => $original_uri,
+ '#width' => 40,
+ '#height' => 20,
);
// Verify that the original image matches the hard-coded values.
$image_file = $image_factory->get($original_uri);
- $this->assertEqual($image_file->getWidth(), $variables['width']);
- $this->assertEqual($image_file->getHeight(), $variables['height']);
+ $this->assertEqual($image_file->getWidth(), $variables['#width']);
+ $this->assertEqual($image_file->getHeight(), $variables['#height']);
// Scale an image that is wider than it is high.
$effect = array(
@@ -70,8 +71,7 @@ function testImageDimensions() {
);
$style->saveImageEffect($effect);
- $img_tag = theme_image_style($variables);
- $this->assertEqual($img_tag, '' . "\n");
+ $this->assertEqual($this->getImageTag($variables), '');
$this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.');
$this->drupalGet($url);
$this->assertResponse(200, 'Image was generated at the URL.');
@@ -91,8 +91,7 @@ function testImageDimensions() {
);
$style->saveImageEffect($effect);
- $img_tag = theme_image_style($variables);
- $this->assertEqual($img_tag, '' . "\n");
+ $this->assertEqual($this->getImageTag($variables), '');
$this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.');
$this->drupalGet($url);
$this->assertResponse(200, 'Image was generated at the URL.');
@@ -113,8 +112,7 @@ function testImageDimensions() {
);
$style->saveImageEffect($effect);
- $img_tag = theme_image_style($variables);
- $this->assertEqual($img_tag, '' . "\n");
+ $this->assertEqual($this->getImageTag($variables), '');
$this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.');
$this->drupalGet($url);
$this->assertResponse(200, 'Image was generated at the URL.');
@@ -135,8 +133,7 @@ function testImageDimensions() {
);
$style->saveImageEffect($effect);
- $img_tag = theme_image_style($variables);
- $this->assertEqual($img_tag, '' . "\n");
+ $this->assertEqual($this->getImageTag($variables), '');
$this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.');
$this->drupalGet($url);
$this->assertResponse(200, 'Image was generated at the URL.');
@@ -153,8 +150,7 @@ function testImageDimensions() {
);
$style->saveImageEffect($effect);
- $img_tag = theme_image_style($variables);
- $this->assertEqual($img_tag, '' . "\n");
+ $this->assertEqual($this->getImageTag($variables), '');
$this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.');
$this->drupalGet($url);
$this->assertResponse(200, 'Image was generated at the URL.');
@@ -174,8 +170,7 @@ function testImageDimensions() {
);
$style->saveImageEffect($effect);
- $img_tag = theme_image_style($variables);
- $this->assertEqual($img_tag, '' . "\n");
+ $this->assertEqual($this->getImageTag($variables), '');
$this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.');
$this->drupalGet($url);
$this->assertResponse(200, 'Image was generated at the URL.');
@@ -194,8 +189,7 @@ function testImageDimensions() {
);
$style->saveImageEffect($effect);
- $img_tag = theme_image_style($variables);
- $this->assertEqual($img_tag, '' . "\n");
+ $this->assertEqual($this->getImageTag($variables), '');
$this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.');
$this->drupalGet($url);
$this->assertResponse(200, 'Image was generated at the URL.');
@@ -215,8 +209,7 @@ function testImageDimensions() {
);
$effect_id = $style->saveImageEffect($effect);
- $img_tag = theme_image_style($variables);
- $this->assertEqual($img_tag, '' . "\n");
+ $this->assertEqual($this->getImageTag($variables), '');
$this->assertFalse(file_exists($generated_uri), 'Generated file does not exist.');
$this->drupalGet($url);
$this->assertResponse(200, 'Image was generated at the URL.');
@@ -234,7 +227,20 @@ function testImageDimensions() {
);
$style->saveImageEffect($effect);
- $img_tag = theme_image_style($variables);
- $this->assertEqual($img_tag, '' . "\n");
+ $this->assertEqual($this->getImageTag($variables), '');
}
+
+ /**
+ * Render an image style element.
+ *
+ * drupal_render() alters the passed $variables array by adding a new key
+ * '#printed' => TRUE. This prevents next call to re-render the element. We
+ * wrap drupal_render() in a helper protected method and pass each time a
+ * fresh array so that $variables won't get altered and the element is
+ * re-rendered each time.
+ */
+ protected function getImageTag($variables) {
+ return drupal_render($variables);
+ }
+
}
diff --git a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
index c8f205f..5f4efe0 100644
--- a/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
@@ -65,7 +65,7 @@ function _testImageFieldFormatters($scheme) {
'#width' => 40,
'#height' => 20,
);
- $default_output = drupal_render($image);
+ $default_output = str_replace("\n", NULL, drupal_render($image));
$this->assertRaw($default_output, 'Default formatter displaying correctly on full node view.');
// Test the image linked to file formatter.
@@ -84,6 +84,7 @@ function _testImageFieldFormatters($scheme) {
'#height' => 20,
);
$default_output = l($image, file_create_url($image_uri), array('html' => TRUE));
+ $default_output = str_replace("\n", NULL, $default_output);
$this->drupalGet('node/' . $nid);
$this->assertRaw($default_output, 'Image linked to file formatter displaying correctly on full node view.');
// Verify that the image can be downloaded.
@@ -113,9 +114,17 @@ function _testImageFieldFormatters($scheme) {
'#width' => 40,
'#height' => 20,
);
- $default_output = l($image, 'node/' . $nid, array('html' => TRUE));
$this->drupalGet('node/' . $nid);
- $this->assertRaw($default_output, 'Image linked to content formatter displaying correctly on full node view.');
+ $elements = $this->xpath(
+ '//a[@href=:path]/img[@src=:url and @alt="" and @width=:width and @height=:height]',
+ array(
+ ':path' => url('node/' . $nid),
+ ':url' => file_create_url($image['#uri']),
+ ':width' => $image['#width'],
+ ':height' => $image['#height'],
+ )
+ );
+ $this->assertEqual(count($elements), 1, 'Image linked to content formatter displaying correctly on full node view.');
// Test the image style 'thumbnail' formatter.
$display_options['settings']['image_link'] = '';
@@ -204,7 +213,7 @@ function testImageFieldSettings() {
$field_name . '[0][title]' => $image['#title'],
);
$this->drupalPostForm('node/' . $nid . '/edit', $edit, t('Save and keep published'));
- $default_output = drupal_render($image);
+ $default_output = str_replace("\n", NULL, drupal_render($image));
$this->assertRaw($default_output, 'Image displayed using user supplied alt and title attributes.');
// Verify that alt/title longer than allowed results in a validation error.
@@ -278,7 +287,7 @@ function testImageFieldDefaultImage() {
'#width' => 40,
'#height' => 20,
);
- $default_output = drupal_render($image);
+ $default_output = str_replace("\n", NULL, drupal_render($image));
$this->drupalGet('node/' . $node->id());
$this->assertRaw($default_output, 'Default image displayed when no user supplied image is present.');
@@ -292,7 +301,7 @@ function testImageFieldDefaultImage() {
'#width' => 40,
'#height' => 20,
);
- $image_output = drupal_render($image);
+ $image_output = str_replace("\n", NULL, drupal_render($image));
$this->drupalGet('node/' . $nid);
$this->assertNoRaw($default_output, 'Default image is not displayed when user supplied image is present.');
$this->assertRaw($image_output, 'User supplied image is displayed.');
@@ -337,7 +346,7 @@ function testImageFieldDefaultImage() {
'#width' => 40,
'#height' => 20,
);
- $default_output = drupal_render($image);
+ $default_output = str_replace("\n", NULL, drupal_render($image));
$this->drupalGet('node/' . $node->id());
$this->assertRaw($default_output, 'Default private image displayed when no user supplied image is present.');
}
diff --git a/core/modules/image/templates/image-anchor.html.twig b/core/modules/image/templates/image-anchor.html.twig
new file mode 100644
index 0000000..eb670a4
--- /dev/null
+++ b/core/modules/image/templates/image-anchor.html.twig
@@ -0,0 +1,14 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a 3x3 grid of checkboxes for image anchors.
+ *
+ * Available variables:
+ * - table: HTML for the table of image anchors.
+ *
+ * @see template_preprocess_image_anchor()
+ *
+ * @ingroup themeable
+ */
+#}
+{{ table }}
diff --git a/core/modules/image/templates/image-crop-summary.html.twig b/core/modules/image/templates/image-crop-summary.html.twig
new file mode 100644
index 0000000..39585b3
--- /dev/null
+++ b/core/modules/image/templates/image-crop-summary.html.twig
@@ -0,0 +1,22 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a summary of an image crop effect.
+ *
+ * Available variables:
+ * - data: The current configuration for this resize effect, including:
+ * - width: The width of the resized image.
+ * - height: The height of the resized image.
+ * - anchor: The part of the image that will be retained after cropping.
+ * - anchor_label: The translated label of the crop anchor.
+ * - effect: The effect information, including:
+ * - id: The effect identifier.
+ * - label: The effect name.
+ * - description: The effect description.
+ *
+ * @ingroup themeable
+ */
+#}
+{% spaceless %}
+ {{ data.width }}x{{ data.height }}
+{% endspaceless %}
diff --git a/core/modules/image/templates/image-formatter.html.twig b/core/modules/image/templates/image-formatter.html.twig
new file mode 100644
index 0000000..c573daf
--- /dev/null
+++ b/core/modules/image/templates/image-formatter.html.twig
@@ -0,0 +1,23 @@
+{#
+/**
+ * @file
+ * Default theme implementation to display a formatted image field.
+ *
+ * Available variables:
+ * - image: A collection of image data.
+ * - image_style: An optional image style.
+ * - path: An optional array containing the link 'path' and link 'options'.
+ * - url: An optional URL the image can be linked to.
+ *
+ * @see template_preprocess_image_formatter()
+ *
+ * @ingroup themeable
+ */
+#}
+{% spaceless %}
+ {% if url %}
+ {{ image }}
+ {% else %}
+ {{ image }}
+ {% endif %}
+{% endspaceless %}
diff --git a/core/modules/image/templates/image-resize-summary.html.twig b/core/modules/image/templates/image-resize-summary.html.twig
new file mode 100644
index 0000000..cc502c5
--- /dev/null
+++ b/core/modules/image/templates/image-resize-summary.html.twig
@@ -0,0 +1,18 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a summary of an image resize effect.
+ *
+ * Available variables:
+ * - data: The current configuration for this resize effect, including:
+ * - width: The width of the resized image.
+ * - height: The height of the resized image.
+ * - effect: The effect information, including:
+ * - id: The effect identifier.
+ * - label: The effect name.
+ * - description: The effect description.
+ *
+ * @ingroup themeable
+ */
+#}
+{{ data.width }}x{{ data.height }}
diff --git a/core/modules/image/templates/image-rotate-summary.html.twig b/core/modules/image/templates/image-rotate-summary.html.twig
new file mode 100644
index 0000000..913728a
--- /dev/null
+++ b/core/modules/image/templates/image-rotate-summary.html.twig
@@ -0,0 +1,29 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a summary of an image rotate effect.
+ *
+ * Available variables:
+ * - data: The current configuration for this resize effect, including:
+ * - degrees: Degrees to rotate the image, positive values will rotate the
+ * image clockwise, negative values counter-clockwise.
+ * - bgcolor: The hex background color of the new areas created as consequence
+ * of rotation.
+ * - random: If the rotation angle is randomized.
+ * - effect: The effect information, including:
+ * - id: The effect identifier.
+ * - label: The effect name.
+ * - description: The effect description.
+ *
+ * @ingroup themeable
+ */
+#}
+{% spaceless %}
+ {% if data.random %}
+ {% trans %}
+ random between -{{ data.degrees|abs }}° and {{ data.degrees|abs }}°
+ {% endtrans %}
+ {% else %}
+ {{ data.degrees }}°
+ {% endif %}
+{% endspaceless %}
diff --git a/core/modules/image/templates/image-scale-summary.html.twig b/core/modules/image/templates/image-scale-summary.html.twig
new file mode 100644
index 0000000..cd3cfbb
--- /dev/null
+++ b/core/modules/image/templates/image-scale-summary.html.twig
@@ -0,0 +1,39 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a summary of an image scale effect.
+ *
+ * Available variables:
+ * - data: The current configuration for this resize effect, including:
+ * - width: The width of the resized image.
+ * - height: The height of the resized image.
+ * - upscale: If images larger than their original size can scale.
+ * - effect: The effect information, including:
+ * - id: The effect identifier.
+ * - label: The effect name.
+ * - description: The effect description.
+ *
+ * @ingroup themeable
+ */
+#}
+{% spaceless %}
+ {% if data.width and data.height %}
+ {{ data.width }}x{{ data.height }}
+ {% else %}
+ {% if data.width %}
+ {% trans %}
+ width {{ data.width }}
+ {% endtrans %}
+ {% elseif data.height %}
+ {% trans %}
+ height {{ data.height }}
+ {% endtrans %}
+ {% endif %}
+ {% endif %}
+
+ {% if data.upscale %}
+ {% trans %}
+ (upscaling allowed)
+ {% endtrans %}
+ {% endif %}
+{% endspaceless %}
diff --git a/core/modules/image/templates/image-style-preview.html.twig b/core/modules/image/templates/image-style-preview.html.twig
new file mode 100644
index 0000000..59b83dd
--- /dev/null
+++ b/core/modules/image/templates/image-style-preview.html.twig
@@ -0,0 +1,57 @@
+{#
+/**
+ * @file
+ * Default theme implementation to display a preview of an image style.
+ *
+ * Available variables:
+ * - style_id: The ID of the image style.
+ * - style_name: The name of the image style.
+ * - cache_bypass: A timestamp token used to avoid browser caching of images.
+ * - original_url: The URL of the original image.
+ * - original: An associative array containing:
+ * - width: The width in pixels of the original image.
+ * - height: The height in pixels of the original image.
+ * - rendered: The render array for the original image.
+ * - derivative_url: The URL of the derivative image.
+ * - derivative: An associative array containing:
+ * - width: The width in pixels of the derivative image.
+ * - height: The height in pixels of the derivative image.
+ * - rendered: The rendered derivative image.
+ * - preview: An associative array containing:
+ * - original: An associative array containing:
+ * - width: The width in pixels of the original image in the preview.
+ * - height: The height in pixels of the original image in the preview.
+ * - derivative: An associative array containing:
+ * - width: The width in pixels of the derivative image in the preview.
+ * - height: The height in pixels of the derivative image in the preview.
+ *
+ * @see template_preprocess_image_style_preview()
+ *
+ * @ingroup themeable
+ */
+#}
+
+ {# Preview of the original image. #}
+
{# End preview-image-wrapper. #}
+
+ {# Derivative of the image style. #}
+
{# End preview-image-wrapper. #}
+
diff --git a/core/modules/image/templates/image-style.html.twig b/core/modules/image/templates/image-style.html.twig
new file mode 100644
index 0000000..6b52839
--- /dev/null
+++ b/core/modules/image/templates/image-style.html.twig
@@ -0,0 +1,29 @@
+{#
+/**
+ * @file
+ * Default theme implementation for an image using a specific image style.
+ *
+ * Available variables:
+ * - attributes: HTML attributes for the image, including the following:
+ * - src: Full URL or relative path to the image file.
+ * - class: One or more classes to be applied to the image.
+ * - width: The width of the image (if known).
+ * - height: The height of the image (if known).
+ * - title: The title of the image.
+ * - alt: The alternate text for the image. HTML 4 and XHTML 1.0 always
+ * require an alt attribute. The HTML 5 draft allows the alt attribute to be
+ * omitted in some cases. Therefore, this variable defaults to an empty
+ * string, but can be set to NULL for the attribute to be omitted. Usually,
+ * neither omission nor an empty string satisfies accessibility
+ * requirements, so it is strongly encouraged for code calling
+ * theme('image') to pass a meaningful value for this variable.
+ *
+ * @see template_preprocess_image_style()
+ * @see http://www.w3.org/TR/REC-html40/struct/objects.html#h-13.8
+ * @see http://www.w3.org/TR/xhtml1/dtds.html
+ * @see http://dev.w3.org/html5/spec/Overview.html#alt
+ *
+ * @ingroup themeable
+ */
+#}
+{% spaceless %}{{ image }}{% endspaceless %}
diff --git a/core/modules/image/templates/image-widget.html.twig b/core/modules/image/templates/image-widget.html.twig
new file mode 100644
index 0000000..43faffc
--- /dev/null
+++ b/core/modules/image/templates/image-widget.html.twig
@@ -0,0 +1,25 @@
+{#
+/**
+ * @file
+ * Default theme implementation for an image field widget.
+ *
+ * Available variables:
+ * - attributes: HTML attributes for the containing element.
+ * - preview: A rendered preview image.
+ * - data: Render elements of image data.
+ *
+ * @see template_preprocess_image_widget()
+ *
+ * @ingroup themeable
+ */
+#}
+
+ {% if preview is defined %}
+
+ {{ preview }}
+
+ {% endif %}
+
+ {{ data }}
+
+
diff --git a/core/modules/responsive_image/lib/Drupal/responsive_image/Tests/ResponsiveImageFieldDisplayTest.php b/core/modules/responsive_image/lib/Drupal/responsive_image/Tests/ResponsiveImageFieldDisplayTest.php
index f580858..f9faace 100644
--- a/core/modules/responsive_image/lib/Drupal/responsive_image/Tests/ResponsiveImageFieldDisplayTest.php
+++ b/core/modules/responsive_image/lib/Drupal/responsive_image/Tests/ResponsiveImageFieldDisplayTest.php
@@ -131,7 +131,7 @@ public function _testResponsiveImageFieldFormatters($scheme) {
'#width' => 40,
'#height' => 20,
);
- $default_output = drupal_render($image);
+ $default_output = str_replace("\n", NULL, drupal_render($image));
$this->assertRaw($default_output, 'Default formatter displaying correctly on full node view.');
// Use the responsive image formatter linked to file formatter.
@@ -151,6 +151,7 @@ public function _testResponsiveImageFieldFormatters($scheme) {
'#height' => 20,
);
$default_output = l($image, file_create_url($image_uri), array('html' => TRUE));
+ $default_output = str_replace("\n", NULL, $default_output);
$this->drupalGet('node/' . $nid);
$this->assertRaw($default_output, 'Image linked to file formatter displaying correctly on full node view.');
// Verify that the image can be downloaded.