Quantcast
Viewing all 294706 articles
Browse latest View live

Add contextual menu item on blocks to allow disabling them

Problem/Motivation

It is currently possible to edit and remove a block from the front-end theme using the contextual menu, this provides quick access to manage blocks without having to load the Block Layout admin page and is great for making quick edits to the blocks. The full Block Layout admin page provides a third option - to disable the block; it would be very useful if this option were to be available from the contextual menu.

Proposed resolution

Provide a contextual menu to disable a given block.

Remaining tasks

Provide a patch with the suggested change.

User interface changes

Contextual menus for blocks would include a new option to disable that block.

API changes

TBD

Data model changes

TBD

Release notes snippet

TBD


Finish deprecating status code and header assertions in JS tests

Problem/Motivation

\Drupal\FunctionalJavascriptTests\WebDriverWebAssert has a number of deprecation errors, e.g.

    @trigger_error('Support for statusCodeEquals is to be dropped from JavaScript tests. See https://www.drupal.org/node/2857562.');

This was added in 8.5.0, we should either actually drop this support, or reinstate it.

Steps to reproduce

Proposed resolution

- create meta issue to get rid of usage
- change deprecation message according standards for 11.0

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

'The "%plugin_id" was not found' warning message is confusing

Problem/Motivation

The warning message 'The "%plugin_id" was not found' warning when importing block config is misleading because it doesn't make clear what kind of thing it's talking about. As a consequence, it leaves you wondering if you broke something, and if so, what that would be. Take the following examples:

  • The "help_block" was not found
  • The "field_block:node:example:body" was not found
  • The "block_content:aa33cb62-047a-4695-a523-aa43266c2bb3" was not found

Without explicit knowledge that these are plugin IDs, what are they talking about? Do these represent missing config dependencies I need to fix? Did it fail to find an important YAML file? Will the corresponding functionality be there if I go looking for it in the UI?

Based on #3180467: Warning "views_block:x was not found" when importing config, probably nothing actually went wrong and nothing is broken. But most people won't know that or be able to easily find out.

Steps to reproduce

You can just export some block config and then re-import it, but really it's enough to just see the message: BlockManager::handlePluginNotFound().

Proposed resolution

Just add the word "plugin" or even "block plugin" to the warning message to make it clear what it's even talking about. For example:

The "field_block:node:example:body" block plugin was not found

As to making the warning actionable. I (TravisCarden) am not sure what can be done without making it even more misleading until the underlying problem can be solved in #3180467: Warning "views_block:x was not found" when importing config.

Remaining tasks

User interface changes

Allow password on registration without disabling e-mail verification

Problem/Motivation

When configuring password behaviour on the registration form, there is no way to force the rendering of the password fields on the registration form if e-mail confirmation is enabled.

An option to configure / force the password fields on the user registration form, while e-mail verification is enabled, might offer a way for site owners to alter the process and make it fit more to their case. (flexibility++)

There is a module that offers this behaviour in Drupal 7, called User Registration Password, the current concept patch started with code that's partially based on this module, but evolved a bit beyond this.

Proposed resolution

Develop a patch that offers minimal functionality. Patch exists, see #58.

Remaining tasks

User interface changes

  • Adds 1 checkbox on the 'admin/config/people/accounts' page.
  • The patch will add 2 extra e-mail templates for sending a welcome and activation e-mail.

API changes

  • Adds 1 new variable: 'password_register'.

Screenshots

Before:
Image may be NSFW.
Clik here to view.
password option before

After:
Image may be NSFW.
Clik here to view.
password option after

First screenshot:
Image may be NSFW.
Clik here to view.
First screenshot

Second screenshot:
Image may be NSFW.
Clik here to view.
Second screenshot

Possible checkbox combinations:

[X] Require e-mail verification when a visitor creates an account.
[_] Require people to choose a password during registration.
This is the first screenshot, people are not able to set a password during registration, because verification is enabled.

[X] Require e-mail verification when a visitor creates an account.
[X] Require people to choose a password during registration.
This is the second screenshot, people are required to set a password during registration, while verification is enabled.

