Commit e76a96f4 authored by alexpott's avatar alexpott

Issue #2363423 by dorficus, Manuel Garcia, stefan.r, Cottser, prajaankit,...

Issue #2363423 by dorficus, Manuel Garcia, stefan.r, Cottser, prajaankit, joelpittet, davidhernandez, alexpott, xjm, dawehner, penyaskito: views-view-fields.html.twig gets escaped
parent c234b832
...@@ -242,7 +242,7 @@ public function elementType($none_supported = FALSE, $default_empty = FALSE, $in ...@@ -242,7 +242,7 @@ public function elementType($none_supported = FALSE, $default_empty = FALSE, $in
} }
} }
if ($this->options['element_type']) { if ($this->options['element_type']) {
return SafeMarkup::checkPlain($this->options['element_type']); return $this->options['element_type'];
} }
if ($default_empty) { if ($default_empty) {
...@@ -270,7 +270,7 @@ public function elementLabelType($none_supported = FALSE, $default_empty = FALSE ...@@ -270,7 +270,7 @@ public function elementLabelType($none_supported = FALSE, $default_empty = FALSE
} }
} }
if ($this->options['element_label_type']) { if ($this->options['element_label_type']) {
return SafeMarkup::checkPlain($this->options['element_label_type']); return $this->options['element_label_type'];
} }
if ($default_empty) { if ($default_empty) {
...@@ -290,7 +290,7 @@ public function elementWrapperType($none_supported = FALSE, $default_empty = FAL ...@@ -290,7 +290,7 @@ public function elementWrapperType($none_supported = FALSE, $default_empty = FAL
} }
} }
if ($this->options['element_wrapper_type']) { if ($this->options['element_wrapper_type']) {
return SafeMarkup::checkPlain($this->options['element_wrapper_type']); return $this->options['element_wrapper_type'];
} }
if ($default_empty) { if ($default_empty) {
......
<?php
/**
* @file
* Contains \Drupal\views\Tests\ViewsEscapingTest.
*/
namespace Drupal\views\Tests;
/**
* Tests output of Views.
*
* @group views
*/
class ViewsEscapingTest extends ViewTestBase {
/**
* Views used by this test.
*
* @var array
*/
public static $testViews = array('test_page_display');
/**
* Used by WebTestBase::setup()
*
* We need theme_test for testing against test_basetheme and test_subtheme.
*
* @var array
*
* @see \Drupal\simpletest\WebTestBase::setup()
*/
public static $modules = array('views', 'theme_test');
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->enableViewsTestModule();
}
/**
* Tests for incorrectly escaped markup in the views-view-fields.html.twig.
*/
public function testViewsViewFieldsEscaping() {
// Test with system theme using theme function.
$this->drupalGet('test_page_display_200');
// Assert that there are no escaped '<'s characters.
$this->assertNoEscaped('<');
// Install theme to test with template system.
\Drupal::service('theme_handler')->install(array('views_test_theme'));
// Make base theme default then test for hook invocations.
$this->config('system.theme')
->set('default', 'views_test_theme')
->save();
$this->assertEqual($this->config('system.theme')->get('default'), 'views_test_theme');
$this->drupalGet('test_page_display_200');
// Assert that we are using the correct template.
$this->assertText('force', 'The force is strong with this one');
// Assert that there are no escaped '<'s characters.
$this->assertNoEscaped('<');
}
}
...@@ -11,13 +11,16 @@ ...@@ -11,13 +11,16 @@
* - class: The safe class ID to use. * - class: The safe class ID to use.
* - handler: The Views field handler controlling this field. * - handler: The Views field handler controlling this field.
* - inline: Whether or not the field should be inline. * - inline: Whether or not the field should be inline.
* - inline_html: Either div or span based on the 'inline' flag. * - wrapper_element: An HTML element for a wrapper.
* - wrapper_prefix: A complete wrapper containing the inline_html to use. * - wrapper_attributes: List of attributes for wrapper element.
* - wrapper_suffix: The closing tag for the wrapper.
* - separator: An optional separator that may appear before a field. * - separator: An optional separator that may appear before a field.
* - label: The field's label text. * - label: The field's label text.
* - label_html: The full HTML of the label to use including configured * - label_element: An HTML element for a label wrapper.
* element type. * - label_attributes: List of attributes for label wrapper.
* - has_label_colon: A boolean indicating whether to display a colon after
* the label.
* - element_type: An HTML element for the field content.
* - element_attributes: List of attributes for HTML element for field content.
* - row: The raw result from the query, with all data it fetched. * - row: The raw result from the query, with all data it fetched.
* *
* @see template_preprocess_views_view_fields() * @see template_preprocess_views_view_fields()
...@@ -31,11 +34,24 @@ See http://api.drupal.org/api/function/theme_views_view_fields/8 for details. ...@@ -31,11 +34,24 @@ See http://api.drupal.org/api/function/theme_views_view_fields/8 for details.
After copying this file to your theme's folder and customizing it, remove this After copying this file to your theme's folder and customizing it, remove this
comment. comment.
#} #}
{% for field in fields %} {% for field in fields -%}
{{ field.separator }} {{ field.separator }}
{%- if field.wrapper_element -%}
{{ field.wrapper_prefix }} <{{ field.wrapper_element }}{{ field.wrapper_attributes }}>
{{ field.label_html }} {%- endif %}
{%- if field.label -%}
{%- if field.label_element -%}
<{{ field.label_element }}{{ field.label_attributes }}>{{ field.label }}{{ field.has_label_colon ? ': ' }}</{{ field.label_element }}>
{%- else -%}
{{ field.label }}{{ field.has_label_colon ? ': ' }}
{%- endif %}
{%- endif %}
{%- if field.element_type -%}
<{{ field.element_type }}{{ field.element_attributes }}>{{ field.content }}</{{ field.element_type }}>
{%- else -%}
{{ field.content }} {{ field.content }}
{{ field.wrapper_suffix }} {%- endif %}
{% endfor %} {%- if field.wrapper_element -%}
</{{ field.wrapper_element }}>
{%- endif %}
{%- endfor %}
{#
/**
* @file
* Theme override to display all the fields in a views row.
*
* The reason for this template is to override the theme function provided by
* views.
*/
#}
{% include '@views/views-view-fields.html.twig' %}
May the force be with you!
name: Views test theme
type: theme
description: Theme for testing Views functionality.
version: VERSION
core: 8.x
...@@ -90,6 +90,9 @@ function template_preprocess_views_view_fields(&$variables) { ...@@ -90,6 +90,9 @@ function template_preprocess_views_view_fields(&$variables) {
$object = new stdClass(); $object = new stdClass();
$object->handler = $view->field[$id]; $object->handler = $view->field[$id];
$object->inline = !empty($variables['options']['inline'][$id]); $object->inline = !empty($variables['options']['inline'][$id]);
// Set up default value of the flag that indicates whether to display a
// colon after the label.
$object->has_label_colon = FALSE;
$object->element_type = $object->handler->elementType(TRUE, !$variables['options']['default_field_elements'], $object->inline); $object->element_type = $object->handler->elementType(TRUE, !$variables['options']['default_field_elements'], $object->inline);
if ($object->element_type) { if ($object->element_type) {
...@@ -101,18 +104,7 @@ function template_preprocess_views_view_fields(&$variables) { ...@@ -101,18 +104,7 @@ function template_preprocess_views_view_fields(&$variables) {
if ($classes = $object->handler->elementClasses($row->index)) { if ($classes = $object->handler->elementClasses($row->index)) {
$attributes['class'][] = $classes; $attributes['class'][] = $classes;
} }
$attributes = new Attribute($attributes); $object->element_attributes = new Attribute($attributes);
$pre = '<' . $object->element_type;
$pre .= $attributes;
$field_output = $pre . '>' . $field_output . '</' . $object->element_type . '>';
}
// Protect ourselves somewhat for backward compatibility. This will
// prevent old templates from producing invalid HTML when no element type
// is selected.
if (empty($object->element_type)) {
$object->element_type = 'span';
} }
$object->content = $field_output; $object->content = $field_output;
...@@ -130,16 +122,14 @@ function template_preprocess_views_view_fields(&$variables) { ...@@ -130,16 +122,14 @@ function template_preprocess_views_view_fields(&$variables) {
$object->class = Html::cleanCssIdentifier($id); $object->class = Html::cleanCssIdentifier($id);
$previous_inline = $object->inline; $previous_inline = $object->inline;
$object->inline_html = $object->handler->elementWrapperType(TRUE, TRUE); // Set up field wrapper element.
if ($object->inline_html === '' && $variables['options']['default_field_elements']) { $object->wrapper_element = $object->handler->elementWrapperType(TRUE, TRUE);
$object->inline_html = $object->inline ? 'span' : 'div'; if ($object->wrapper_element === '' && $variables['options']['default_field_elements']) {
$object->wrapper_element = $object->inline ? 'span' : 'div';
} }
// Set up the wrapper HTML. // Set up field wrapper attributes if field wrapper was set.
$object->wrapper_prefix = ''; if ($object->wrapper_element) {
$object->wrapper_suffix = '';
if ($object->inline_html) {
$attributes = array(); $attributes = array();
if ($object->handler->options['element_default_classes']) { if ($object->handler->options['element_default_classes']) {
$attributes['class'][] = 'views-field'; $attributes['class'][] = 'views-field';
...@@ -149,26 +139,24 @@ function template_preprocess_views_view_fields(&$variables) { ...@@ -149,26 +139,24 @@ function template_preprocess_views_view_fields(&$variables) {
if ($classes = $object->handler->elementWrapperClasses($row->index)) { if ($classes = $object->handler->elementWrapperClasses($row->index)) {
$attributes['class'][] = $classes; $attributes['class'][] = $classes;
} }
$attributes = new Attribute($attributes); $object->wrapper_attributes = new Attribute($attributes);
$object->wrapper_prefix = '<' . $object->inline_html;
$object->wrapper_prefix .= $attributes;
$object->wrapper_prefix .= '>';
$object->wrapper_suffix = '</' . $object->inline_html . '>';
} }
// Set up the label for the value and the HTML to make it easier // Set up field label
// on the template. $object->label = $view->field[$id]->label();
$object->label = SafeMarkup::checkPlain($view->field[$id]->label());
$object->label_html = ''; // Set up field label wrapper and its attributes.
if ($object->label) { if ($object->label) {
$object->label_html .= $object->label; // Add a colon in a label suffix.
if ($object->handler->options['element_label_colon']) { if ($object->handler->options['element_label_colon']) {
$object->label_html .= ': '; $object->has_label_colon = TRUE;
} }
$object->elementLabelType = $object->handler->elementLabelType(TRUE, !$variables['options']['default_field_elements']); // Set up label HTML element.
if ($object->elementLabelType) { $object->label_element = $object->handler->elementLabelType(TRUE, !$variables['options']['default_field_elements']);
// Set up label attributes.
if ($object->label_element) {
$attributes = array(); $attributes = array();
if ($object->handler->options['element_default_classes']) { if ($object->handler->options['element_default_classes']) {
$attributes['class'][] = 'views-label'; $attributes['class'][] = 'views-label';
...@@ -179,13 +167,7 @@ function template_preprocess_views_view_fields(&$variables) { ...@@ -179,13 +167,7 @@ function template_preprocess_views_view_fields(&$variables) {
if ($element_label_class) { if ($element_label_class) {
$attributes['class'][] = $element_label_class; $attributes['class'][] = $element_label_class;
} }
$attributes = new Attribute($attributes); $object->label_attributes = new Attribute($attributes);
$pre = '<' . $object->elementLabelType;
$pre .= $attributes;
$pre .= '>';
$object->label_html = $pre . $object->label_html . '</' . $object->elementLabelType . '>';
} }
} }
...@@ -219,12 +201,32 @@ function theme_views_view_fields($variables) { ...@@ -219,12 +201,32 @@ function theme_views_view_fields($variables) {
if (!empty($field->separator)) { if (!empty($field->separator)) {
$output .= $field->separator; $output .= $field->separator;
} }
$wrapper_element = Html::escape($field->wrapper_element);
$output .= $field->wrapper_prefix; if ($wrapper_element) {
$output .= $field->label_html; $output .= '<' . $wrapper_element . $field->wrapper_attributes . '>';
if (isset($field->label_element) && !empty($field->label_element)) {
$label_element = Html::escape($field->label_element);
$output .= '<' . $label_element . $field->label_attributes . '>';
}
$output .= Html::escape($field->label);
if ($field->has_label_colon) {
$output .= ': ';
}
if (isset($label_element)) {
$output .= '</' . $label_element . '>';
}
}
$element_type = Html::escape($field->element_type);
if ($element_type) {
$output .= '<' . $element_type . $field->element_attributes . '>';
}
$output .= $field->content; $output .= $field->content;
if ($element_type) {
$output .= $field->wrapper_suffix; $output .= '</' . $element_type . '>';
}
if ($wrapper_element) {
$output .= '</' . $wrapper_element . '>';
}
} }
return $output; return $output;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment