Problem/Motivation

When Views rewrites the display of a multi-valued field, it passes each value in that field through the rewrite code. If we wish to use Twig when rewrite a field, we want to option to pass all values to Twig and use Twig to sort out how the final HTML will look. Even though it's semantically correct to render lists with only one item as a list, it clutters the display.

Proposed resolution

Extend the 'Multiple fields settings' form with an option to "Render all items together." The default for this option is FALSE, which keeps things backward compatible.

Remaining tasks

API changes

This does not change any APIs.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

kaare’s picture

Project: Views (for Drupal 7) » Drupal core
Issue summary: View changes

Updated issue summary with attached screenshots

kaare’s picture

Issue summary: View changes

Updated issue summary.

kaare’s picture

Issue summary: View changes

Updated issue summary. Removed UI changes header

kaare’s picture

Project: Drupal core » Views (for Drupal 7)
Status: Active » Needs review
FileSize
38.31 KB
1.8 KB

Renamed option from 'list_single' to 'omit_list_singletons' which also inverts the logic. It makes sense to enable an exception, because that is what this is. You're adding an exception to creating lists of everything.

Views multiple field list display settings

kaare’s picture

Title: Disable HTML lists for multivalue fields with only one item » Option to not render multivalue fields with only one value as HTML lists in views
Project: Views (for Drupal 7) » Drupal core
Version: 7.x-3.x-dev » 8.x-dev
Component: fieldapi data » views.module
FileSize
5.76 KB
24.52 KB
1.97 KB

And here is a D8 version, i.e. -dev, where feature requests are supposed to go first. I'm learning :-) Though I'm not sure if this belongs in the 'field system' component as the code resides in the field module.

Settings as seen in D8:
views-omit-list-singletons-2055597-2-settings.png

It even works!
views-omit-list-singletons-2055597-2-after.png

kaare’s picture

Issue summary: View changes

Updated issue summary.

jhedstrom’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll

Patch no longer applies. It may be too late for 8.0, but perhaps allowed for 8.1?

mikeker’s picture

If #2342287: Allow Twig in Views token replacement lands, we might be able to do this by providing a token for all the values of a multi-valued field and using Twig to style it as needed.

Pro: avoids clutter in the UI, allows even greater flexibility to site builders (eg: displays such as "item1, item2, and item3"), could add support for multi-value field tokens in contrib while waiting for acceptance into core.
Con: Less discoverable and requires knowledge of how to code Twig to make it work.

Thoughts?

Sivaji_Ganesh_Jojodae’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
FileSize
1.89 KB

+1 for adding this option. Have rerolled patch #2 against 8.0.x.

Status: Needs review » Needs work

The last submitted patch, 5: issue-2055597-5.patch, failed testing.

kaare’s picture

@mikeker: Intriguing idea. It moves the burden over to the site builder and keeps the views code cleaner and UI uncluttered. I picture the rewritten field code could look something like this pseudo twig code:

{% if field_multiple|count > 1 %}
<ul>
{% for field_multiple in item %}
  <li>
    {{ item.content }}
  </li>
{% endfor %}
</ul>
{% else %}
  {{ field_multiple }}
{% endif %}

This example code could reside in views documentation as an example on how to manage/rewrite/use multi value fields. Would it be an easy fix to provide this as a multiple item in twig?

@sivaji@knackforge.com: Thanks for the re-roll!

Edited: Fixed user names

mikeker’s picture

FileSize
45.22 KB

@kaare, exactly!

One issue: multi-valued fields run the rewrite on each value of that field, not once for the field itself. This makes sense when you're wanting to rewrite each term a page is tagged with, for example.

Using the terms-on-a-page example, the term handler would need to 1) provide a Views token of all the terms in a single item, and b) only execute the render code once for that field. I'm not sure the best way to handle the UI as the site builder would need to control it -- in code we don't know if they want to rewrite each value or rewrite all the values at once. I suppose it would have to be somewhere in the field handler...

(Edit: Duh... I just realized that's exactly where you proposed your change as well! At least we're clearly thinking along the same lines!)

I've got a feeling that this is going to be too much change, too late in the product. And there's no reason it can't be done in contrib.

I've been thinking about this idea for a while now -- I'm happy to fiddle with it and roll a patch, but I don't want to hijack your issue and change its scope. Let me know if you'd prefer this in a separate issue or not. (assuming I can make it work...)

kaare’s picture

Oh, I don't care much about the solution of this problem, as long as it's possible for site builders/themers to do it. Even though … the ability to override the field with a twig template with all individual items available seems far more generic than using <ul> for count > 2 and no html without.

If we can argument that this feature doesn't disrupt the 8.0.x target, I think it's a valid candidate. It would bring much flexibility for site builders.

So sure, hijack away.

mikeker’s picture

Issue tags: +Needs tests
FileSize
5.96 KB
21.89 KB

OK, hijacking away! :P

The attached patch provides a "Render all items together" option when "Display all values in the same row" is checked. When enabled, multi-valued fields in a Views row will run renderAltered() once for each field rather than once for each value in each field. In addition, a foo_multiple is added so you can render the field using Twig.

To solve the initial use case -- rendering a single value (field_tags, in this case) as plain HTML and multiple values as a <ul> -- you would check the "Render all items together" option and use a rewrite similar to the following:

{% if field_tags_multiple|length > 1 %}
  <ul>
  {% for item in field_tags_multiple %}
    <li>{{ item }}</li>
  {% endfor %}
  </ul>
{% elseif field_tags_multiple|length == 1  %}
  {{ field_tags_multiple|first }}
{% else %}
  There are no tags for this item.
{% endif %}

The result is:

mikeker’s picture

