diff --git a/core/modules/field/templates/field-multiple-value-form.html.twig b/core/modules/field/templates/field-multiple-value-form.html.twig
new file mode 100644
index 0000000..fd1aba1
--- /dev/null
+++ b/core/modules/field/templates/field-multiple-value-form.html.twig
@@ -0,0 +1,39 @@
+{#
+/**
+ * @file
+ * Default theme implementation for an individual form element.
+ *
+ * Available variables for all fields:
+ * - multiple_cardinality: Whether the field is multiple cardinality or not.
+ *
+ * Available variables for single cardinality fields:
+ * - elements: Form elements to be rendered.
+ *
+ * Available variables for multiple cardinality fields:
+ * - table: Table of field items for multiple cardinality fields.
+ * - description: Description text for the form element.
+ * - button: "Add another item" button.
+ *
+ * @see template_preprocess_field()
+ * @see template_process_field()
+ *
+ * @ingroup themeable
+ */
+#}
+{% if multiple_cardinality %}
+
+{% else %}
+ {% for element in elements %}
+ {{ element }}
+ {% endfor %}
+{% endif %}
diff --git a/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php.orig b/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php.orig
new file mode 100644
index 0000000..927097d
--- /dev/null
+++ b/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php.orig
@@ -0,0 +1,202 @@
+ 'Picture field display tests',
+ 'description' => 'Test picture display formatter.',
+ 'group' => 'Picture',
+ );
+ }
+
+ /**
+ * Drupal\simpletest\WebTestBase\setUp().
+ */
+ public function setUp() {
+ parent::setUp();
+
+ // Create user.
+ $this->admin_user = $this->drupalCreateUser(array(
+ 'administer pictures',
+ 'access content',
+ 'access administration pages',
+ 'administer site configuration',
+ 'administer content types',
+ 'administer node display',
+ 'administer nodes',
+ 'create article content',
+ 'edit any article content',
+ 'delete any article content',
+ 'administer image styles'
+ ));
+ $this->drupalLogin($this->admin_user);
+
+ // Add breakpoint_group and breakpoints.
+ $breakpoint_group = entity_create('breakpoint_group', array(
+ 'id' => 'atestset',
+ 'label' => 'A test set',
+ 'sourceType' => Breakpoint::SOURCE_TYPE_USER_DEFINED,
+ ));
+
+ $breakpoints = array();
+ $breakpoint_names = array('small', 'medium', 'large');
+ for ($i = 0; $i < 3; $i++) {
+ $width = ($i + 1) * 200;
+ $breakpoint = entity_create('breakpoint', array(
+ 'name' => $breakpoint_names[$i],
+ 'mediaQuery' => "(min-width: {$width}px)",
+ 'source' => 'user',
+ 'sourceType' => Breakpoint::SOURCE_TYPE_USER_DEFINED,
+ 'multipliers' => array(
+ '1.5x' => 0,
+ '2x' => '2x',
+ ),
+ ));
+ $breakpoint->save();
+ $breakpoint_group->breakpoints[$breakpoint->id()] = $breakpoint;
+ }
+ $breakpoint_group->save();
+
+ // Add picture mapping.
+ $picture_mapping = entity_create('picture_mapping', array(
+ 'id' => 'mapping_one',
+ 'label' => 'Mapping One',
+ 'breakpointGroup' => 'atestset',
+ ));
+ $picture_mapping->save();
+ $picture_mapping->mappings['custom.user.small']['1x'] = 'thumbnail';
+ $picture_mapping->mappings['custom.user.medium']['1x'] = 'medium';
+ $picture_mapping->mappings['custom.user.large']['1x'] = 'large';
+ $picture_mapping->save();
+ }
+
+ /**
+ * Test picture formatters on node display for public files.
+ */
+ public function testPictureFieldFormattersPublic() {
+ $this->_testPictureFieldFormatters('public');
+ }
+
+ /**
+ * Test picture formatters on node display for private files.
+ */
+ public function testPictureFieldFormattersPrivate() {
+ // Remove access content permission from anonymous users.
+ user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array('access content' => FALSE));
+ $this->_testPictureFieldFormatters('private');
+ }
+
+ /**
+ * Test picture formatters on node display.
+ */
+ public function _testPictureFieldFormatters($scheme) {
+ $field_name = drupal_strtolower($this->randomName());
+ $this->createImageField($field_name, 'article', array('uri_scheme' => $scheme));
+ // Create a new node with an image attached.
+ $test_image = current($this->drupalGetTestFiles('image'));
+ $nid = $this->uploadNodeImage($test_image, $field_name, 'article');
+ $node = node_load($nid, TRUE);
+
+ // Test that the default formatter is being used.
+ $image_uri = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['fid'])->getFileUri();
+ $image_info = array(
+ 'uri' => $image_uri,
+ 'width' => 40,
+ 'height' => 20,
+ );
+ $default_output = theme('image', $image_info);
+ $this->assertRaw($default_output, 'Default formatter displaying correctly on full node view.');
+
+ // Use the picture formatter linked to file formatter.
+ $display_options = array(
+ 'type' => 'picture',
+ 'module' => 'picture',
+ 'settings' => array('image_link' => 'file'),
+ );
+ $display = entity_get_display('node', 'article', 'default');
+ $display->setComponent($field_name, $display_options)
+ ->save();
+
+ $default_output = l(theme('image', $image_info), file_create_url($image_uri), array('html' => TRUE));
+ $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.
+ $this->assertEqual(file_get_contents($test_image->uri), $this->drupalGet(file_create_url($image_uri)), 'File was downloaded successfully.');
+ if ($scheme == 'private') {
+ // Only verify HTTP headers when using private scheme and the headers are
+ // sent by Drupal.
+ $this->assertEqual($this->drupalGetHeader('Content-Type'), 'image/png', 'Content-Type header was sent.');
+ $this->assertTrue(strstr($this->drupalGetHeader('Cache-Control'), 'private') !== FALSE, 'Cache-Control header was sent.');
+
+ // Log out and try to access the file.
+ $this->drupalLogout();
+ $this->drupalGet(file_create_url($image_uri));
+ $this->assertResponse('403', 'Access denied to original image as anonymous user.');
+
+ // Log in again.
+ $this->drupalLogin($this->admin_user);
+ }
+
+ // Use the picture formatter with a picture mapping.
+ $display_options['settings']['picture_mapping'] = 'mapping_one';
+ $display->setComponent($field_name, $display_options)
+ ->save();
+
+ // Output should contain all image styles and all breakpoints.
+ $this->drupalGet('node/' . $nid);
+ $this->assertRaw('/styles/thumbnail/');
+ $this->assertRaw('/styles/medium/');
+ $this->assertRaw('/styles/large/');
+ $this->assertRaw('media="(min-width: 200px)"');
+ $this->assertRaw('media="(min-width: 400px)"');
+ $this->assertRaw('media="(min-width: 600px)"');
+
+ // Test the fallback image style.
+ $display_options['settings']['image_link'] = '';
+ $display_options['settings']['fallback_image_style'] = 'large';
+ $display->setComponent($field_name, $display_options)
+ ->save();
+
+ $this->drupalGet(image_style_url('large', $image_uri));
+ $image_info['uri'] = $image_uri;
+ $image_info['width'] = 480;
+ $image_info['height'] = 240;
+ $image_info['style_name'] = 'large';
+ $default_output = '';
+ $this->drupalGet('node/' . $nid);
+ $this->assertRaw($default_output, 'Image style thumbnail formatter displaying correctly on full node view.');
+
+ if ($scheme == 'private') {
+ // Log out and try to access the file.
+ $this->drupalLogout();
+ $this->drupalGet(image_style_url('large', $image_uri));
+ $this->assertResponse('403', 'Access denied to image style thumbnail as anonymous user.');
+ }
+ }
+
+}
diff --git a/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php.rej b/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php.rej
new file mode 100644
index 0000000..6552901
--- /dev/null
+++ b/core/modules/picture/lib/Drupal/picture/Tests/PictureFieldDisplayTest.php.rej
@@ -0,0 +1,28 @@
+***************
+*** 124,135 ****
+
+ // Test that the default formatter is being used.
+ $image_uri = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['fid'])->uri;
+- $image_info = array(
+- 'uri' => $image_uri,
+- 'width' => 40,
+- 'height' => 20,
+ );
+- $default_output = theme('image', $image_info);
+ $this->assertRaw($default_output, 'Default formatter displaying correctly on full node view.');
+
+ // Use the picture formatter linked to file formatter.
+--- 124,136 ----
+
+ // Test that the default formatter is being used.
+ $image_uri = file_load($node->{$field_name}[Language::LANGCODE_NOT_SPECIFIED][0]['fid'])->uri;
++ $image = array(
++ '#theme' => 'image',
++ '#uri' => $image_uri,
++ '#width' => 40,
++ '#height' => 20,
+ );
++ $default_output = drupal_render($image);
+ $this->assertRaw($default_output, 'Default formatter displaying correctly on full node view.');
+
+ // Use the picture formatter linked to file formatter.
diff --git a/core/modules/system/lib/Drupal/system/Controller/SystemInfoController.php b/core/modules/system/lib/Drupal/system/Controller/SystemInfoController.php
index af48c1f..7f7e1f8 100644
--- a/core/modules/system/lib/Drupal/system/Controller/SystemInfoController.php
+++ b/core/modules/system/lib/Drupal/system/Controller/SystemInfoController.php
@@ -53,7 +53,10 @@ public function __construct(SystemManager $systemManager) {
public function status() {
$requirements = $this->systemManager->listRequirements();
$this->systemManager->fixAnonymousUid();
- return theme('status_report', array('requirements' => $requirements));
+ return array(
+ '#theme' => 'status_report',
+ '#requirements' => $requirements,
+ );
}
/**
diff --git a/core/modules/system/system.admin.inc b/core/modules/system/system.admin.inc
index c499692..859423e 100644
--- a/core/modules/system/system.admin.inc
+++ b/core/modules/system/system.admin.inc
@@ -12,6 +12,7 @@
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Drupal\Core\Datetime\DrupalDateTime;
+use Drupal\Core\Template\Attribute;
use Drupal\system\Form\ModulesInstallConfirmForm;
use Drupal\system\Form\ModulesUninstallConfirmForm;
@@ -48,10 +49,11 @@ function system_admin_config_page() {
unset($item['localized_options']['attributes']['title']);
}
$block = $item;
- $block['content'] = '';
- $block['content'] .= theme('admin_block_content', array('content' => system_admin_menu_block($item)));
- if (!empty($block['content'])) {
- $block['show'] = TRUE;
+ if ($content = system_admin_menu_block($item)) {
+ $block['content'] = array(
+ '#theme' => 'admin_block_content',
+ '#content' => $content,
+ );
}
// Prepare for sorting as in function _menu_tree_check_access().
@@ -62,7 +64,10 @@ function system_admin_config_page() {
}
if ($blocks) {
ksort($blocks);
- return theme('admin_page', array('blocks' => $blocks));
+ return array(
+ '#theme' => 'admin_page',
+ '#blocks' => $blocks,
+ );
}
else {
return t('You do not have any administrative items.');
@@ -83,12 +88,17 @@ function system_admin_config_page() {
function system_admin_menu_block_page() {
$item = menu_get_item();
if ($content = system_admin_menu_block($item)) {
- $output = theme('admin_block_content', array('content' => $content));
+ $build = array(
+ '#theme' => 'admin_block_content',
+ '#content' => $content,
+ );
}
else {
- $output = t('You do not have any administrative items.');
+ $build = array(
+ '#markup' => t('You do not have any administrative items.'),
+ );
}
- return $output;
+ return $build;
}
/**
@@ -217,8 +227,12 @@ function system_themes_page() {
uasort($theme_groups['enabled'], 'system_sort_themes');
drupal_alter('system_themes_page', $theme_groups);
- $admin_form = drupal_get_form('system_themes_admin_form', $admin_theme_options);
- return theme('system_themes_page', array('theme_groups' => $theme_groups, 'theme_group_titles' => $theme_group_titles)) . drupal_render($admin_form);
+ return array(
+ '#theme' => 'system_themes_page',
+ '#theme_groups' => $theme_groups,
+ '#theme_group_titles' => $theme_group_titles,
+ '#admin_theme_options' => $admin_theme_options,
+ );
}
/**
@@ -993,9 +1007,12 @@ function _system_modules_build_row($info, $extra) {
}
else {
$form['enable'] = array(
- '#markup' => theme('image', array('uri' => 'core/misc/watchdog-error.png', 'alt' => $status_short, 'title' => $status_short)),
+ '#theme' => 'image',
+ '#uri' => 'core/misc/watchdog-error.png',
+ '#alt' => $status_short,
+ '#title' => $status_short,
);
- $form['description']['#markup'] .= theme('system_modules_incompatible', array('message' => $status_long));
+ $form['description']['#markup'] .= '
' . $status_long . '
';
}
// Build operation links.
@@ -1273,45 +1290,9 @@ function system_batch_page() {
}
/**
- * Returns HTML for an administrative block for display.
- *
- * @param $variables
- * An associative array containing:
- * - block: An array containing information about the block:
- * - show: A Boolean whether to output the block. Defaults to FALSE.
- * - title: The block's title.
- * - content: (optional) Formatted content for the block.
- * - description: (optional) Description of the block. Only output if
- * 'content' is not set.
+ * Prepares variables for administrative content block template.
*
- * @ingroup themeable
- */
-function theme_admin_block($variables) {
- $block = $variables['block'];
- $output = '';
-
- // Don't display the block if it has no content to display.
- if (empty($block['show'])) {
- return $output;
- }
-
- $output .= '
';
- if (!empty($block['title'])) {
- $output .= '
';
+ $current_theme['attributes'] = new Attribute(array('class' => $theme->classes));
+ $current_theme['name'] = $theme->info['name'];
+ $current_theme['version'] = isset($theme->info['version']) ? $theme->info['version'] : '';
+ $current_theme['notes'] = count($theme->notes) ? '(' . join(', ', $theme->notes) . ')' : '';
// Make sure to provide feedback on compatibility.
if (!empty($theme->incompatible_core)) {
- $output .= '
' . t('This version is not compatible with Drupal !core_version and should be replaced.', array('!core_version' => DRUPAL_CORE_COMPATIBILITY)) . '
';
+ $current_theme['compatibility'] = t('This version is not compatible with Drupal !core_version and should be replaced.', array('!core_version' => DRUPAL_CORE_COMPATIBILITY));
}
elseif (!empty($theme->incompatible_php)) {
if (substr_count($theme->info['php'], '.') < 2) {
$theme->info['php'] .= '.*';
}
- $output .= '
' . t('This theme requires PHP version @php_required and is incompatible with PHP version !php_version.', array('@php_required' => $theme->info['php'], '!php_version' => phpversion())) . '
';
+ $current_theme['compatibility'] = t('This theme requires PHP version @php_required and is incompatible with PHP version !php_version.', array('@php_required' => $theme->info['php'], '!php_version' => phpversion()));
}
elseif (!empty($theme->incompatible_base)) {
- $output .= '
' . t('This theme requires the base theme @base_theme to operate correctly.', array('@base_theme' => $theme->info['base theme'])) . '
';
+ $current_theme['compatibility'] = t('This theme requires the base theme @base_theme to operate correctly.', array('@base_theme' => $theme->info['base theme']));
}
elseif (!empty($theme->incompatible_engine)) {
- $output .= '
' . t('This theme requires the theme engine @theme_engine to operate correctly.', array('@theme_engine' => $theme->info['engine'])) . '
';
-
- return $output;
}
/**
@@ -3807,6 +3810,7 @@ function theme_system_config_form($variables) {
* A string containing an HTML-formatted form.
*
* @ingroup themeable
+ * @todo Move this out of system.module and back into theme.inc.
*/
function theme_exposed_filters($variables) {
$form = $variables['form'];
diff --git a/core/modules/system/templates/admin-block-content.html.twig b/core/modules/system/templates/admin-block-content.html.twig
new file mode 100644
index 0000000..1900082
--- /dev/null
+++ b/core/modules/system/templates/admin-block-content.html.twig
@@ -0,0 +1,29 @@
+{#
+/**
+ * @file
+ * Default theme implementation for the content of an administrative block.
+ *
+ * Available variables:
+ * - content: A list containing information about the block. Each element
+ * of the array represents an administrative menu item, and must at least
+ * contain the keys 'title', 'href', and 'localized_options', which are
+ * passed to l(). A 'description' key may also be provided.
+ * - attributes: Remaining HTML attributes to be aded to the element.
+ * - is_compact_mode: It defines if compact mode is used.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_admin_block_content()
+ *
+ * @ingroup themeable
+ */
+#}
+{% if content %}
+
+ {% for item in content %}
+
{{ item.link }}
+ {% if item.description %}
+
{{ item.description }}
+ {% endif %}
+ {% endfor %}
+
+{% endif %}
diff --git a/core/modules/system/templates/admin-block.html.twig b/core/modules/system/templates/admin-block.html.twig
new file mode 100644
index 0000000..8e9bc96
--- /dev/null
+++ b/core/modules/system/templates/admin-block.html.twig
@@ -0,0 +1,31 @@
+{#
+/**
+ * @file
+ * Default theme implementation for an administrative block.
+ *
+ * Available variables:
+ * - block: An array of information about the block, including:
+ * - show: A boolean flag indicating if the block should be displayed.
+ * - title: The block title.
+ * - content: (optional) The content of the block.
+ * - description: (optional) A description of the block.
+ * (description should only be output if content is not available).
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_admin_block()
+ *
+ * @ingroup themeable
+ */
+#}
+{% if block.show %}
+
+ {% if block.title %}
+
{{ block.title }}
+ {% endif %}
+ {% if block.content %}
+
{{ block.content }}
+ {% elseif block.description %}
+
{{ block.description }}
+ {% endif %}
+
+{% endif %}
diff --git a/core/modules/system/templates/admin-page.html.twig b/core/modules/system/templates/admin-page.html.twig
new file mode 100644
index 0000000..c3c42f0
--- /dev/null
+++ b/core/modules/system/templates/admin-page.html.twig
@@ -0,0 +1,26 @@
+{#
+/**
+ * @file
+ * Default theme implementation for an administrative page.
+ *
+ * Available variables:
+ * - system_compact_link: Themed link to toggle compact view.
+ * - containers: An list of administrative blocks keyed by position: left or
+ * right.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_admin_page()
+ *
+ * @ingroup themeable
+ */
+#}
+
+ {{ system_compact_link }}
+ {% for position, container in containers %}
+
+ {% for block in container.blocks %}
+ {{ block }}
+ {% endfor %}
+
+{{ admin_form }}
diff --git a/core/themes/bartik/templates/field--taxonomy-term-reference.html.twig b/core/themes/bartik/templates/field--taxonomy-term-reference.html.twig
new file mode 100644
index 0000000..bfbe97d
--- /dev/null
+++ b/core/themes/bartik/templates/field--taxonomy-term-reference.html.twig
@@ -0,0 +1,32 @@
+{#
+/**
+ * @file
+ * Bartik theme override for taxonomy term fields.
+ *
+ * Available variables:
+ * - attributes: HTML attributes for the containing element.
+ * - label_hidden: Whether to show the field label or not.
+ * - title_attributes: HTML attributes for the title.
+ * - label: The label for the field.
+ * - content_attributes: HTML attributes for the content.
+ * - items: List of all the field items.
+ * - item_attributes: HTML attributes for each item.
+ *
+ * @see template_preprocess_field()
+ * @see template_process_field()
+ *
+ * @ingroup themeable
+ */
+ @todo Remove even/odd striping once http://drupal.org/node/1649780 lands.
+#}
+
+ {% if not label_hidden %}
+
{{ label }}:
+ {% endif %}
+
+ {% for delta, item in items %}
+ {# @todo remove type casting once http://drupal.org/node/1970960 lands #}
+