[_] Require e-mail verification when a visitor creates an account.
[..] Require people to choose a password during registration.
No separate screenshot, but this is the same as the second screenshot, users need to set a password during registration and are directly authenticated after submit. [..] is the disabled checkbox (via #states).

Notes

This patch overrides the 'status' on the submit form for new users and set the status to '0' (disabled). This makes it possible to facilitate our new option and functionality with minimal changes to the existing code.

The current patch also implements a change in user_pass_reset() to facilitate re-sending password_register activation e-mails to users that never logged in yet. (and also didn't receive the first activation e-mail.) They can re-request it via the password reset page.

For Drupal 8 the current patch works, but while it does already improve the account options a bit, some wonder if we should implement this as-is, without implementing some new account status workflow first.

For Drupal 9 we might want to think about refactoring the workflow even more, really decouple the password option from the 'verify' code, and maybe even implement a workflow for accounts, but most people agree to continue with the current patch / idea and focus on more / bigger changes in D9.
(possible future issue: Decouple 'email verify' and 'password' options.)

Original report by finalternatives

Hi, I run a daily news site and have been getting a lot of complaints about people who say it is confusing to log in using the temporary password. Is it possible to have people choose their own password when signing up? Ideally they would then receive an email telling them to click on the link to verify the account. My guess is that people log in the first time and then are too lazy to change the password, and when they return to the site they can’t log in again.

Does anyone have any other ideas for streamlining the registration/login process to make it more user friendly?

Unable to parse core/modules/mysql/mysql.info.yml as it does not exist

Just upgrade to D10.3.0

1) Drupal\Tests\ua_arop_module\Kernel\UaAropServiceTest::testUaAropServiceBasics
Drupal\Core\Extension\InfoParserException: Unable to parse core/modules/mysql/mysql.info.yml as it does not exist

/code/web/core/lib/Drupal/Core/Extension/InfoParserDynamic.php:40
/code/web/core/lib/Drupal/Core/Extension/InfoParser.php:47
/code/web/core/lib/Drupal/Core/Extension/DatabaseDriver.php:216
/code/web/core/lib/Drupal/Core/Extension/DatabaseDriver.php:166
/code/web/core/lib/Drupal/Core/Database/Database.php:589
/code/web/core/tests/Drupal/KernelTests/KernelTestBase.php:492
/code/web/core/tests/Drupal/KernelTests/KernelTestBase.php:299
/code/web/core/tests/Drupal/KernelTests/KernelTestBase.php:269
/code/web/modules/contrib/token/tests/src/Kernel/KernelTestBase.php:31
/code/web/modules/custom/ua_arop_module/tests/src/Kernel/UaAropServiceTest.php:33
/code/vendor/phpunit/phpunit/src/Framework/TestResult.php:729

--

BC break in login auth changes from #3444978

Problem/Motivation

#3410582: Optimize user logins by avoiding duplicate entity queries refactored the user login process to optimise queries. To do that, it introduced a new UserAuthenticationInterface (see https://www.drupal.org/node/3411040). This was done with a BC layer in place, but that had some bugs affecting e.g. mail_login.

#3444978: UserAuth BC layer is not working for modules that use it to provide email based logins attempted to fix that, but in doing so actually broke things for email_registration (see #3456461: [2.x] Login fails with Drupal 10.3). The issue is that it moves the BC else into an elseif one level up in the code, which means it is never executed in the case of email_registration, where an account is returned, but the old interface is implemented.

This is then rather difficult to solve in email_registration because whilst different classes can be swapped out, static analysis will fail without the correct versions etc.

Steps to reproduce

Install Drupal 10.3 and Email Registration 2.x - you cannot log in.

Proposed resolution

  1. Fix UserLogin::validateAuthenticate; perhaps move all the authentication finalisation to the end of the method with a BC if/else rather than trying to do inline with flood etc.
  2. Given this is supposed to be a BC compatible change, probably some tests that swap out for the old interface would be a worthwhile investment.

Remaining tasks

Fix & test.

User interface changes

M/A

API changes

N/A

Data model changes

N/A

Release notes snippet

Fixes BC breaks in UserLoginForm.

Add a "context" array variable to all theme hooks and "#context" array property to all elements to provide optional contextual data

Problem/Motivation

Fairly often there is a need for some sort of contextual data when rendering an element, which parts of, ultimately needs to make its way down the theme system pipeline.

This is especially true when certain render elements or theme hooks, that are not normally aware of the context in which they'll be rendered, needs additional information to provide rendering variations (i.e. per type or identifier).

While it is possible to add any variable you want in preprocess functions, it is often too late in the process and the original data that usually contains the needed information has long since been lost.

This is, in part, due to arbitrary properties (not registered in the theme hook) from being automatically transferred from a renderable element's properties.

Example from the search module in core, where a 'context' variable was manually added to allow for this flexibility (#2495419: Move the 'search-results' class from the render array and into a Classy template):

$build['search_results'] = [
  '#theme' => ['item_list__search_results__' . $plugin->getPluginId(), 'item_list__search_results'],
  //...
  '#context' => ['plugin' => $plugin->getPluginId()],
];

Another example of use is for Views suggestions (which this issue is blocking): #2923634: [PP-1] Use hook_theme_suggestions in views.

Proposed resolution

Add a context variable as an empty array for all theme hooks, if one doesn't already exist.

Add a #context property as an empty array to all elements, if one doesn't already exist.

Remaining tasks

  • Create test(s)
  • Create patch

User interface changes

None

API changes

  • The addition of a default #context property added to all elements
  • The addition of a default context property added to all theme hooks (for preprocessing purposes only)
  • The automatic mapping of a renderable element's #context property to the context variable
  • Removal of the context variable immediately prior to rendering (for security concerns).

Data model changes

None

Last read comment field/filter/argument uses still the node.changed instead of node_field_data.changed column

Updated: Comment 0

Problem/Motivation

Comment entity statistics view plugins are broken and there's no tests.
They are not properly ported to interact with entities other then nodes.
There's no way to detect the name of the "changed" field for entities that implements EntityChangedInterface

Proposed resolution

Probably needs to check that commented entity type implements \Drupal\Core\Entity\EntityChangedInterface and expose this field only for this entity types

Remaining tasks

Fix views integration with comment statistics and cover with tests.

User interface changes

API changes


Update loading icon and use SVG

Problem/Motivation

The animated GIFs loading.gif and loading-small.gif icons look poor on HiDPI displays.

Note: some instances of .ajax-progress-throbber currently reference loading-small.gif, while others reference throbber-active.gif. throbber-active.gif is being worked on in a separate issue #1974928.

Proposed resolution

  • Replace the animated GIF file loading.gif with an animated scalable vector graphic (SVG) loading.svg that matches the look and feel.

  • Replace the animated GIF file loading-small.gif with an animated scalable vector graphic (SVG) loading-small.svg that matches the look and feel.

  • Update all references in Drupal core where loading-small.gif was previously used in the CSS background-image, including some instances of .ajax-progress-throbber and all instances of .ajax-progress-fullscreen. Since loading.gif is not referenced anywhere in Drupal core except in a single test, no CSS or IMG tag changes are required for this image.

  • Add an .htaccess RedirectRule to forward requests to the deleted GIF images to their respective SVG image equivalents.

Before / After comparison:

  1. loading.gif => loading.svg
    https://codepen.io/jameswilson/pen/OJYXqZE

  2. loading-small.gif => loading-small.svg
    https://codepen.io/jameswilson/pen/oNRLVxx

Remaining tasks

  1. Use the visual style / look of the existing loading GIF.
  2. Create an SVG based on ^ and animate it.
  3. Create an MR.
  4. Review and commit.

User interface changes

Users on devices with high resolution screens will see a modern, crisp image with no diffusion artifacts or blur inherent from legacy image formats.

Users on devices with low resolution may or may not notice any visual difference.

API changes

In as much as images can be considered an "API", the old GIF files will be removed. In case any themes still reference the old images, the routes to these static assets can be redirected at the server level to the new SVG assets. Such redirects have been added to the .htaccess file shipped with Drupal core.

Data model changes

None.

Release notes snippet

Not necessary.

View with Contextual Filter & Relationship displays WSD in 10.3.0

Problem/Motivation

I have a content type of Room that has an entity reference field to another content type, Organisation. I have a view that lists rooms, using the entity reference field as a relationship to display fields from the related Organisation nodes. I have a view with two displays, the first one lists all the rooms in a table, grouped by the Organisation title (this works fine) and the second uses a contextual filter on the Organisation to show the Rooms for the organisation (filtered by the node ID from the URL). When I view an organisation and it's rooms on the second view, I get a white screen of death since upgrading to Drupal 10.3.0

Steps to reproduce

Upgrade to to Drupal 10.3.0
View the complete list of Rooms by Organisation
Click on the link to one of the Organisations to display the those rooms filtered by that organisation
WSD

Proposed resolution

I can list Organisations by the Content page and edit them. This seems to be an issue with Views that use contextual filters and relationships. The config export is below and I've confirmed the config for the view does not change when I upgrade drupal core. The issue is with block_1

For now I will need to revert to 10.2.7

uuid: 0daff11f-5427-4fcf-bc52-cc8da491b65a
langcode: en
status: true
dependencies:
  config:
    - core.entity_view_mode.node.teaser
    - field.storage.node.body
    - field.storage.node.field_type
    - node.type.room
    - user.role.authenticated
  module:
    - node
    - options
    - text
    - user
_core:
  default_config_hash: wCGRBQ2612zX9UGIoUV0_LfKS2TJ9NbtHDarusKBX20
id: cil_meet
label: 'CIL Meet'
module: views
description: ''
tag: ''
base_table: node_field_data
base_field: nid
display:
  default:
    id: default
    display_title: Master
    display_plugin: default
    position: 0
    display_options:
      title: 'CIL Meet'
      fields:
        body:
          id: body
          table: node__body
          field: body
          relationship: field_organisation
          group_type: group
          admin_label: ''
          plugin_id: field
          label: ''
          exclude: true
          alter:
            alter_text: false
            text: ''
            make_link: false
            path: ''
            absolute: false
            external: false
            replace_spaces: false
            path_case: none
            trim_whitespace: false
            alt: ''
            rel: ''
            link_class: ''
            prefix: ''
            suffix: ''
            target: ''
            nl2br: false
            max_length: 0
            word_boundary: true
            ellipsis: true
            more_link: false
            more_link_text: ''
            more_link_path: ''
            strip_tags: false
            trim: false
            preserve_tags: ''
            html: false
          element_type: ''
          element_class: ''
          element_label_type: ''
          element_label_class: ''
          element_label_colon: false
          element_wrapper_type: ''
          element_wrapper_class: ''
          element_default_classes: true
          empty: ''
          hide_empty: false
          empty_zero: false
          hide_alter_empty: true
          click_sort_column: value
          type: text_summary_or_trimmed
          settings:
            trim_length: 600
          group_column: value
          group_columns: {  }
          group_rows: true
          delta_limit: 0
          delta_offset: 0
          delta_reversed: false
          delta_first_last: false
          multi_type: separator
          separator: ', '
          field_api_classes: false
        title_1:
          id: title_1
          table: node_field_data
          field: title
          relationship: field_organisation
          group_type: group
          admin_label: ''
          entity_type: node
          entity_field: title
          plugin_id: field
          label: ''
          exclude: true
          alter:
            alter_text: true
            text: "<h2>{{ title_1 }}</h2>\r\n{{ body }}"
            make_link: false
            path: ''
            absolute: false
            external: false
            replace_spaces: false
            path_case: none
            trim_whitespace: false
            alt: ''
            rel: ''
            link_class: ''
            prefix: ''
            suffix: ''
            target: ''
            nl2br: false
            max_length: 0
            word_boundary: true
            ellipsis: true
            more_link: false
            more_link_text: ''
            more_link_path: ''
            strip_tags: false
            trim: false
            preserve_tags: ''
            html: false
          element_type: ''
          element_class: ''
          element_label_type: ''
          element_label_class: ''
          element_label_colon: false
          element_wrapper_type: ''
          element_wrapper_class: ''
          element_default_classes: false
          empty: ''
          hide_empty: false
          empty_zero: false
          hide_alter_empty: true
          click_sort_column: value
          type: string
          settings:
            link_to_entity: true
          group_column: value
          group_columns: {  }
          group_rows: true
          delta_limit: 0
          delta_offset: 0
          delta_reversed: false
          delta_first_last: false
          multi_type: separator
          separator: ', '
          field_api_classes: false
        title:
          id: title
          table: node_field_data
          field: title
          relationship: none
          group_type: group
          admin_label: ''
          entity_type: node
          entity_field: title
          plugin_id: field
          label: 'Room (click/tap to join)'
          exclude: false
          alter:
            alter_text: false
            text: ''
            make_link: false
            path: ''
            absolute: false
            external: false
            replace_spaces: false
            path_case: none
            trim_whitespace: false
            alt: ''
            rel: ''
            link_class: ''
            prefix: ''
            suffix: ''
            target: ''
            nl2br: false
            max_length: 0
            word_boundary: false
            ellipsis: false
            more_link: false
            more_link_text: ''
            more_link_path: ''
            strip_tags: false
            trim: false
            preserve_tags: ''
            html: false
          element_type: ''
          element_class: ''
          element_label_type: ''
          element_label_class: ''
          element_label_colon: true
          element_wrapper_type: ''
          element_wrapper_class: ''
          element_default_classes: true
          empty: ''
          hide_empty: false
          empty_zero: false
          hide_alter_empty: true
          click_sort_column: value
          type: string
          settings:
            link_to_entity: true
          group_column: value
          group_columns: {  }
          group_rows: true
          delta_limit: 0
          delta_offset: 0
          delta_reversed: false
          delta_first_last: false
          multi_type: separator
          separator: ', '
          field_api_classes: false
        body_1:
          id: body_1
          table: node__body
          field: body
          relationship: none
          group_type: group
          admin_label: ''
          plugin_id: field
          label: Description
          exclude: false
          alter:
            alter_text: false
            text: ''
            make_link: false
            path: ''
            absolute: false
            external: false
            replace_spaces: false
            path_case: none
            trim_whitespace: false
            alt: ''
            rel: ''
            link_class: ''
            prefix: ''
            suffix: ''
            target: ''
            nl2br: false
            max_length: 0
            word_boundary: true
            ellipsis: true
            more_link: false
            more_link_text: ''
            more_link_path: ''
            strip_tags: false
            trim: false
            preserve_tags: ''
            html: false
          element_type: ''
          element_class: ''
          element_label_type: ''
          element_label_class: ''
          element_label_colon: true
          element_wrapper_type: ''
          element_wrapper_class: ''
          element_default_classes: true
          empty: ''
          hide_empty: false
          empty_zero: false
          hide_alter_empty: true
          click_sort_column: value
          type: text_default
          settings: {  }
          group_column: value
          group_columns: {  }
          group_rows: true
          delta_limit: 0
          delta_offset: 0
          delta_reversed: false
          delta_first_last: false
          multi_type: separator
          separator: ', '
          field_api_classes: false
        field_type:
          id: field_type
          table: node__field_type
          field: field_type
          relationship: none
          group_type: group
          admin_label: ''
          plugin_id: field
          label: Type
          exclude: false
          alter:
            alter_text: true
            text: "{% if field_type[:7] == 'Classic' %}\r\n\r\n{% else %}\r\n{{ field_type }}\r\n{% endif %}"
            make_link: false
            path: ''
            absolute: false
            external: false
            replace_spaces: false
            path_case: none
            trim_whitespace: false
            alt: ''
            rel: ''
            link_class: ''
            prefix: ''
            suffix: ''
            target: ''
            nl2br: false
            max_length: 0
            word_boundary: true
            ellipsis: true
            more_link: false
            more_link_text: ''
            more_link_path: ''
            strip_tags: false
            trim: false
            preserve_tags: ''
            html: false
          element_type: ''
          element_class: ''
          element_label_type: ''
          element_label_class: ''
          element_label_colon: true
          element_wrapper_type: ''
          element_wrapper_class: ''
          element_default_classes: true
          empty: ''
          hide_empty: false
          empty_zero: false
          hide_alter_empty: true
          click_sort_column: value
          type: list_default
          settings: {  }
          group_column: value
          group_columns: {  }
          group_rows: true
          delta_limit: 0
          delta_offset: 0
          delta_reversed: false
          delta_first_last: false
          multi_type: separator
          separator: ', '
          field_api_classes: false
      pager:
        type: none
        options:
          offset: 0
      exposed_form:
        type: basic
        options:
          submit_button: Apply
          reset_button: false
          reset_button_label: Reset
          exposed_sorts_label: 'Sort by'
          expose_sort_order: true
          sort_asc_label: Asc
          sort_desc_label: Desc
      access:
        type: role
        options:
          role:
            authenticated: authenticated
      cache:
        type: tag
        options: {  }
      empty:
        area_text_custom:
          id: area_text_custom
          table: views
          field: area_text_custom
          relationship: none
          group_type: group
          admin_label: ''
          plugin_id: text_custom
          empty: true
          content: 'No results'
          tokenize: false
      sorts:
        title:
          id: title
          table: node_field_data
          field: title
          relationship: field_organisation
          group_type: group
          admin_label: ''
          entity_type: node
          entity_field: title
          plugin_id: standard
          order: ASC
          expose:
            label: ''
            field_identifier: title
          exposed: false
        title_1:
          id: title_1
          table: node_field_data
          field: title
          relationship: none
          group_type: group
          admin_label: ''
          entity_type: node
          entity_field: title
          plugin_id: standard
          order: ASC
          expose:
            label: ''
            field_identifier: title_1
          exposed: false
      arguments: {  }
      filters:
        status:
          id: status
          table: node_field_data
          field: status
          entity_type: node
          entity_field: status
          plugin_id: boolean
          value: '1'
          group: 1
          expose:
            operator: ''
            operator_limit_selection: false
            operator_list: {  }
        type:
          id: type
          table: node_field_data
          field: type
          entity_type: node
          entity_field: type
          plugin_id: bundle
          value:
            room: room
          expose:
            operator_limit_selection: false
            operator_list: {  }
        sticky:
          id: sticky
          table: node_field_data
          field: sticky
          relationship: none
          group_type: group
          admin_label: ''
          entity_type: node
          entity_field: sticky
          plugin_id: boolean
          operator: '='
          value: '1'
          group: 1
          exposed: false
          expose:
            operator_id: ''
            label: ''
            description: ''
            use_operator: false
            operator: ''
            operator_limit_selection: false
            operator_list: {  }
            identifier: ''
            required: false
            remember: false
            multiple: false
            remember_roles:
              authenticated: authenticated
          is_grouped: false
          group_info:
            label: ''
            description: ''
            identifier: ''
            optional: true
            widget: select
            multiple: false
            remember: false
            default_group: All
            default_group_multiple: {  }
            group_items: {  }
        langcode:
          id: langcode
          table: node_field_data
          field: langcode
          relationship: none
          group_type: group
          admin_label: ''
          entity_type: node
          entity_field: langcode
          plugin_id: language
          operator: in
          value:
            '***LANGUAGE_language_interface***': '***LANGUAGE_language_interface***'
          group: 1
          exposed: false
          expose:
            operator_id: ''
            label: ''
            description: ''
            use_operator: false
            operator: ''
            operator_limit_selection: false
            operator_list: {  }
            identifier: ''
            required: false
            remember: false
            multiple: false
            remember_roles:
              authenticated: authenticated
            reduce: false
          is_grouped: false
          group_info:
            label: ''
            description: ''
            identifier: ''
            optional: true
            widget: select
            multiple: false
            remember: false
            default_group: All
            default_group_multiple: {  }
            group_items: {  }
        langcode_1:
          id: langcode_1
          table: node_field_data
          field: langcode
          relationship: field_organisation
          group_type: group
          admin_label: ''
          entity_type: node
          entity_field: langcode
          plugin_id: language
          operator: in
          value:
            '***LANGUAGE_language_interface***': '***LANGUAGE_language_interface***'
          group: 1
          exposed: false
          expose:
            operator_id: ''
            label: ''
            description: ''
            use_operator: false
            operator: ''
            operator_limit_selection: false
            operator_list: {  }
            identifier: ''
            required: false
            remember: false
            multiple: false
            remember_roles:
              authenticated: authenticated
            reduce: false
          is_grouped: false
          group_info:
            label: ''
            description: ''
            identifier: ''
            optional: true
            widget: select
            multiple: false
            remember: false
            default_group: All
            default_group_multiple: {  }
            group_items: {  }
      style:
        type: table
        options:
          grouping:
            -
              field: title_1
              rendered: true
              rendered_strip: false
          row_class: ''
          default_row_class: true
          columns:
            body: body
            title_1: title_1
            title: title
            body_1: body_1
          default: '-1'
          info:
            body:
              sortable: false
              default_sort_order: asc
              align: ''
              separator: ''
              empty_column: false
              responsive: ''
            title_1:
              sortable: false
              default_sort_order: asc
              align: views-align-left
              separator: ''
              empty_column: true
              responsive: ''
            title:
              sortable: false
              default_sort_order: asc
              align: views-align-left
              separator: ''
              empty_column: false
              responsive: ''
            body_1:
              sortable: false
              default_sort_order: asc
              align: views-align-left
              separator: ''
              empty_column: false
              responsive: ''
          override: true
          sticky: false
          summary: ''
          empty_table: false
          caption: ''
          description: ''
      row:
        type: 'entity:node'
        options:
          view_mode: teaser
      query:
        type: views_query
        options:
          query_comment: ''
          disable_sql_rewrite: false
          distinct: false
          replica: false
          query_tags: {  }
      relationships:
        field_organisation:
          id: field_organisation
          table: node__field_organisation
          field: field_organisation
          relationship: none
          group_type: group
          admin_label: 'field_organisation: Content'
          plugin_id: standard
          required: true
      header: {  }
      footer: {  }
      display_extenders: {  }
    cache_metadata:
      max-age: -1
      contexts:
        - 'languages:language_content'
        - 'languages:language_interface'
        - 'user.node_grants:view'
        - user.roles
      tags:
        - 'config:field.storage.node.body'
        - 'config:field.storage.node.field_type'
  block_1:
    id: block_1
    display_title: 'Organisation Index Block'
    display_plugin: block
    position: 2
    display_options:
      arguments:
        nid:
          id: nid
          table: tracker_node
          field: nid
          relationship: field_organisation
          group_type: group
          admin_label: ''
          plugin_id: node_nid
          default_action: default
          exception:
            value: all
            title_enable: false
            title: All
          title_enable: false
          title: ''
          default_argument_type: node
          default_argument_options: {  }
          summary_options:
            base_path: ''
            count: true
            override: false
            items_per_page: 25
          summary:
            sort_order: asc
            number_of_records: 0
            format: default_summary
          specify_validation: false
          validate:
            type: none
            fail: 'not found'
          validate_options: {  }
          break_phrase: false
          not: false
      defaults:
        fields: true
        arguments: false
      display_description: ''
      display_extenders: {  }
      block_description: 'CIL Meet Rooms for an Organisation'
    cache_metadata:
      max-age: -1
      contexts:
        - 'languages:language_content'
        - 'languages:language_interface'
        - url
        - 'user.node_grants:view'
        - user.roles
      tags:
        - 'config:field.storage.node.body'
        - 'config:field.storage.node.field_type'
  block_2:
    id: block_2
    display_title: 'Main Page Block'
    display_plugin: block
    position: 1
    display_options:
      display_description: ''
      display_extenders: {  }
      block_description: 'CIL Meet Rooms by Organisation'
    cache_metadata:
      max-age: -1
      contexts:
        - 'languages:language_content'
        - 'languages:language_interface'
        - 'user.node_grants:view'
        - user.roles
      tags:
        - 'config:field.storage.node.body'
        - 'config:field.storage.node.field_type'

Sort::fields property is incorrectly defined as a string

Problem/Motivation

In \Drupal\jsonapi\Query\Sort, the property $fields is defined as a string, when it is an array. This causes IDEs such as VSCode to flag iteration of the array as an error when it is not.

Steps to reproduce

In an IDE, write something like

$fields = [
  ['path' => 'changed', 'direction' => 'DESC'], 
  ['path' => 'title', 'direction' => 'ASC'],
];
$sort = new \Drupal\jsonapi\Query\Sort($fields);
foreach ($sort->fields() as $field) {
  echo $field['path'];
}

The IDE will complain "Expected type 'iterable|object'. Found 'string'."

Proposed resolution

Define the $fields property as @var array instead of string.

Allow tokens to be used in Text Editor/CKEditor 5 image upload directory path

Allow Drupal date tokens to be used in the "Upload Directory" path, much like they are used for the upload path in Image fields of Content Types.

That way instead of inline-images one could have inline-images/[date:custom:Y]/[date:custom:m]

Use comment access handler instead of hardcoding permissions

Problem/Motivation

The comment module comes with a CommentAccessControlHandler which is not really used on crucial places. Instead of using this handler, there are dozens of places, where the permissions provided by the comment module are checked directly (e.g. post comment permission checks instead of $entity->access('create') or access comments permission checks instead of $entity->access('view')).

For example, the $entity->access('create') access check is only used during comment link generation, but not for the comment form itself.

Due to this, it is currently impossible to create a custom access control handler for comment entities, as it would not be used where necessary. When reading through the code, you can also see there is a lot of access-related duplicate code (because the permission checks duplicate the access checks of the access control handler).

These changes will affect other issues as well, when those deal with comment access/permissions, but they are very important to get the comment entity access handling correct.

Proposed resolution

  • Scan through the code and eliminate all permission checks with proper $entity->access() checks. Search for the following permissions:
    • access comments
    • post comments
    • edit own comments

    The <em>administer comments</em> permission has been split in #3180177: [PP-2] Replaces usages of 'administer comments' permission w/ access handler checks in order to limit the scope of this issue.

  • If possible, the commenting status of the parent ID should be taken into account in the access control handler checks. As this status flag affects the entity access for certain operations, its checks should also be centralized in the access control handler
  • On "create access" the commented entity and, on comment replying, the parent comment should be passed as context as they might contain valuable information for a custom comment entity access control handler when making the decision.
  • Comment-related tests should still work as before, because only the access checking behavior is changed, but not the access requirements themselves

Remaining tasks

None.

User interface changes

None.

API changes

The current comments access checks behaviour can be altered by swapping the comment access control handler and implementing a custom access logic.

Data model changes

None.

Update Drupal's default throbber icons

Problem/Motivation

The default AJAX progress throbber icons looks poor on a retina display.

Note: some instances of .ajax-progress-throbber currently reference throbber-active.gif, while others reference loading-small.gif. loading-small.gif is being worked on in a separate issue #2575253.

Proposed resolution

  • Replace throbber-active.gif with a high resolution animated SVG throbber-active.svg.
  • Replace throbber-inactive.png with a high resolution static SVG throbber-inactive.svg.
  • Maintain existing image size, color, and animation speed from the originals.
  • Replace references to each file in core ajax-progress and autocomplete stylesheets.
  • Replace references to each file Stable theme.
  • Redirect old GIFs to new SVGs in core's bundled .htaccess file.

Codepen for before/after comparison:
https://codepen.io/jameswilson/full/LYoZaXy

Before:

Inactive: Image may be NSFW.
Clik here to view.
PNG ajax progress throbber inactive

Active: Image may be NSFW.
Clik here to view.
GIF ajax progress throbber active

After:

Inactive: throbber-inactive.svg
Active: throbber-active.svg

Note: server limitations on uploading SVGs and/or rendering images from git.drupalcode.org prevent us from displaying the proposed SVGs inline here. See the Codepen for a better comparison.

Remaining tasks

  1. Ensure that overriding throbber's is as easy as possible and provide instructions for how themers can use libraries-override.
    COMPLETE: (See Docs → Theming Drupal → Update the throbber
  2. Override core's default throbber design in the Olivero theme, to help document an approach for themers to follow.
    COMPLETE: (See Olivero's throbber.svg).
  3. Create a patch.
  4. Review the code changes.
  5. Manually test and upload before/after screenshots.
  6. Since Seven was removed from core, copy issue credits from folks who worked on #2775725: Update throbber icon in Seven theme that was split out from this issue while Seven theme was still in core.

User interface changes

Users on devices with high resolution screens will see a crisp image with no diffusion artifacts or blur inherent from legacy image formats.

Users on devices with low resolution may or may not notice much of a visual difference.

API changes

In as much as images can be considered an "API", the old GIF files will be removed. In case any themes still reference the old images, the routes to these static assets can be redirected at the server level to the new SVG assets. Such redirects have been added to the .htaccess file shipped with Drupal core.

Clean-up: *Exception::buildErrors returns an array of errors, but never returns >1 error.

Problem/motivation

This issue was openend way back and referenced in the json:api code. Since this issue is deemed outdated, the reference to the issue should be removed from core.

Remaining tasks

Remove reference to this issue from: core/modules/jsonapi/src/Normalizer/JsonApiDocumentTopLevelNormalizer.php:217

Old IS

Issue title pretty much says it all, but there are certainly other clean-ups to be done in the exception classes, like these static \Drupal:: bits:

$error['links']['via']['href'] = \Drupal::request()->getUri();

and

$resource_type = \Drupal::service('jsonapi.resource_type.repository')->get($entity_type_id, $bundle);
$resource_type_name = $resource_type->getTypeName();
$route_name = !is_null($relationship_field)
  ? "jsonapi.$resource_type_name.$relationship_field.related"
  : "jsonapi.$resource_type_name.individual";
$url = Url::fromRoute($route_name, ['entity' => $entity->uuid()]);
$errors[0]['links']['via']['href'] = $url->setAbsolute()->toString(TRUE)->getGeneratedUrl();


The submit button is not following any condition while in popup/dialogs

Hi,

Description of the issue
The form button like the default "Submit" button of any webform, is not accepting any #state conditions once the dialog is initialized.

Problem
The problem is in getting the default state of the button to initialize in the dialog. Because once you start entering input values the button's state is updated.

Why
The issue is Drupal.behaviors.dialog.prepareDialogButtons in core/misc/dialog/dialog.ajax.es6.js clones the primary buttons without copying the #states conditions.

This must be a core States API issue.

Reproduce the issue:

1) Install the webform module.

2) Using the built-in "contact" form, create a condition to hide the "Send message" button.

_ "Hidden" if "Your Name" textfield value is "Hide Button".

the yaml #state condition will be something like:

'#states':
    invisible:
      ':input[name="name"]':
        value: 'Hide Button'

3) Add the "contact" form as a field of type "webform" to the article content type.

4) Create one test article, lets consider the article nid is "12".

