diff --git a/core/modules/views/templates/views-exposed-form.html.twig b/core/modules/views/templates/views-exposed-form.html.twig
new file mode 100644
index 0000000000000000000000000000000000000000..239b67df030865eac7dd70ee535ca684d400f556
--- /dev/null
+++ b/core/modules/views/templates/views-exposed-form.html.twig
@@ -0,0 +1,87 @@
+{#
+/**
+ * @file
+ * Default theme implementation of a views exposed form.
+ *
+ * Available variables:
+ * - widgets: A list of exposed form widgets. Each widget contains:
+ * - label: The sanitized label of the widget.
+ * - id: The ID of the widget, if available.
+ * - operator: The select element for the operator widget.
+ * - description: The sanitized description of the widget.
+ * - widget: The widget itself.
+ * - index: the widget's row index.
+ * - form: A render element representing the form.
+ * - sort_by: An optional select element to sort the view by fields.
+ * - sort_order: An optional select element with ascending or
+ * descending order options.
+ * - items_per_page: An optional select element for the available items per
+ * page.
+ * - offset: An optional textfield to define the offset of the view.
+ * - reset_button: An optional button to reset the exposed filter applied.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_views_exposed_form()
+ *
+ * @ingroup themeable
+ */
+#}
+{% if q is not empty %}
+ {#
+ This ensures that, if clean URLs are off, the 'q' is added first,
+ as a hidden form element, so that it shows up first in the POST URL.
+ #}
+{{ q }}
+{% endif %}
+
diff --git a/core/modules/views/templates/views-exposed-form.tpl.php b/core/modules/views/templates/views-exposed-form.tpl.php
deleted file mode 100644
index bdd570c228a87c14ccf02d22a2f40d31936bb4e8..0000000000000000000000000000000000000000
--- a/core/modules/views/templates/views-exposed-form.tpl.php
+++ /dev/null
@@ -1,80 +0,0 @@
-label: The visible label to print. May be optional.
- * - $widget->operator: The operator for the widget. May be optional.
- * - $widget->widget: The widget itself.
- * - $sort_by: The select box to sort the view using an exposed form.
- * - $sort_order: The select box with the ASC, DESC options to define order. May be optional.
- * - $items_per_page: The select box with the available items per page. May be optional.
- * - $offset: A textfield to define the offset of the view. May be optional.
- * - $reset_button: A button to reset the exposed filter applied. May be optional.
- * - $button: The submit button for the form.
- *
- * @ingroup views_templates
- */
-?>
-
-
-
-
diff --git a/core/modules/views/views.theme.inc b/core/modules/views/views.theme.inc
index d3c0a1346d1a7462bcca88d23d690a9b3d68816b..6113b3d4f53358b747bf80b1155383a707be08d0 100644
--- a/core/modules/views/views.theme.inc
+++ b/core/modules/views/views.theme.inc
@@ -935,49 +935,57 @@ function template_preprocess_views_view_row_rss(&$vars) {
}
/**
- * Default theme function for all filter forms.
+ * Prepares variables for views exposed form templates.
+ *
+ * Default template: views-exposed-form.html.twig.
+ *
+ * @param array $vars
+ * An associative array containing:
+ * - form: A render element representing the form.
*/
function template_preprocess_views_exposed_form(&$vars) {
$form = &$vars['form'];
// Put all single checkboxes together in the last spot.
- $checkboxes = '';
+ $checkboxes = array();
if (!empty($form['q'])) {
- $vars['q'] = drupal_render($form['q']);
+ $vars['q'] = $form['q'];
}
$vars['widgets'] = array();
foreach ($form['#info'] as $id => $info) {
// Set aside checkboxes.
if (isset($form[$info['value']]['#type']) && $form[$info['value']]['#type'] == 'checkbox') {
- $checkboxes .= drupal_render($form[$info['value']]);
+ $checkboxes[] = $form[$info['value']];
continue;
}
$widget = new stdClass();
// set up defaults so that there's always something there.
- $widget->label = $widget->operator = $widget->widget = $widget->description = NULL;
+ $widget->label = $widget->operator = $widget->widget = $widget->description = '';
$widget->id = isset($form[$info['value']]['#id']) ? $form[$info['value']]['#id'] : '';
if (!empty($info['label'])) {
$widget->label = check_plain($info['label']);
}
- if (!empty($info['operator'])) {
- $widget->operator = drupal_render($form[$info['operator']]);
+ if (!empty($info['operator']) && isset($form[$info['operator']])) {
+ $widget->operator = $form[$info['operator']];
}
- $widget->widget = drupal_render($form[$info['value']]);
+ $widget->widget = $form[$info['value']];
if (!empty($info['description'])) {
$widget->description = check_plain($info['description']);
}
$vars['widgets'][$id] = $widget;
+ // Unset the widget, so that it doesn't get rendered twice.
+ unset($form[$info['value']]);
}
// Wrap up all the checkboxes we set aside into a widget.
- if ($checkboxes) {
+ if (!empty($checkboxes)) {
$widget = new stdClass();
// set up defaults so that there's always something there.
$widget->label = $widget->operator = $widget->widget = NULL;
@@ -985,22 +993,6 @@ function template_preprocess_views_exposed_form(&$vars) {
$widget->widget = $checkboxes;
$vars['widgets']['checkboxes'] = $widget;
}
-
- if (isset($form['sort_by'])) {
- $vars['sort_by'] = drupal_render($form['sort_by']);
- $vars['sort_order'] = drupal_render($form['sort_order']);
- }
- if (isset($form['items_per_page'])) {
- $vars['items_per_page'] = drupal_render($form['items_per_page']);
- }
- if (isset($form['offset'])) {
- $vars['offset'] = drupal_render($form['offset']);
- }
- if (isset($form['reset'])) {
- $vars['reset_button'] = drupal_render($form['reset']);
- }
- // This includes the submit button.
- $vars['button'] = drupal_render_children($form);
}
/**