Quantcast
Channel: Issues for Drupal core
Viewing all 292476 articles
Browse latest View live

Allow users to translate content they can edit

$
0
0

Problem/Motivation

#253157: Add "Translate own content" permission, rename "Translate content" to "Translate all content" was committed in earlier versions of Drupal 8 which allowed users to translate their own content. However, this feature was later removed from the core and it made https://www.drupal.org/node/1776752 obsolete.

Nowadays, multilingual community sites still have a requirement to allow users to translate their own content.

Proposed resolution

Based on @Berdir's feedback:

Options are:

  • New permissions: "translate own entities", "translate own {entity_type}", "translate own {bundle} {entity_type}"
  • Single global permission: "allow translating content that the user can edit"

Remaining tasks

Discuss.

User interface changes

API changes

Data model changes


Telephone Link field formatter InvalidArgumentException with 5 digits or fewer in the number

$
0
0

Problem/Motivation

When applying the telephone link field formatter on number with 5 digits or less, Drupal miserably breaks, displaying some kind of WSOD with the following message: "The website encountered an unexpected error. Please try again later". Another message can be then found in the watchdog: InvalidArgumentException: The URI 'tel:112' is invalid. You must use a valid URI scheme. in Drupal\Core\Url::fromUri() (line 301 of /media/alex/4126b75c-86e8-4b12-a7c2-08e2d7dbfb08/alex/201310/drupal/core/lib/Drupal/Core/Url.php).

Steps to reproduce

  • Create a content type with a telephone field.
  • In the "Manage Display" page, choose the "Telephone link" field formatter for this field.
  • Create a node of that content type with "123" as value of this field.
  • The exception is thrown when the page is displayed.

Cause

The bug occurs in the parse_url PHP function, which processes numbers with 5 digits or less like TCP ports.

Proposed resolution

  • Not allowing numbers with 5 digits or less: however, short numbers do exist, like emergency numbers, internal numbers, etc.
  • We might have to deal with these numbers differently, though: are there specifications about this?
  • Writing our own function, instead of the parse_url PHP function.
  • Use a tiny hack to force parse_url to behave as expected. (add an empty query string at the end of the uri)

The underlying parse_url PHP function problem can be managed in a follow up issue. See https://www.drupal.org/node/2575577

Remaining tasks

Contributor tasks needed
TaskNovice task?Contributor instructionsComplete?
Create a patchInstructionsDone
Update the issue summaryInstructionsDone
Add automated testsInstructionsDone
Manually test the patch NoviceInstructionsDone
Add steps to reproduce the issueNoviceInstructionsDone
Review patch to ensure that it fixes the issue, stays within scope, is properly documented, and follows coding standardsInstructionsDone

User interface changes

None.

API changes

None.

Data model changes

None.

View with user/% path breaks login/logout on 8.5.x

$
0
0

I'm not sure if this is a Views bug or a core bug.

How to reproduce

1. Create a Drupal 8.5.0 site.
2. Create a view and set the path to user/% to override the user profiles.
3. /user/login and /user/logout and /user/register will now show the 404 page. Using Drush to log in and removing or changing the path of the view set to "user/%" will allow login and logout to work normally.

I have always used "user/%" in a view to override the user profile display, but since 8.5 it does not work.

(Edit: Based on the discussion, I edited the summary to reflect that the bug affects 8.5.x, not just 8.5.1.)

Reference info

Additional details can be found in this forum support thread and on Drupal Answers.

Add Date function support in DTBNG

$
0
0

Problem/Motivation

Support for date formats is implemented in such a way that database drivers other than the ones in core are impossible to implement without modifying the module.

This code (just an example there are a few methods involved) was straight ported from D7, where it was also crippled:

function views_get_timezone() {
  global $user;
  if (variable_get('configurable_timezones', 1) && $user->uid && strlen($user->timezone)) {
    $timezone = $user->timezone;
  }
  else {
    $timezone = variable_get('date_default_timezone', 0);
  }

  // set up the database timezone
  $db_type = Database::getConnection()->databaseType();
  if (in_array($db_type, array('mysql', 'pgsql'))) {
    $offset = '+00:00';
    static $already_set = FALSE;
    if (!$already_set) {
      if ($db_type == 'pgsql') {
        db_query("SET TIME ZONE INTERVAL '$offset' HOUR TO MINUTE");
      }
      elseif ($db_type == 'mysql') {
        db_query("SET @@session.time_zone = '$offset'");
      }

      $already_set = true;
    }
  }

  return $timezone;
}