5) launch the created article in a dialog/popup using the below code:

<a class="use-ajax" data-dialog-type="modal" href="/node/12">Open article</a>

6) Find the webform field and try to input inside the "your name" field the text: Hide Button

7) You will notice that the "Send message" button is still visible without any changes for its #states.

Reference
The discussion of the webform issue here, lead to create this core issue.

Thank you all for your help and time,

Below is the source code of a configured "contact" form to speed up the reproducing of the issue:

name:
  '#type': textfield
  '#title': 'Your Name''#required': true
  '#default_value': '[current-user:account-name]''#multiple__no_items_message': '<p>No items entered. Please add items below.</p>'
email:
  '#title': 'Your Email''#type': email
  '#required': true
  '#default_value': '[current-user:mail]'
subject:
  '#type': textfield
  '#title': Subject
  '#required': true
  '#states':
    visible:
      ':input[name="name"]':
        value: Webform
  '#multiple__no_items_message': '<p>No items entered. Please add items below.</p>''#test': 'Testing contact webform from [site:name]'
message:
  '#title': Message
  '#type': textarea
  '#required': true
  '#test': 'Please ignore this email.'
actions:
  '#type': webform_actions
  '#title': 'Submit button(s)''#states':
    invisible:
      ':input[name="name"]':
        value: 'Hide Button''#states_clear': false
  '#submit__label': 'Send message'

