Problem/Motivation

With #2226267: Improve default value handling of fields to be consistent the default value handling got improved, but the patch did not cover converting the default value implementations of uuid, created and changed fields.

We should convert those field types to use the new API as well, such that you can ask their definitions about the default values also.

uuid, language, created and changed field types currently use the Typed data way of setting default values, which basically is deprecated by the field definition way. Thus I think we should
- make DataDefinitionInterface follow the default value approach of FieldDefinitions + make applyDefaultValue() just use that (separate issue: #2318607: Improve default value handling for data definitions)
- We could support specifying a base default-value per field type, such that Created+Changed could just it to NOW + add that in FieldDefinition::getDefaultValue(). TimestampItem should support NOW as default value, as DateTime does. See DateTimeFieldItemList.

So this is definitely not a final version : I left these questions in the patch for reviewers.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

fago’s picture

Issue summary: View changes
fago’s picture

Issue tags: +beta deadline

This will have to cover "language" as well once #1966436: Default *content* entity languages are not set for entities created with the API goes in. Also tagging "beta deadline" as we have to give proper default value examples in core, such that modules can apply the pattern.

fago’s picture

Issue tags: -beta deadline +beta target

Given there is no API break or so, target probably fits better. Still, it should really happen before beta.

yched’s picture

Left a note in #2150511-74: [meta] Deduplicate the set of available field types - in short, I don't get why we have the 'created' and 'changed' field types.

More specifically, the 'created' field type only exists to be able to specify REQUEST_TIME as a default value for what is otherwise a regular 'timestamp' field.

If we rework default values, should we make it possible to assign "NOW" as a default value for a 'timestamp' FieldDefinition ?

fago’s picture

If we rework default values, should we make it possible to assign "NOW" as a default value for a 'timestamp' FieldDefinition ?

yep, that what I've been thinking. It's a good thing to have generally and fits perfectly into processDefaultValue() of its field item list.

andypost’s picture

andypost’s picture

Is there any examples? There weekend sprint coming so would be nice to attack

andypost’s picture

related issues uses FieldItemList::processDefaultValue() so it looks all items will require to implement corresponding classes

fago’s picture

Status: Active » Needs review
FileSize
7.22 KB

related issues uses FieldItemList::processDefaultValue() so it looks all items will require to implement corresponding classes

Yep, except that for timestamp's I think it's enough to do it once for TimeStampItem (see patch).

There is no example yet, but here is first start of the implementation I've discussed with yched.

The idea is to add a "default_value" annotation to field type's which then is picked up if no default value is provided. For dynamic value the field type has to implement processDefaultValue() on the field item class.

Attached patch does that for TimestampItem + Create/Changed, but I did not test it at all. It misses completion for Langauge and UUID fields, i.e. those miss the ItemList class + processDefaultValue() implementation.

If you like, it would be great if you could pick it up from here. I'm at the sprint or IRC if there are questions.

Status: Needs review » Needs work

The last submitted patch, 9: d8_field_default_value.patch, failed testing.

fgm’s picture

Issue summary: View changes
Status: Needs work » Needs review
FileSize
11.2 KB

Rerolled, fixed and completed. Some tests which would not pass with the previous version are now passing. Not sure everything's good, though:

  • language / DEFAULT_LANGUAGE = which one should be chosen ? I used \Drupal::languageManager()->getDefaultLanguage()->getId(); but maybe $entity->language()->getId(); would make more sense
  • uuid / RANDOM ? I had to get the Uuidgenerator service from \Drupal, which is some of an antipattern, because $entity->uuidGenerator() is protected, preventing its use outside the entity class itself, although it looks like this would be a case for it
fgm’s picture

Rerolled according to fago's insights : removed the comments, and the applyDefaultValue() methods on item classes.

The last submitted patch, 11: 2318605-Updated-default-value-implementation.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 12: 2318605-Updated-default-value-implementation.patch, failed testing.

fgm’s picture

Status: Needs work » Needs review
FileSize
11.93 KB

This version should have /less/ fails, but probably still some.

Status: Needs review » Needs work

The last submitted patch, 15: 2318605-default-values.patch, failed testing.

yched’s picture

  1. +++ b/core/lib/Drupal/Core/Field/Annotation/FieldType.php
    @@ -87,4 +87,14 @@ class FieldType extends DataType {
    +  /**
    +   * The default value assigned to the field.
    +   *
    +   * Note that the provided value can be processed by the field type's item list
    +   * class via \Drupal\Core\Field\FieldItemListInterface::processDefaultValue().
    +   *
    +   * @var mixed
    +   */
    +  public $default_value;
    

    "The default value assigned to the field" is not too clear in that context.
    Maybe change to "The default value for fields of this type" ?

    Should we also explain something like :
    Individual field definitions can specify their own "default value", which will then take precedence on the value specified here. This thus can be seen as a default "default value" for fields of this type.

    @var mixed means we need to explain what is accepted here - an example could also help for how to write that in annotations.

  2. +++ b/core/lib/Drupal/Core/Field/BaseFieldDefinition.php
    @@ -387,6 +387,15 @@ public function getDefaultValue(ContentEntityInterface $entity) {
    +    if (!isset($value)) {
    +      $definition = \Drupal::service('plugin.manager.field.field_type')
    +        ->getDefinition($this->getType());
    +      if (isset($definition['default_value'])) {
    +        $value = $definition['default_value'];
    +      }
    +    }
    
    +++ b/core/lib/Drupal/Core/Field/FieldConfigBase.php
    @@ -340,6 +340,12 @@ public function getDefaultValue(ContentEntityInterface $entity) {
    +    if (!isset($value)) {
    +      $value = \Drupal::service('plugin.manager.field.field_type')
    +        ->getDefinition($this->getType())['default_value'];
    +    }
    

    Those two pieces of code should be exactly the same, right ?
    One does if (isset($definition['default_value']), the other does not - looks like this check is needed, since the 'default_value' entry is optional in the annotation ?

  3. +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/CreatedItem.php
    @@ -15,19 +15,11 @@
    + *   default_value = "NOW"
    
    +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/TimestampItemList.php
    @@ -0,0 +1,29 @@
    +  public static function processDefaultValue($default_value, ContentEntityInterface $entity, FieldDefinitionInterface $definition) {
    +    if ($default_value == 'NOW') {
    +      $default_value = REQUEST_TIME;
    +    }
    +    return parent::processDefaultValue($default_value, $entity, $definition);
    +  }
    

    OK, so this adds support for 'NOW' as a "default value" for timestamp field types - Great :-)

    But BaseFieldDefinitions can specify "allowed values" in several shapes :

    The phpdoc for BaseFieldDefinitions::setDefaultValue($value) says: "$value can be specified in the same formats returned by FDI::getDefaultValue()"
    FDI::getDefaultValue() says :
    "This can be either:
    - a literal, in which case it will be assigned to the first property of the first item.
    - a numerically indexed array of items, each item being a property/value array.- NULL or array() for no default value"

    Looks like this code here will only catch the 1st shape, which works for our tested case here because it's what CreatedItem's @FieldType annotation does.

    But looks like it would fail to catch

    $my_field = new BaseFieldDefinition('timestamp')
    ->setCardinality(2)
    ->setDefaultValue(array(
      0 => array('value' => 'NOW'),
      1 => array('value' => 'NOW')
    ));

    Same remark for the other cases added here (CURRENT_LANGUAGE / LanguageItem, RANDOM / UuidItem).

In short : that polymorphism in the way you can specify allowed values is great for UX in BaseFieldDefinition::setDefaultValue(), and was kind of OK since it matches what $item_list->setValue() accepts at the end of the chain, but it is problematic the moment you need to do some masaging on that mixed input in between. We should add a step that always expands the 1st shape into the 2nd shape, so that processDefaultValues() implementations that need to do this kind of massaging always work with a predictable shape.

This could be done :
- in the base implementation of FieldItemList::processDefaultValues(), but that only works if child implementations think of calling the parent first.
- by the caller of ::processDefaultValues(), before the call. That would allow better documenting the @param and @return of FieldItemListInterface::processDefaultValues(), but has the drawback that the code that calls ::processDefaultValues() is duplicated in BaseFieldDefinition::getDefaultValue() and FieldConfigBase::getDefaultValue() :-(

fgm’s picture

Status: Needs work » Needs review
FileSize
13.14 KB

Rerolled to take into account

- part of 1) (don't know how to document the mixed return, since it's basically anything)
- 2)

and hopefully fix one test, which tested for an undefaulted timestamp which is now defaulted.

Status: Needs review » Needs work

The last submitted patch, 18: 2318605-default-values.patch, failed testing.

fgm’s picture

Status: Needs work » Needs review
FileSize
15.46 KB

More test fixes : because created now defaults to NOW, the install user gets included in the online users.

yched’s picture

@fgm : interdiffs ? :-)

Regarding #17.3 :
Actually, I think we can consider this ("implementations of processDefaultValue() are currently supposed to do their job on data whose shape can vary") as an existing issue in the current API. This patch just adds implementations of processDefaultValue() that do not take that polymorphism into account, but the existing implementations that exist in HEAD (e.g in DateTimeFieldItemList or EntityReferenceFieldItemList) are currently equally broken, in that they assume they receive $default_value in a specific shape, which might not be the case.

So I think it's fine to proceed here, and fix processDefaultValue() in a separate issue. I'll try to open one soon.

Status: Needs review » Needs work

The last submitted patch, 20: 2318605-default-values.patch, failed testing.

yched’s picture

fgm’s picture

Status: Needs work » Needs review
FileSize
20.11 KB

More fails removed. Don't forget (like I did) that in PHP, 0 == 'NOW' .

Status: Needs review » Needs work

The last submitted patch, 24: 2318605-default-values.patch, failed testing.

fgm’s picture

Status: Needs work » Needs review
FileSize
20.1 KB

One down ?

Status: Needs review » Needs work

The last submitted patch, 26: 2318605-default-values.patch, failed testing.

fgm’s picture

Status: Needs work » Needs review
FileSize
20.1 KB

Rerolled to match HEAD class renaming.

Status: Needs review » Needs work

The last submitted patch, 28: 2318605-default-values-28.patch, failed testing.

fgm’s picture

Status: Needs work » Needs review
FileSize
10.59 KB
9.92 KB

As discussed with yched and gabor, removing the language support from this patch, as this is another can of worms which warrants its own followup issue.

Interdiff is with the #24 patch, not the latest one.

fago’s picture

Status: Needs review » Needs work
+++ b/core/modules/user/src/Tests/UserBlocksTest.php
@@ -8,6 +8,7 @@
@@ -76,7 +77,10 @@ function testUserLoginBlock() {

@@ -76,7 +77,10 @@ function testUserLoginBlock() {
   function testWhosOnlineBlock() {
     $block = $this->drupalPlaceBlock('views_block:who_s_online-who_s_online_block');
 
-    // Generate users.
+    // Get the install user.
+    $install_user = User::load(1);
+

Looks like some unrelated changes sneaked in. Else the patch looks good to me.

fgm’s picture

@fago : as I discuessed with @yched, this is actually related : prior to this patch, the timestamp information on the install user were not initialized, and now they are, like for any other user. Better consistency, IMO.

In turn, this causes the install user to be listed in the Who's online block, so the test needs to account for it.

yched’s picture

Like @fago said - the changes in testUserLoginBlock() just seem to be testing more things (adding checks about the $install_user). Not sure why this patch means we need to test more things there ?

Other than that, RTBC.

We should open an issue for the "default language" part @fago described in #3.

fgm’s picture

@yched : as I wrote above, the patch causes the install user to be part of the "who's online" block (not the testUserLoginBlock as git would have you believe), because its timestamps are now correctly initialized, which they never were previously, so I think the tests needs to be modified to reflect this.

fgm’s picture

Status: Needs work » Needs review
FileSize
10.7 KB
1.16 KB

Added comment per our offline discussion.

yched’s picture

Status: Needs review » Reviewed & tested by the community

Thanks!

fago’s picture

I see - thanks! Agreed this is RTBC, but re-uploading to make sure that exactly the committed patch has been tested. No changes!

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 37: d8_typed_data_adapter-2002138-118.patch, failed testing.

fgm’s picture

@fago that looks like an entirely different patch ?

fago’s picture

Status: Needs work » Needs review
FileSize
10.7 KB

ops, sry. Re-uploading the same file again seems to be a too hard task for me ;-) Next try. (No changes!)

yched’s picture

Status: Needs review » Reviewed & tested by the community

Bot seems a bit distracted, but RTBC when green

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 40: 2318605-default-values-35.patch, failed testing.

Berdir’s picture

Status: Needs work » Needs review
FileSize
10.7 KB

Testbot ate the previous patch, uploading again, wasn't able to trigger a restart on testbot side. No commit credit :)

Berdir’s picture

Status: Needs review » Reviewed & tested by the community

Was RTBC, testbot can set it back if he disagrees.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 43: 2318605-default-values-35.patch, failed testing.

yched’s picture

Oops, I expected it would be the other way around :-)

Basically, the changes needed here is that processDefaultValue() now receives $default_value as an array keyed by delta, e.g :

array(
  0 => array('value' => 'NOW')
);

The implementations added in this patch need to be adjusted to do their massaging in that format - basically, doing a foreach ($default_value as $delta => &$item_value) { process $item_value }

yched’s picture

Status: Needs work » Needs review
FileSize
10.88 KB
4.93 KB

Here's the updated patch.

The interdiff hunks in getDefaultValue() implementations are about doing things in the right order :
- get the default value as specified in the field definition
- if not present, get it from the field type (added by this patch here)
- normalize it to an array (added by #2347711: FieldItemlListInterface::processDefaultValue($default_value) is expected to massage polymorphic data)
- pass it to processDefaultValue()

Status: Needs review » Needs work

The last submitted patch, 49: 2318605-default-values-39.patch, failed testing.

yched’s picture

Status: Needs work » Needs review
FileSize
11.18 KB
1.33 KB

NULL needs to be normalized to array() if we want processDefaultValue() implementations to just foreach (also, the phpdoc for processDefaultValue() says it receives an array). That's more a bug from #2347711: FieldItemlListInterface::processDefaultValue($default_value) is expected to massage polymorphic data :-/

yched’s picture

Thinking a bit more about uuids:

UuidItem fields defaulting to a newly generated value duplicates the code that currently assigns UUIDs on entity_create() :

EntityStorageBase::create()
    // Assign a new UUID if there is none yet.
    if ($this->uuidKey && $this->uuidService && !isset($values[$this->uuidKey])) {
      $values[$this->uuidKey] = $this->uuidService->generate();
    }

That one runs for both config and content entities, while the feature added here only scopes content entities - and is actually never leveraged, since the Storage handler makes sure a value is specified for the uuid field before it reaches the place where ItemList::assigndefaultValue() is called.
Seems confusing to have two places that try to create UUIDs on new entities, one of which never actually runs ?

Moreover - what if I want a field that stores a UUID as a reference / foreign key ? I wouldn't want a "newly generated UUID" to be applied as a default value there. Then I need to specify ->setDefaultValue(NULL) or something ?

In the end, I'm not fully convinced that adding that as "the default value for all fields of this type" really helps. *If* we really want the generation of entity primary UUIDs to go through the "default values" flow (and, as stated above, that is currently not the case even with this patch), then why don't we leave it to each field definition to specify $field['uuid'] = new BFD('uuid')->setDefaultValue('RANDOM') ?

yched’s picture

Oh gee. That code in EntityStorageBase::create() actually only runs for config entities, because ConfigEntityStorage defines $this->uuidService and ContentEntityStorageBase doesn't. Not exactly intuitive :-/

Why don't we rather unify this for config and content entities, then ?

fago’s picture

Title: uuid, created, changed default value implementations need to be updated » uuid, created, changed, language default value implementations need to be updated
Priority: Normal » Major
Issue summary: View changes

Bumped into this while working on #2405943: User entity validation misses form validation logic in conjunction with languages. Added missing language field to the issue summary and updating title.

Also I think this is major because it requires us to do this:

    // NULL or array() mean "no default value", but  0, '0' and the empty string
    // are valid default values.
    if (!isset($value) || (is_array($value) && empty($value))) {
      // Create one field item and apply defaults.
      $this->first()->applyDefaultValue(FALSE);
    }
    else {
      $this->setValue($value, $notify);
    }

This effectively makes the *valid* default value of NULL for language fields being ignored, while the currently used *invalid* default value of '' works. ('' is no valid language, nor is the field unset).

yched’s picture

I still think we should do this too.
Just, as explained in #52 / #53, I'm not sure we should include UUID fields in that mechanism.

fago’s picture

I agree that having a random default value as uuid field type default, doesn't make so much sense.

$field['uuid'] = new BFD('uuid')->setDefaultValue('RANDOM') ?

Yeah, that would make sense to me - so you can see the default value from looking at the BFD. The storage's create method is the last place I'd look for a default value assignment actually.
So for config entities, couldn't we do that in the Entity base classes' pre/post create method instead?

yched’s picture

Yep, I think #56 would make sense to me too - if we do include the "for ConfigEntities, create the UUID in ConfigEntityBase::pre/postCreate()" part :-)

The current situation where:
- EntityStorageBase::create() seems to provide a generic mechanism for UUID generation,
- but you have to look close enough to understand that it's only opt-in (only if the actual storage subclass has a $this->uuidService),
- and that ContentEntityBase choses to opt-out (by not having a $this->uuidService), and instead has UUIDs generated in a whole different code flow (field default values)
feels very confusing to me :-)

yched’s picture

Also, looking back at it:

$field['uuid'] = new BFD('uuid')->setDefaultValue('RANDOM');
$field['date'] = new BFD('date')->setDefaultValue('NOW');

feels like we should highlight a bit more the "special/magic placeholder" aspect. As is, they look like legit strings for a regular, literal default value.

Maybe we make them look weirder ? '**RANDOM**', '**DATE**' ? (Views has/had something like that IIRC)

Also, those magic placeholders only apply to a given field type, and would be treated as a "regular" litteral if used with another field type. 'RANDOM' feels like something you might be very tempted to use on other fields types :-)
I was thinking about using class constants defined by the individual FieldItem classes, but I guess that would prevent using them in annotations for "all fields of this type have a dynamic default value" (is that really useful though ?) Or maybe just stick to '**UUID**' for the "generate uuid" placeholder ?

tstoeckler’s picture

Re #58: Can't we just make them constants somewhere? (Then I don't care very much about the actual values.) But in my world a kitten dies everytime I see "***LANGUAGE_language_content***"...

Also, with this patch, there's no reason for ChangedItem to extend CreatedItem any longer, is there?

yched’s picture

@tstoeckler - from #58

I guess [constants] would prevent using them in annotations for "all fields of this type have a dynamic default value" (is that really useful though ?)

I guess this depends on whether we need to support "the field type enforces a 'default default value' in its field type definition" :-)

yched’s picture

Oh, right, the whole point of CreatedItem as a separate field type is that it encapsulates the "default value is NOW" behavior in its field type definition. So it requires the "magic placeholders" to be something you can put in an @Annotation.

Never been fully convinced about that :-), and given the discussion in #56 / #57 about using $field['uuid'] = new BFD('uuid')->setDefaultValue('RANDOM'); for uuid generation, IMO doing the same for 'created' field (regular timestamp field with an explicit default value of 'NOW' in the BFD) would be consistent.
.

Status: Needs review » Needs work

The last submitted patch, 51: 2318605-field_type_default_values-51.patch, failed testing.

yched’s picture

jhedstrom’s picture

Version: 8.0.x-dev » 8.2.x-dev
Status: Needs work » Postponed (maintainer needs more info)
Issue tags: +Needs issue summary update

Is there anything left that can be done in 8.x here?

xjm’s picture

Issue tags: -beta target

This issue was marked as a beta target for the 8.0.x beta, but is not applicable as an 8.1.x beta target, so untagging.

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

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now 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.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now 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.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now 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.

andypost’s picture

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

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now 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.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now 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.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.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.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). 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.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now 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: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

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

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.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.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

quietone’s picture

Issue summary: View changes
Issue tags: +Bug Smash Initiative

darvanen and I discussed this in #bugsmash. We think this is a task instead of a bug so changing category. And it certainly needs an Issue Summary update. I added the standard template to start that process off.

quietone’s picture

Category: Bug report » Task

Really change to a task

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

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now 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.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now 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: 10.1.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, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.