Title: Option to not render multivalue fields with only one value as HTML lists in views » Allow multi-value field rendering to pass through Views rewrite only once
Assigned: Unassigned » mikeker
Status: Needs work » Needs review

Things still to work on:

1. UI cleanup, could use a better explanation of what this new option really does. As was suggested by @kaare, there should be a doc page on d.o that could be linked to from the description.

2. I really want someone that knows Twig and security to tell me if there's a problem with the "unfiltering" I'm doing of admin-entered Twig:

    // Xss::filterAdmin encodes '>' and '<' to '&gt;' and '&lt;'. Since these
    // are both valid in Twig, we un-encode those that appear within block
    // delimiters ('{%' and '%}') before handing it back to Twig for processing.
    $text = preg_replace(
      ['/\{%([\s\S]*?)&gt;([\s\S]*?)%\}/', '/\{%(.*?)&lt;(.*?)%\}/'],
      ['{%$1>$2%}', '{%$1<$2%}'],
      $text
    );

I'm trying to keep the un-encoding as limited as possible, but you never know...

#2 is actually a more generic issue and, if this issue gets postponed it might be worth a separate issue for that. Otherwise something like {% if foo|length > 1 %} causes Twig to barf. And that seems like a crucial fix if #2342287: Allow Twig in Views token replacement is going to be worth anything...

mikeker’s picture

Summary update. Hiding screenshots that are no longer valid with the new approach and (in case we return to the former fix) everything except the most recent patch of the previous approach that got a green from the testbot.

mikeker’s picture

Status: Needs review » Needs work

The last submitted patch, 10: 2055597-10_multi-item-field-rendering.patch, failed testing.

mikeker’s picture

Status: Needs work » Needs review
FileSize
6.53 KB
2.55 KB

Hopefully fixes tests... Let's see what the testbot thinks!

star-szr’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll

Tagging for reroll.

jyotisankar’s picture

Status: Needs work » Needs review
FileSize
6.9 KB

Rerolled

star-szr’s picture

Status: Needs review » Needs work
Issue tags: -Needs reroll

Thanks @jyotisankar, a couple things I noticed…

  1. +++ b/core/modules/field/config/schema/field.views.schema.yml
    diff --git a/core/modules/views/src/Plugin/views/PluginBase.php b/core/modules/views/src/Plugin/views/PluginBase.php
    old mode 100644
    new mode 100755
    
    +++ b/core/modules/views/src/Plugin/views/field/Field.php
    diff --git a/core/modules/views/src/Plugin/views/field/FieldPluginBase.php b/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
    old mode 100644
    new mode 100755
    

    Mode changes snuck in.

  2. +++ b/core/modules/views/src/Plugin/views/PluginBase.php
    @@ -364,6 +364,15 @@ protected function viewsTokenReplace($text, $tokens) {
    +    ¶
    
    +++ b/core/modules/views/src/Plugin/views/field/Field.php
    @@ -522,7 +526,21 @@ function multiple_options_form(&$form, FormStateInterface $form_state) {
    +    ¶
    
    +++ b/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
    @@ -1145,7 +1151,20 @@ public function advancedRender(ResultRow $values) {
    +          ¶
    ...
    +          ¶
    

    Unwanted trailing whitespace snuck in.

star-szr’s picture

Issue tags: +Needs reroll

For me this rebases cleanly following the steps at http://drupal.org/patch/reroll with no conflicts. Maybe give it another shot @jyotisankar?

mikeker’s picture

While there are other eyes looking at this issue, I would love some feedback on what I'm doing as mentioned in #11 -- see item #2 in that comment.

Thanks!

mikeker’s picture

Status: Needs work » Needs review
FileSize
5.55 KB

Reroll.

mikeker’s picture

Issue tags: -Needs reroll

The patch in #21 still applies. Forgot to remove the "needs reroll" tag...

mikeker’s picture

Assigned: mikeker » Unassigned

Added child issue to deal with #11. If we can get that into core, we may be able to handle this in contrib...

mikeker’s picture

Category: Feature request » Task
star-szr’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll

Tagging for reroll.

Nitesh Sethia’s picture

Status: Needs work » Needs review
FileSize
6.66 KB

Rerolled the patch.

Status: Needs review » Needs work

The last submitted patch, 27: allow_multi_value_field-2055597-27.patch, failed testing.

mikeker’s picture

#21 still applies for me. Running it past the testbot to be sure...

#27 seems to add a bunch of unrelated stuff to the Views field schema.

The last submitted patch, 21: 2055597-21-field-render-multivalue.patch, failed testing.

mikeker’s picture

Ack... Nevermind, I was on an experimental branch. Will reroll #21 shortly.

mikeker’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
FileSize
5.55 KB

Looks like the schema definition for views.field.field moved from field.views.schema.yml to views.field.schema.yml.

Yeah, that's not confusing!

star-szr’s picture

Issue summary: View changes
Status: Needs review » Needs work

Updating the issue summary to remove this stuff #2466931: Valid Twig syntax is incorrectly escaped in Views rewrites. Needs work for the test coverage.

mikeker’s picture

Note: tests for this are potentially blocked on #2346615: Views doesn't have multi-valued field unit tests.

mikeker’s picture

Following an IRC conversation with @dawener, he suggested refactoring advancedRender to wrap a new doAdvancedRender (or possibly doAdvancedRenderText to clarify what we're rendering) and push the code that does the multi-value parsing into Field.php.

That avoids the need to do things like:

+++ b/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
@@ -1138,8 +1138,15 @@ public function advancedRender(ResultRow $values) {
+        if ($this instanceof Field && $this->options['group_rows_render_together'] && $this->options['alter']['alter_text']) {

Also the existing if ($this instanceof MultiItemsFieldHandlerInterface) in FieldPluginBase would be removed.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.