Make the active menu item visually stand out more

Problem/Motivation

In the context of the toolbar module, #3097907: Active toolbar tray has weak affordance and fails WCAG color criteria outlined the problems certain groups of people have to perceive the active toolbar tray. To a certain degree that problem applies to the navigation module as well, for certain groups of people and/or in certain contexts it is challenging to perceive which menu item is currently in the active state. There is no direct success criterion in the WCAG or any other spec I am aware of, the only recommendation I was able to find was in a tutorial for the W3C Web Accessibility Initiative (WAI) stating the following about the active state (https://www.w3.org/WAI/tutorials/menus/styling/#active-state):

Indicate the menu item that was activated through clicking, tapping, or keyboard selection. Users can identify unintended activation, for instance when they have clicked on the wrong menu item.

a) Top-level menu item in active state

How does a top level menu item in active state differ from those in none active state? There are two ways the difference is currently communicated:

None active menu itemActive menu itemColor contrast
Font color#55565b (--admin-toolbar-color-gray-800)#002e9a (--admin-toolbar-color-blue-700)1.5:1
Background color#FFFFFF#f3f4f9 (--admin-toolbar-color-gray-050)1.1:1

Image may be NSFW.
Clik here to view.
a few top level menu items in the vertical navigation with the appearance page as the menu item in the active state

