diff --git a/core/modules/field/field.form.inc b/core/modules/field/field.form.inc
index 461e20d..eed312f 100644
--- a/core/modules/field/field.form.inc
+++ b/core/modules/field/field.form.inc
@@ -8,43 +8,56 @@
use Drupal\Component\Utility\NestedArray;
/**
- * Returns HTML for an individual form element.
+ * Prepares variables for individual form element templates.
+ *
+ * Default template: field-multiple-value-form.html.twig.
*
* Combines multiple values into a table with drag-n-drop reordering.
*
- * @param $variables
+ * @param array $variables
* An associative array containing:
* - element: A render element representing the form element.
- *
- * @ingroup themeable
- *
- * @todo Convert to a template.
*/
-function theme_field_multiple_value_form($variables) {
+function template_preprocess_field_multiple_value_form(&$variables) {
$element = $variables['element'];
$output = '';
- if ($element['#cardinality'] > 1 || $element['#cardinality'] == FIELD_CARDINALITY_UNLIMITED) {
+ $variables['multiple_cardinality'] = $element['#cardinality'] > 1 || $element['#cardinality'] == FIELD_CARDINALITY_UNLIMITED;
+
+ if ($variables['multiple_cardinality']) {
$table_id = drupal_html_id($element['#field_name'] . '_values');
$order_class = $element['#field_name'] . '-delta-order';
$required = !empty($element['#required']) ? theme('form_required_marker', $variables) : '';
$header = array(
array(
- 'data' => '
' . t('!title !required', array('!title' => $element['#title'], '!required' => $required)) . "
",
+ 'data' => array(
+ '#prefix' => '',
+ 'title' => array(
+ '#markup' => $element['#title'],
+ ),
+ '#suffix' => '
',
+ ),
'colspan' => 2,
'class' => array('field-label'),
),
t('Order', array(), array('context' => 'Sort order')),
);
+ if (!empty($element['#required'])) {
+ $header[0]['data']['required'] = array(
+ '#theme' => 'form_required_marker',
+ '#element' => $element,
+ );
+ }
$rows = array();
// Sort items according to '_weight' (needed when the form comes back after
- // preview or failed validation)
+ // preview or failed validation).
$items = array();
+ $variables['button'] = array();
foreach (element_children($element) as $key) {
if ($key === 'add_more') {
- $add_more_button = &$element[$key];
+ $variables['button'] = &$element[$key];
}
else {
$items[] = &$element[$key];
@@ -55,10 +68,15 @@ function theme_field_multiple_value_form($variables) {
// Add the items as table rows.
foreach ($items as $key => $item) {
$item['_weight']['#attributes']['class'] = array($order_class);
- $delta_element = drupal_render($item['_weight']);
+
+ // Remove weight form element from item render array so it can be rendered
+ // in a separate table column.
+ $delta_element = $item['_weight'];
+ unset($item['_weight']);
+
$cells = array(
array('data' => '', 'class' => array('field-multiple-drag')),
- drupal_render($item),
+ array('data' => $item),
array('data' => $delta_element, 'class' => array('delta-order')),
);
$rows[] = array(
@@ -67,21 +85,22 @@ function theme_field_multiple_value_form($variables) {
);
}
- $output = '';
+ $variables['table'] = array(
+ '#theme' => 'table',
+ '#header' => $header,
+ '#rows' => $rows,
+ '#attributes' => array('id' => $table_id, 'class' => array('field-multiple-table')),
+ );
+ $variables['description'] = $element['#description'] ? $element['#description'] : '';
drupal_add_tabledrag($table_id, 'order', 'sibling', $order_class);
}
else {
+ $variables['elements'] = array();
foreach (element_children($element) as $key) {
- $output .= drupal_render($element[$key]);
+ $variables['elements'][] = $element[$key];
}
}
-
- return $output;
}
/**
diff --git a/core/modules/field/field.module b/core/modules/field/field.module
index 92a2c45..a198af1 100644
--- a/core/modules/field/field.module
+++ b/core/modules/field/field.module
@@ -172,9 +172,12 @@ function field_theme() {
return array(
'field' => array(
'render element' => 'element',
+ 'template' => 'field',
),
'field_multiple_value_form' => array(
+ 'file' => 'field.form.inc',
'render element' => 'element',
+ 'template' => 'field-multiple-value-form',
),
);
}
@@ -1009,88 +1012,6 @@ function template_preprocess_field(&$variables, $hook) {
*/
/**
- * Returns HTML for a field.
- *
- * This is the default theme implementation to display the value of a field.
- * Theme developers who are comfortable with overriding theme functions may do
- * so in order to customize this markup. This function can be overridden with
- * varying levels of specificity. For example, for a field named 'body'
- * displayed on the 'article' content type, any of the following functions will
- * override this default implementation. The first of these functions that
- * exists is used:
- * - THEMENAME_field__body__article()
- * - THEMENAME_field__article()
- * - THEMENAME_field__body()
- * - THEMENAME_field()
- *
- * Theme developers who prefer to customize templates instead of overriding
- * functions may copy the "field.html.twig" from the "modules/field/theme"
- * folder of the Drupal installation to somewhere within the theme's folder and
- * customize it, just like customizing other Drupal templates such as
- * page.html.twig or node.html.twig. However, it takes longer for the server to
- * process templates than to call a function, so for websites with many fields
- * displayed on a page, this can result in a noticeable slowdown of the website.
- * For these websites, developers are discouraged from placing a field.html.twig
- * file into the theme's folder, but may customize templates for specific
- * fields. For example, for a field named 'body' displayed on the 'article'
- * content type, any of the following templates will override this default
- * implementation. The first of these templates that exists is used:
- * - field--body--article.html.twig
- * - field--article.html.twig
- * - field--body.html.twig
- * - field.html.twig
- * So, if the body field on the article content type needs customization, a
- * field--body--article.html.twig file can be added within the theme's folder.
- * Because it's a template, it will result in slightly more time needed to
- * display that field, but it will not impact other fields, and therefore, is
- * unlikely to cause a noticeable change in website performance. A very rough
- * guideline is that if a page is being displayed with more than 100 fields and
- * they are all themed with a template instead of a function, it can add up to
- * 5% to the time it takes to display that page. This is a guideline only and
- * the exact performance impact depends on the server configuration and the
- * details of the website.
- *
- * @param $variables
- * An associative array containing:
- * - label_hidden: A boolean indicating whether to show or hide the field
- * label.
- * - title_attributes: A string containing the attributes for the title.
- * - label: The label for the field.
- * - content_attributes: A string containing the attributes for the content's
- * div.
- * - items: An array of field items.
- * - item_attributes: An array of attributes for each item.
- * - classes: A string containing the classes for the wrapping div.
- * - attributes: A string containing the attributes for the wrapping div.
- *
- * @see template_preprocess_field()
- * @see field.html.twig
- *
- * @ingroup themeable
- */
-function theme_field($variables) {
- $output = '';
-
- // Render the label, if it's not hidden.
- if (!$variables['label_hidden']) {
- $output .= '' . $variables['label'] . '
';
- }
-
- // Render the items.
- $output .= '';
- foreach ($variables['items'] as $delta => $item) {
- $classes = 'field-item ' . ($delta % 2 ? 'odd' : 'even');
- $output .= '
' . drupal_render($item) . '
';
- }
- $output .= '
';
-
- // Render the top-level DIV.
- $output = '' . $output . '
';
-
- return $output;
-}
-
-/**
* Assembles a partial entity structure with initial IDs.
*
* @param stdClass $ids
diff --git a/core/modules/field/lib/Drupal/field/Tests/DisplayApiTest.php b/core/modules/field/lib/Drupal/field/Tests/DisplayApiTest.php
index 70195d3..7598849 100644
--- a/core/modules/field/lib/Drupal/field/Tests/DisplayApiTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/DisplayApiTest.php
@@ -64,6 +64,8 @@ public static function getInfo() {
function setUp() {
parent::setUp();
+ $this->installSchema('user', array('role_permission'));
+
// Create a field and instance.
$this->field_name = 'test_field';
$this->label = $this->randomName();
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php
index 4739d5f..24e8bb3 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldAttachOtherTest.php
@@ -38,6 +38,7 @@ public static function getInfo() {
public function setUp() {
parent::setUp();
+ $this->installSchema('user', array('role_permission'));
$this->createFieldWithInstance();
}
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/themes/bartik/bartik.theme b/core/themes/bartik/bartik.theme
index e4f03b9..ceaadfd 100644
--- a/core/themes/bartik/bartik.theme
+++ b/core/themes/bartik/bartik.theme
@@ -118,28 +118,3 @@ function bartik_preprocess_node(&$variables) {
function bartik_menu_tree($variables) {
return '';
}
-
-/**
- * Implements theme_field__field_type().
- */
-function bartik_field__taxonomy_term_reference($variables) {
- $output = '';
-
- // Render the label, if it's not hidden.
- if (!$variables['label_hidden']) {
- $output .= '' . $variables['label'] . ':
';
- }
-
- // Render the items.
- $output .= ($variables['element']['#label_display'] == 'inline') ? '