NO WHERE IN CORE THERE SHOULD BE CODE IN THE FORM OF:

if ($db_type == 'mysql') {
  whatever
}
else {
 whetever else
}

Instead, this should be moved in one way or another to the database engine layer:

if ($connection->supportsWhateverFeature()) {
  whatever
}
else {
 whetever else
}

Proposed resolution

Move the logic to the database drivers and ask them what the specific implementations should be.

Remaining tasks

Do it.

User interface changes

None.

API changes

None.

Data model changes

None.

[Meta] Remove database specific logic from core

$
0
0

Problem/Motivation

Drupal core has still lots of database specific logic that has not been moved to DTBNG. There are many parts of core that take conditional actions depending on which database backend is being used:

$db_type = Database::getConnection()->databaseType();
    if (in_array($db_type, ['mysql', 'pgsql'])) {
      $offset = '+00:00';
      static $already_set = FALSE;
      if (!$already_set) {
        if ($db_type == 'pgsql') {
          Database::getConnection()->query("SET TIME ZONE INTERVAL '$offset' HOUR TO MINUTE");
        }
        elseif ($db_type == 'mysql') {
          Database::getConnection()->query("SET @@session.time_zone = '$offset'");
        }

        $already_set = TRUE;
      }
    }

This prevents contributed database drivers from being able to fully support Drupal, and completely defeats the purpose of having a Database Abstraction layer.

How much code is affected? Doing a quick find-in-files of "databaseType()":

...\lib\Drupal\Core\Command\DbDumpCommand.php(138): if ($connection->databaseType() !== 'mysql') {
...\modules\path\tests\src\Functional\PathAliasTest.php(103): if ($connection->databaseType() != 'sqlite') {
...\modules\path\tests\src\Functional\PathAliasTest.php(257): if ($connection->databaseType() != 'sqlite') {
...\modules\simpletest\src\Tests\KernelTestBaseTest.php(345): if ($connection->databaseType() != 'sqlite') {
...\modules\system\src\Tests\Entity\Update\LangcodeToAsciiUpdateTest.php(30): if (Database::getConnection()->databaseType() !== 'mysql') {
...\modules\system\tests\src\Kernel\Scripts\DbDumpCommandTest.php(29): if (Database::getConnection()->databaseType() !== 'mysql') {
...\modules\views\src\Plugin\views\argument\StringArgument.php(183): if (Database::getConnection()->databaseType() == 'sqlite') {
...\modules\views\src\Plugin\views\argument\StringArgument.php(189): if (Database::getConnection()->databaseType() == 'pgsql') {
...\modules\views\src\Plugin\views\argument\StringArgument.php(215): if ($this->options['case'] != 'none'&& Database::getConnection()->databaseType() == 'pgsql') {
...\modules\views\src\Plugin\views\argument\StringArgument.php(284): if ($this->options['case'] != 'none'&& Database::getConnection()->databaseType() == 'pgsql') {
...\modules\views\src\Plugin\views\query\Sql.php(1758): $db_type = Database::getConnection()->databaseType();
...\modules\views\src\Plugin\views\query\Sql.php(1796): $db_type = Database::getConnection()->databaseType();
...\modules\views\src\Plugin\views\query\Sql.php(1819): $db_type = Database::getConnection()->databaseType();
...\tests\Drupal\KernelTests\Core\Command\DbDumpTest.php(83): $this->skipTests = Database::getConnection()->databaseType() !== 'mysql';
...\tests\Drupal\KernelTests\Core\Database\ConnectionTest.php(125): if (Database::getConnection()->databaseType() !== 'mysql' || !defined('\PDO::MYSQL_ATTR_MULTI_STATEMENTS')) {
...\tests\Drupal\KernelTests\Core\Database\ConnectionTest.php(162): if (Database::getConnection()->databaseType() !== 'pgsql') {
...\tests\Drupal\KernelTests\Core\Database\SchemaTest.php(66): if (Database::getConnection()->databaseType() == 'mysql') {
...\tests\Drupal\KernelTests\Core\Database\SchemaTest.php(189): $db_type = Database::getConnection()->databaseType();
...\tests\Drupal\KernelTests\Core\Database\SchemaTest.php(266): if (Database::getConnection()->databaseType() != 'mysql') {
...\tests\Drupal\KernelTests\Core\Database\SchemaTest.php(430): if (Database::getConnection()->databaseType() == 'mysql') {
...\tests\Drupal\KernelTests\Core\Database\SchemaTest.php(838): $db_type = Database::getConnection()->databaseType();
...\tests\Drupal\KernelTests\Core\Database\SelectComplexTest.php(236): $db_type = Database::getConnection()->databaseType();
...\tests\Drupal\KernelTests\KernelTestBaseTest.php(226): if ($connection->databaseType() != 'sqlite') {
...\tests\Drupal\Tests\Core\Database\Stub\Connection.php(47): public function databaseType() {

Proposed resolution

Remove any code in core that is in the form of:

   $db_type = Database::getConnection()->databaseType();
    if ($db_type == 'whatever') {
      // I'm not portable.
   }

Remaining tasks

Do it.

Child issues:

User interface changes

API changes

Data model changes

JSON API 8.18 update causes users disallowed to login randomly

$
0
0

After updating to 8.18 some existing users (apparently those with moderator or admin privileges) face stochastic problems with login to the site with the REST service. Login via Drupal standard interface posed no problem for the same users. I tried to clear the cache, reinitialize the passwords, nothing helped. The next day, magically users could log in.
In the logs I see only this:

Type: access denied
User: Anonymous (not verified)
Message: /user/login?_format=json

I haven't seen this behavior previously but maybe the issue is even older than 8.17

[policy, no patch] Drupal 9 release timing and Drupal 7/8 EOL

$
0
0

Problem/Motivation

Closely related to #2598662: Decide when Drupal 7 (and Drupal 8 and later) should enter the LTS and security-support-only phase, except that's about when the branches start LTS, this is about when they are designated as being at end of life (EOLed).

For reference 5.x EOL was on the day 7.x was released.

Drupal 6 EOL is three months after 8.0.0 release.

The Drupal 8 LTS (Long Term Support) will be released sometime between the opening and release of 9.0.0

Things to consider:

1. How many major core branches are supported at once? The current LTS policy says 2 with a 3 month crossover, is that a hard maximum?

2. If we end up with two LTS releases of 8.x for any reason, would that affect the number of major branches we'd want to support.

3. Do we expect people to migrate from 7.x to 8.x when the migration is available, or wait for 9.x? When will the 7-8 migration be available?

4. Do we expect people to migration from 8.x to 9.x (especially if that's a smaller jump) or wait for 10.x?

5. If 9.x ships with a fully support migration path from 7.x, how much time is reasonable to allow people to jump if we support that?

6. Do we want to support going from 7.x LTS to 9.x LTS, or just to 8.x LTS and 9.x minor releases - the answer to #1 affects the feasibility of this

7. What's going to happen with D6 extended support? How quickly with 6.x usage drop off on http://drupal.org/project/usage/drupal? Will we finally see the remaining hard-core 5.x sites disappear?

8. Given we've shifted to a timed release cycle for new releases, would we consider moving to timed EOL, for example LTS + 2 years? Instead of pinning it to major version + 2 release dates which is more variable.

(add more if you have them)

Proposed resolution

A few examples of what we could do:

Option 1

Drupal 10.0.0 + 3 months (same as 6.x EOL timing)

Option 2

Drupal 10.0.0 release day (same as 5.x EOL timing)

Option 3

Drupal 10.X.0 LTS release day (allows for LTS to LTS)

Option 4

Drupal 9.X.0 LTS + 1 year (assumes we start only supporting version N to version N + 1 again and make the upgrade path smoother.

Option 5

Drupal 8.X.0 LTS + 2 years (allows us to announce the actual date much earlier than any of the other options, because it's only based on the 8/9 release cycle).

Add more options here.

Remaining tasks

User interface changes

API changes

Data model changes

Allow Paragraphs widget/field and similar use cases to to be considered translatable

$
0
0

Problem/Motivation

The changes in content_moderation/translation and how it handles non-translatable fields broke paragraphs pretty badly. See #2951436: Fix integration with content moderation in multi-lingual scenarios, based on some reports we saw, it also affects non content-moderation workflows (as in, non-workflow workflows. Excuse the bad wordplay, it is late).

The thing with paragraphs is that we display references entities, which have their own revisions and translations in the same form. The field itself is untranslatable (at least that's currently the only supported mode), and we lock down all changes that would result in a change on the field itself, to make sure referenced paragraph id/revision id and order can not change across translations. But we do allow the change the corresponding translations and revisions in the referenced paragraphs and their fields.

A lot of that keeping-in-sync stuff happens directly in Entity Reference Revisions which supports the concept of "composite entities" that only exist in the context of a parent and automatically get a new revision if the parent does.

That means we're technically compatible with the limitations that core has on non-translatable fields, the logic in content_translation/entity storage just doesn't know about it because all it knows is the isTranslatable() flag on the field.

Proposed resolution

There are a few steps that are necessary here to make things work:

* First we need to get around the fact that \Drupal\content_translation\ContentTranslationHandler::entityFormSharedElements() is hiding our widget on the form. I found a workaround for that, but I think it would be easier if widgets could just set #multilingual themself and content_translation_form_alter() would not override it. This might also help with some hacks we have right now to get rid of the translatability clue message.

* Then we need to prevent the field from being replaced with the default revision/translation values in \Drupal\Core\Entity\ContentEntityStorageBase::createRevision(). Not sure about this, maybe allow to extend the $skipped_field_names somehow or a hook that allows us to at least somehow undo things.

* While we don't want the paragraph field values to be replaced, we basically need to be able to apply the same/similar logic to our referenced entities. So when a new "merge-revision" of the node is created, we want to do the same to the paragraphs, so that they too merge their translatable/untranslatable fields together. And later on when we have fancy conflict resolution that will replace this special case, we'll need to be able to apply that recursively as well.

Remaining tasks

User interface changes

API changes

Data model changes


The revision ID field should be flagged as revisionable

$
0
0

Problem/Motivation

The revision ID field is not flagged as revisionable, which might be a problem when iterating through the entity fields and retrieving only non-revisionable fields - e.g. when wanting to check if a non-revisionable field has changed. This has been detected in #2620980-106: ContentEntityStorageBase::loadRevision() should use the static and the persistent entity cache like ContentEntityStorageBase::load(), where it caused problems.

Proposed resolution

Flag the revision ID field as revisionable.

Remaining tasks

User interface changes

API changes

Data model changes

Allow the inline creation of non-reusable Custom Blocks in the layout builder

$
0
0

Problem/Motivation

When you create a Custom Block entity, a Block Plugin definition is derived and is available anywhere Block Plugin definitions are listed. This makes a lot of sense when Custom Blocks are meant to be re-used, for example you may want a "Logo" Custom Block on many pages in different regions.

Performance
However, when using something like Panels or Layout Builder, Custom Blocks are often only meant to be used once. If you're building out hundreds of pages you could end up with thousands of Custom Blocks that clutter user interfaces and lead to performance issues.

UX
Currently to add a custom block to a Layout the user would have to first navigate to the custom block page, create the block and then navigate back to the layout builder.

Access Control
If we allow inline block creation a user who creates a custom block on the Layout Builder for an access controlled entity probably expects only those that can view the entity that has the Layout to be able to view the custom block. Currently blocks have no connection on an access level to where they are placed so if you listed the block in a View or it was referenced in an Entity Reference value anyone would be able to see it.

Revision
Currently if you placed a block via the Layout Builder there is no connection between the revision of the block and revision of the entity with the Layout. If you updated a custom block all previous revision of the entity with the layout would display the update version.

Deletion
If a custom block is deleted then it would be removed from all placements via the Layout Builder across all revisions.

Proposed resolution

Add the ability for users to create custom non-reusable blocks from within within the Layout Builder. These blocks will be the same entity type as Custom Block provide by the block_content module therefore all the site current block types will be available from within the Layout Builder.

The non-reusable blocks will be only be viewable within the context of the layout that they were placed in. For bundles that are set to create a new revision for each update the changes to custom inline block will be tracked with the parent entities revision.

The new custom inline blocks should be "owned" by the layout that they are placed in in that they should be editable or deleted from outside of the layout builder.

Implementation

Add a new base field to Custom Blocks that determines is they are re-usable. If a Custom Block is not re-usable, it should not have a derived Block Plugin definition and should not be visible in normal Views listings. For integration with Layout Builder, we should create a new Block Plugin that stores Custom Block revision IDs and implement an inline form for creating and editing these Custom Blocks.

This issue actually include several concepts that should probably be split out into separate issues.
To determine if end goal is achievable and advisable with this approach lets keep this as a big patch containing the sub tasks until it looks like it is good idea. We won't want to commit small supporting parts if we are going abandon this approach for something like #2948064: Layout Builder should support inline creation of Custom Blocks using entity serialization(currently that issue seems not doable)

Eventually we may want to have separate issues for

  1. Allow some Content Blocks to be non-reusable(probably in Block Content module eventually)
  2. Implement generic entity usage tracking to support non-reusable blocks
  3. Allow inline creation of non-reusable blocks in the Layout Builder (maybe all that would remain for this issue)

Remaining tasks

Write a patch to explore the feasibility of this approach.

User interface changes

n/a

API changes

n/a

Data model changes

n/a

Invalidating 'node_list' and other broad cache tags early in a transaction severely increases lock wait time and probability of deadlock

$
0
0

Problem/Motivation

Suppose you have some content entity type (foo) with an entity reference to nodes, and you have contrib or custom code that needs to update something about the referenced nodes whenever the host entity is updated. So you implement hook_foo_presave() or hook_foo_update(), and in that function you load the referenced nodes, do something to them, and save them.

By design, all of this happens within a single database transaction: SqlContentEntityStorage::save() starts the transaction prior to invoking hook_foo_presave() and doesn't commit the transaction until after all hook_foo_update() implementations complete.

Meanwhile, when the first child node is saved, Entity::invalidateTagsOnSave() invalidates several broad tags ('node_list' and '4xx-response') that are not specific to the particular node, which causes DatabaseCacheTagsChecksum::invalidateTags() to send a merge (UPDATE) query to the corresponding records in the {cachetags} table.

This causes the database engine (e.g., InnoDB) to acquire a row lock on those records, which it doesn't release until the end of the transaction. However, if there are more child nodes that need to be saved, or other slow hook implementations that need to be performed, prior to the end of the transaction, then these locks could last 10, 20, or more seconds.

Now suppose you have concurrent users editing foo entities on this site. Even if they're editing different foo entities with different child nodes, they all end up competing for the same lock on the 'node_list' cache tag. Depending on how long they each need to wait, this could end up appearing as a deadlock, or in some cases, even lead to real deadlock.

Proposed resolution

Change DatabaseCacheTagsChecksum to delay updating the database with cache tag invalidations until just before the end of the transaction. However, also have its isValid() return FALSE while there are not-yet-committed invalidations. This way, other requests continue seeing the old value until the end of the transaction (which is already the case in HEAD, since that's how transactions work), while later code in the same request (e.g., other presave/update hooks) continues to see the invalidation as having already occurred (just as in HEAD).

If done right, I think this is fully backwards compatible, while reducing to practically 0 the time that a {cachetags} record lock is held.

Remaining tasks

  • Write patch.
  • Review if the idea and implementation are sound.
  • Figure out what test coverage to add.

User interface changes

None.

API changes

A public method addition to Drupal\Core\Database\Connection for adding callbacks to run just prior to transaction commit.

Data model changes

Seven's focused/hovered tabs do not meet WCAG AA 1.4.3 for contrast

$
0
0

Seven's tabs styling uses a brighter colour foreground text colour for a tab with a :hover or :focus state:

.tabs__tab:hover,
.tabs__tab:focus {
  color: #008ee6;
  background-color: #fafaf7;
}

This brighter blue (#008ee6) means that the foreground text and the background colour do not have sufficient contrast to meet WCAG AA. The ratio is 3.34:1 when it should be at least 4.5:1.

To reproduce,
1. Login to Drupal 8
2. Navigate to /admin/content
3. Use developer tools to simulate a hover/focus state on an inactive tab and check the foreground text to background colour contrast ratio

Chrome dev tools showing a failing contrast ratio of 3.34 for a Seven's tab in the hover state

Deprecate system_get_info() and system_register()

Replace hard coded static cache of entities with cache backends

$
0
0

Problem/Motivation

When loading large numbers of entities, especially during migrations and updates, it's quite easy to run out of PHP memory.

Migrate works around this by trying to clear the entity static cache, but this also results in a persistent cache clear.

Static caching is hard coded in storage classes which prevents swapping it out unless you change the whole class.

Proposed resolution

Add a 'static cache' service, which does not serialize at all, but which conforms to CacheBackendInterface.

Rework entity storage to rely on this service instead of a raw class property.

This will allow for two things:

- once this issue has landed, migrate will be able to reset the static cache via the service, therefore not affecting the persistent entity cache.
- in a follow-up, we'll be able to add a simple Least Recently Used implementation, allowing the static cache to have a fixed maximum number of items.
- beyond this, there is the possibility to go even further:
- have a cache backend limited by the actual size of the items in it (will require estimating memory usage of entities)
- add a cache backend, probably in contrib, using PHP weak references http://php.net/manual/en/intro.weakref.php which theoretically will allow cached entities to be removed by garbage collection.

Remaining tasks

User interface changes

API changes

Data model changes

Spinning this out of #1302378: Use multiple specialized entity controllers.

The base EntityController class currently handles keeping it's own 'static' cache internal to the class, or always fetching from the database all the time.

In Drupal 7, this means that http://drupal.org/project/entitycache needs to provide it's own controller class to provide persistent caching for entities.

We can make this a lot more flexible by just replacing the custom caching within the Entity controller class, with a configurable cache controller key instead of the current 'static cache' key. There's no need for entity-specific cache controllers, since any class implementing CacheBackendInterface will do fine.

To allow for 'static' caching, I've added a new ArrayBackend which simply stores cache items in a php array. Apart from expires which didn't seem worth working on until #730060: Replace CACHE_TEMPORARY, cache_clear_all() and minimum cache lifetime with cache tags support is in, this (untested) backend supports everything the database backend does, including tags etc., meaning it should be useful for unit testing eventually.

For no static caching at all, the NullBackend works fine.

To actually implement entitycache in D8 (whether core or contrib), you'd need a backend that proxies the MemoryBackend + whichever one is implemented for the cache_entity bin, since we're placing responsibility for both in a single class doing things this way. There's some inconsistencies with resetCache() etc. that would need to be sorted out for that.

Completely untested patch that will likely blow up, but just to show what it looks like.

One feature gets dropped here, which is fetching from cache when $conditions is passed to entity_load(). That's already a bit wonky as it is, and the $conditions parameter is already on its way out and documented as deprecated in 7.x per #1184272: Remove deprecated $conditions support from entity controller.

Menu overview always shows the untranslated config entities

$
0
0

Problem/Motivation

Currently the menu overview (located under admin/structure/menu) always displays the menu names/descriptions in the original language.
I know this was intentionally done for all config entity admin lists in #2136559: Config entity admin lists show configuration with overrides (eg. localized).

However in the case of the menu overview which is a config overview that is often accessed by editors whom are not necessarily fluent in english (or whatever the original language of your menu is) this can be a bit daunting.

Proposed resolution

Override the load method in the MenuListBuilder class to use the overridden config entities.


[PP-1] Add workspace UI in top dialog

$
0
0

Problem/Motivation

This is the implementation issue for #2732081: WI: Phase G2: Full-site preview with Workspace UI.

There is one dependency:
#2916781: Allow off-canvas dialog to be rendered at the top of the page

Should-have:
#2940677: Support prefers-reduced-motion in off-canvas dialog

Proposed resolution

Following the designs from https://marvelapp.com/2db8i71/screen/26360612, implement the Workspace list builder in a top dialog.

Remaining tasks

User interface changes

There are many changes to the Workspace UI which is experimental.
The concerning changes are those to off canvas CSS which is stable.

API changes

None

Data model changes

None

Use a tri-state checkbox for tableselect widget.

$
0
0

Problem/Motivation

The tableselect widget allows users to carry out two short cut actions on the table selections: select all, and unselect all. Currently the master checkbox in the table header behaves in a boolean way, either checked or not-checked.

It's possible to implement "tri-state" checkboxes. These are uncommon on the web, but desktop applications use them more often. There are two kinds of behaviour:

  • Some also allow cycling though the all/none/mixed states, allowing a user to go back to their particular mixed selection.
  • Not all tri-state checkboxes behave this way though - some only allow select-all and select-none actions, and don't allow a user to recover their previous mixed selection.

A specific usability benefit is that when a table is too long to fit inside the viewport, the master checkbox in the header can convey the all/none/mixed to a user, without requiring them to look down the entire table. This can be especially useful to assistive technology users.

GMail is an example of a web application that uses a tri-state checkbox for the main message list. When a user selects some of the rows, the select-all checkbox indicates a mixed selection, which looks a hyphen inside a checkbox. The select-all checkbox can be used to select-all (and it shows a checkmark), and then select-none. It does not allow a user to recover their previous mixed selection.

The aria-checked property supports tri-state checkboxes, with true, false, and mixed values. GMail uses this.

Proposed resolution

  • Implement tri-state checkboxes in our tableselect widget, and convey the mixed-selection state visually.
  • Use aria-checked=true|false|mixed to convey the state to assistive technology.
  • Make this available wherever the tableselect widget is used, including views bulk operations.

Remaining tasks

  • Research support for aria-checked=mixed in browsers and assistive technology.
  • Decide whether we want the behaviour which preserves the user's selctions when cycling through the all/none/mixed states.
  • Add functionality to tableselect.js
  • Tests.

User interface changes

The main select-all checkbox in tableselect widgets would become a tri-state checkbox. It would show a "mixed" state when some rows are selected and others are not selected. Typically this is presented as a checkbox with a dash/hyphen inside. Additionally, this would be conveyed to assistive technology using aria-checked=true|false|mixed.

API changes

TBD. Some extra JS behaviours, possibly some Form API states and methods.

Data model changes

TBD.

Install profile in settings.php and mismatch check makes re-installs of Drupal hard

$
0
0

Problem/Motivation

#2156401: Write install_profile value to configuration and only to settings.php if it is writeable changed from always writing the install profile to configuration, and only to settings.php if settings.php is writable.

Change record is here: https://www.drupal.org/node/2538996

However this leaves a relatively annoying issue when re-installing Drupal.

Steps to reproduce:

1. Install minimal profile
2. Drop the database, try to reinstall with Standard (doesn't matter if this is via drush or the UI)
3. You'll see an error message about the install profile in settings.php not matching the chosen profile.

Proposed resolution

Completely stop writing the install profile to settings.php regardless of whether it's writable or not.

Remaining tasks

User interface changes

API changes

We'e already deprecated getting the install profile from settings.php and accepted it won't always be available there for new sites where settings.php is read-only. Given this change will also only affect new sites, it should not in practice break bc that anyone is relying on at this point.

Data model changes

Add a button to reinstall Umami demo

$
0
0

Problem/Motivation

In #2944113: Should Umami/OOTB support backwards compatibility and an offical upgrade path from one version to another? we discussed that it could be useful to have a reinstall button to make it easier to start over with the demo. This button would also signal that the demo is ephemeral and it should not be built on.

Proposed resolution

Explore adding a reinstall button. Design, technology, etc. Define whether this is a requirement for Umami for some milestone.

Remaining tasks

TBD

User interface changes

TBD

API changes

TBD

Data model changes

TBD

Figure out a way to deal with form submits that would leak into the Live workspace

$
0
0

Problem/Motivation

The concept of workspaces and site-wide previews apply only to revisionable and publishable entities. However, it is very easy for site editors to miss this point and change some config values in a non-default workspace, for example adding a block in a Stage workspace, thinking that it will not show up in the Live workspace.

Proposed resolution

Figure out a way to communicate this and prevent any changes that would leak into the Live workspace.

Likely candidates:
- config entities/objects
- state
- others?

Remaining tasks

Discuss.

User interface changes

Yes, TBD.

API changes

Nope.

Data model changes

Nope.

Viewing all 292476 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>