Even though it seems that the active menu item label looks like using a bold typeface the font weight remains at 700, the same weight as menu items that are not in an active state. So basically the active state is communicated solely by color so SC1.4.1 applies, and due to the too low color contrast SC1.4.3 (for the font color) and SC1.4.11 (for the background-color) applies.

b) Top-level menu item in active state that is also added to the shortcuts

How does a submenu item in active state differ from those in none active state? There are two ways the difference is currently communicated:

None active menu itemActive menu itemColor contrast
Font color#55565b (--admin-toolbar-color-gray-800)#0036b1 (--admin-toolbar-color-blue-600)1.3:1
blue dot#FFFFFF#002E9A11.3:1

Image may be NSFW.
Clik here to view.
the new vertical navigation with the structure top level menu item expanded as well as the display mode sub menu item and the view menu sub menu item shown as active menu item

Compared to the top-level menu items sub menu items aren't using a change of the background color to label the active menu item, instead a blue dot is used which is good. In regards of the text color there is the same problem of the same low color contrast (ref SC 1.4.3) that was already noted for top-level menu items.

c) Sub-menu menu item in active

There is one additional special third case. In the event of that a top-level menu item becomes active that is also added as a shortcut, the shortcuts group autoexpands using the pattern described in b) while the top-level menu item gets shown as active as well. That way you have two active menu items at the same time.

Image may be NSFW.
Clik here to view.
the content overview page with the content top level menu item shown in active state as well as the shortcuts group expanded with all content shortcut shown in active state as well

Strictly speaking probably correct but still a little bit confusing since the label for the top-level menu item in the current example is Content while the label for the shortcut is All content plus having two active elements at once is a source of potential confusion

Steps to reproduce

  • Go to /admin/appearance
  • Go to /admin/structure/display-modes/form
  • Go to /admin/content

Proposed resolution

Update the current styles with the new designs:
Image may be NSFW.
Clik here to view.

Link to the designs on Figma.

User interface changes

The active state for the Navigation items will change.

Allow the ChangedItem to skip updating the entity's "changed" timestamp when synchronizing (f.e. when migrating)

Problem/Motivation

Especially for migrate it would be really useful to be able to copy the old changed time, for example from a note.

After #2428795: Translatable entity 'changed' timestamps are not working at all we have a solution for new entities, but we still need a solution for existing entities e.g. currently you can't resave an entity with changes without updating the changed timestamp.

Proposed resolution

Skip the automatic updating when synchronizing entities. Ever since #2985297: Generalize the concept of entity synchronization, all entities are synchronizable. And it already provides the exact semantics that we need. Quoting \Drupal\Core\Entity\SynchronizableInterface::isSyncing():

  /**
   * Returns whether this entity is being changed as part of a synchronization.
   *
   * If you are writing code that responds to a change in this entity (insert,
   * update, delete, presave, etc.), and your code would result in a change to
   * this entity itself, a configuration change (whether related to this entity,
   * another entity, or non-entity configuration), you need to check and see if
   * this entity change is part of a synchronization process, and skip executing
   * your code if that is the case.
   *
   * For example, \Drupal\node\Entity\NodeType::postSave() adds the default body
   * field to newly created node type configuration entities, which is a
   * configuration change. You would not want this code to run during an import,
   * because imported entities were already given the body field when they were
   * originally created, and the imported configuration includes all of their
   * currently-configured fields. On the other hand,
   * \Drupal\field\Entity\FieldStorageConfig::preSave() and the methods it calls
   * make sure that the storage tables are created or updated for the field
   * storage configuration entity, which is not a configuration change, and it
   * must be done whether due to an import or not. So, the first method should
   * check $entity->isSyncing() and skip executing if it returns TRUE, and the
   * second should not perform this check.
   *
   * @return bool
   *   TRUE if the configuration entity is being created, updated, or deleted
   *   through a synchronization process.
   */
  public function isSyncing();

