Problem/Motivation

It is valid for an entity type not to specify a canonical link. If you call $entity->toUrl() on an entity of that type, it will fail with a

No link template 'canonical' found for the '...' entity type

exception.

If you explicitly dealing with an entity type of that type, just calling $entity->toUrl() like that might be considered a bug, as you should instead do $entity->toUrl('edit-form') (assuming there is an edit-form link) or whatever other link you want to link to, but there is a lot of code in core that generically deals with entities of any type and just wants to output "a link" to an entity. Code like that currently breaks with entities without a canonical link.

See #3367475: [meta] Improve support for entity types without a canonical link for more context, but I think the moist poignant example is the cancel URL of entity delete forms (see Drupal/Core/Entity/EntityDeleteFormTrait::getCancelUrl():

      // Otherwise fall back to the default link template.
      return $entity->toUrl();

The comment notes that it does not really care, whether the canonical link template is used or not, but it needs to link somewhere. It seems unfortunate to require EntityDeleteFormTrait to explicitly check the availability of various link templates. Since we have chosen to make $rel optional, I think we should try to actually make that work also for entities without a canonical link.

Steps to reproduce

1. Create an entity type without a canonical link and provide the default delete form used in core.
2. Expect the delete form to work.
3. Frown, because the delete form throws an exception.

Proposed resolution

In Entity::toUrl(), if no $rel is passed explicitly, check if no canonical link exists, but edit-form does and in that case fall back to edit-form.

Remaining tasks

Review the change record

User interface changes

-

API changes

EntityBase::toUrl() works without specifying $rel for entities without a canonical link.

Data model changes

-

Release notes snippet

Issue fork drupal-3371753

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

tstoeckler created an issue. See original summary.

tstoeckler’s picture

Status: Active » Needs review
StatusFileSize
new2.44 KB

This is the least intrusive version possible. It still fails in the same way for entities with neither a canonical nor an edit-form link.

I think it would be slightly better to in that case throw a more helpful exception in that case and possibly we could also consider other link templates than edit-form as fallback, but I wanted to make the smallest possible change first.

As an additional improvement we could remove the override of ConfigEntityBase::toUrl() which defaults $rel to edit-form directly, but didn't do that yet, either.

sonam_sharma made their first commit to this issue’s fork.

tstoeckler’s picture

StatusFileSize
new2.8 KB
new4.51 KB

This implements the additional things noted in #2.

The additional exception being thrown, while technically a behavioral change, shouldn't really affect anyone as it's the same exception class, so in effect there is not really a change, just a (slightly) more meaningful message.

The default value change in ConfigEntityBase is somewhat of a behavior change for config entities that do provide a canonical link. Those are rare, but Search API indexes, for example, provide a status overview of the index in addition to the edit-form. Search API already provides a custom delete form where the cancel link links to the canonical URL, but a similar contrib or custom module would notice a change if it were using core's default entity delete form. This is an improvement, however, as it does make sense to link to the canonical URL in that case. The only reason the override was there in the first-place was to allow the "default URL" case for config entities at all, which is still possible with this.

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Needs change record

Removing credit from sonam_sharma for the empty MR.

Change makes sense but think we will need a change record for the new behavior please

Thanks!

tstoeckler’s picture

Title: Fall back to 'edit-form' as default $rel in Entity::toUrl() » Fall back to 'edit-form' as default $rel in EntityBase::toUrl()
Status: Needs work » Needs review
Issue tags: -Needs change record
StatusFileSize
new2.18 KB
new5.91 KB

Good point, added a change notice.

Also fixed some stray characters in the exception message. I thought about how to test this properly and looked into actually adding a functional test for the delete form cancel URL, but our test entity types override the cancel URL of the delete form for some reason (see \Drupal\entity_test\EntityTestDeleteForm::getCancelUrl()). We do have EntityUrlTest, however, so that seemed reasonable enough to add a small test to.

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: +Needs Review Queue Initiative

Change looks good. Think ready for committer review.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 7: 3371753-7.patch, failed testing. View results

smustgrave’s picture

Status: Needs work » Reviewed & tested by the community

Seems random

lauriii’s picture

In my opinion adding the 'edit-form' as a fallback to entities without canonical URL seems reasonable, but I'd love to hear what the subsystem maintainers or framework managers think about this.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 7: 3371753-7.patch, failed testing. View results

tstoeckler’s picture

Status: Needs work » Reviewed & tested by the community

Random failure

quietone’s picture

Issue summary: View changes

I'm triaging RTBC issues.

The IS is up to date and the proposed resolution matches the change. All questions have been answered. I read the CR and made changes for readability. I have added an item to the remaining tasks to review the change record.

Other than that the only thing is review by a subsystem maintainer review or framework manager as stated in #11.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 7: 3371753-7.patch, failed testing. View results

lauriii’s picture

  • catch committed 9c4bc86c on 11.x
    Issue #3371753 by tstoeckler, smustgrave, lauriii: Fall back to 'edit-...
catch’s picture

Status: Reviewed & tested by the community » Fixed
Issue tags: -Needs subsystem maintainer review

Untagging for subystem maintainer review since I am one. I think it makes sense to prioritise the canonical URL if one exists instead of always defaulting to edit, and for me the change record is enough for the small behaviour change.

Committed 9c4bc86 and pushed to 11.x. Thanks!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

larowlan’s picture

tstoeckler’s picture

I was wondering how this could have broken BC, as I thought I/we had been careful about that, but I completely missed that Entity::toUrl() does in fact handle entities with a uri_callback and that those entities do not necessarily define any link templates.

Sorry about that! Opened #3421114: [regression] Entity::toUrl() without argument is broken for entity types with a URI callback as a (hopefully) quick follow-up to revert the unintended API change.

jenlampton’s picture

We have one site using translation that is unable to delete files at all, and on all our others we able to reproduce the same problem when we remove the `destination` parameter in the URL.

edit: Oops, I should have read the issue linked in THE PREVIOUS COMMENT more closely. Will try that patch first :)

jenlampton’s picture

That issue appears unrelated to our problems with files. We're now working over here: https://www.drupal.org/project/drupal/issues/3424701