From #79:

  1. 👍 95% of this patch is to ensure everything in ChangedItem is using the time service instead of the REQUEST_TIME global. That is necessary to allow for testability.

Remaining tasks

None.

User interface changes

None.

API changes

None.

Update 10.3 release notes to indicate Rules module is not compatible

The Rules module is not yet compatible with 10.3. Having Rules installed on 10.3 will break the site, with the only real workaround being to uninstall Rules.

https://www.drupal.org/project/rules/issues/3454056
https://www.drupal.org/project/rules/issues/3456150
https://www.drupal.org/forum/support/upgrading-drupal/2024-06-20/update-...

Since Rules is a pretty popular module (currently listed at #43 at https://www.drupal.org/project/usage with over 120K installs) it probably makes sense to list this issue in the release notes for 10.3 so users are not caught by surprise.

The last update for Rules was in October 2023 so its current maintenance status is a bit unclear.

Generate JSON schema for content entity types

Drupal boasts a feature-rich API whereby content entities may contain attached data or references to other entities in fields. These are either "base" fields that are always present for a given entity type, or bundle fields which are used only on a subset of "bundles" for that entity. The storage configuration for a field is always the same for all instances of a particular entity type.

Drupal 8's release cycle saw the introduction of decoupled/API-first concepts on top of the core entity system, e.g. JSON:API and REST modules. In contrib, GraphQL is also popular, however it provides additional abstractions on top of the field API.

When working with Drupal entities over an API, it is very helpful to have a schema for the data structure of a particular entity. This allows clients to know, for instance, what acceptable values may be sent or received for the value and format properties of a formatted text field.

This issue's MR enhances the core typed data, field and serialization APIs to provide JSON Schema representations of a field's properties. These field-level schemas may then be used to generate comprehensive schemas for fielded entities, e.g. as OpenAPI specs. Currently we leave this level of schema generation to contrib, however it could make sense in the future to incorporate something like openapi_jsonapi into core. Currently, the jsonapi_openapi 4.x development branch depends on this MR and is a good window through which to review this issue's functionality.

This issue only covers content entities. Config entities have some support over the API, e.g. in JSON:API module, however schema discovery for them is very different given content entities are not fieldable in the same way, and their schemas would be derived from the config schema and validation APIs vs. typed data.

Some technical notes for review

While this issue/concept was originally blocked by an inability to cache the outcome of a "supports" query on a normalizer, that was fixed in #3252872: Use CacheableSupportsMethodInterface for performance improvement in normalizers thanks in large part to changes upstream in Symfony.

As it turns out, the original solution of a new interface and method to get a schema is not possible due to the fact the resolved normalizer may not be accessed directly from the serializer. A proposed change of Serializer::getNormalizer() was rejected upstream. The consensus alternate approach, which is probably more elegant anyway, is to use a new normalization "format" of json_schema to retrieve the schema, if supported.


Original Solution (originally authored by @gabesullice):

Add a SchematicNormalizerInterface with a ::getNormalizationSchema() method.

Initial thoughts on a method signature:

  • $type is a supported interface or class.
  • $format is the encoding format.
  • $refinements is a parameter bag of anything that is required to return a correct schema. For example, ResourceObjectNormalizer::getNormalizationSchema() would need $refinements->get('resource_type'). Best practice would be for refinements to be documented on the method and then asserted in the method. It's imperfect, but the best I can think of.

I think under this system, every normalizer would be required to return a complete schema. Meaning that the JsonApiDocumentTopLevelNormalizer would be responsible for returning a schema that included schema for any child resource object(s). Alternatively, we could allow normalizers to return placeholder objects and resolve them separately. That might end up as an over-engineered solution though.

Finally, I think that we would put this method on the Serializer service so that normalizers will not need to specifically know which child normalizer services will be applied.

Viewing all 294706 articles
Browse latest View live