Problem/Motivation

- Enable Multilingual modules
- Add a language on the site (I added "spannish")
- Enable Custom menu link translations on the settings page "admin/config/regional/content-language" and check the "menu link item" as a translatable
- Add a new menu item on a Menu (exemple: admin/structure/menu/manage/main)
- Translate this newly created menu item
- You should be on the page "/es/admin/structure/menu/item/1/edit/translations/add/en/es"

Here, the breadcrumb displays

Note : if we click on any of those "Add" link, it crashes.

The add link links to "/es/admin/structure/menu/item/2/edit/translations/add" for the first one, and "/es/admin/structure/menu/item/2/edit/translations/add/es" for the second.

Remaining tasks

- Find out why the "Add" are displayed twice
- Fix the crash (Not sure about this one, since the "Add" item should not even be here).

I'm putting this as "major" since it display an error by clicking on a link. Not sure if major or normal.

CommentFileSizeAuthor
#76 2542834-76.patch1.66 KBConnBi
#72 2542834-72.patch11.49 KBsegi
#67 2542834-67.patch11.52 KBAjitS
#66 2542834-66.patch11.72 KBAjitS
#63 2542834-62-63-interdiff.txt1.25 KBgnuget
#63 2542834-63.patch11.76 KBgnuget
#62 2542834-62.patch11.78 KBgnuget
#55 2542834-55.patch11.7 KBdravenk
#53 2542834-54.patch11.18 KBdravenk
#48 2542834-47-content-translation-routes.patch12.8 KBtstoeckler
#47 2542834-47-content-translation-routes.txt12.8 KBtstoeckler
#47 2542834-45-47--interdiff.txt6.1 KBtstoeckler
#45 2542834-45.patch8.93 KBtstoeckler
#45 2542834-43-45-interdiff.txt1.19 KBtstoeckler
#43 2542834-43.patch8.88 KBtstoeckler
#43 2542834-40-43-interdiff.txt1 KBtstoeckler
#40 2542834-40.patch8.65 KBtstoeckler
#40 2542834-22-40-interdiff.txt3.12 KBtstoeckler
#22 2542834-21.patch8.82 KBmorenstrat
#19 2542834-19.patch5.35 KBmorenstrat
#16 2542834-16.patch4.53 KBmorenstrat
#13 2542834-13.patch2.61 KBmorenstrat
#4 capture_16df40a.png16.21 KBHaza
#2 2542834.menu_item_translation_bug.2.patch770 bytesHaza
capture_fc4e58e.png94.03 KBHaza
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Haza’s picture

Issue summary: View changes
Haza’s picture

Status: Active » Needs review
FileSize
770 bytes

Very small attached that removes the "forced" NULL values that are passed to ContentTranslationController::Add().

It removes the "add" links that does not have any reason to be on this page.
I think that the crash is linked to a page that should not even exist, due to a faulty generated link.

Not sure if this is the right approach.

Haza’s picture

Title: Menu item translate : breadcrumb item "add" leads to crash » Menu item translation : breadcrumb item "add" leads to crash
Haza’s picture

Title: Menu item translation : breadcrumb item "add" leads to crash » Menu item translation : breadcrumb displays (twice) "add" that have no sense
Issue summary: View changes
FileSize
16.21 KB
camoa’s picture

Basically the Add was an attempt to create the link to the same page where they were shown, but that broke in 2 links (something like add/en/es is the right link and it created add/ and then add/es) The main question here is why are those added and if this may happen in some other place.

swentel’s picture

Issue tags: +D8MI

This happens for any translation add screen, also for content for instance, so I guess it simply happens everywhere.

tstoeckler’s picture

Component: language system » content_translation.module
Issue tags: +language-content

Tagging and re-categorizing.

tstoeckler’s picture

tstoeckler’s picture

Issue tags: +SprintWeekendBerlin
tstoeckler’s picture

Issue tags: +Needs tests

Like I proposed in the duplicate issue, I think we should also remove the NULL language from the edit and delete route.

And we need tests for this.

tstoeckler’s picture

Issue tags: +SprintWeekend2016
morenstrat’s picture

Assigned: Unassigned » morenstrat
morenstrat’s picture

Added a test and whitelisted links in NodeViewController.

tstoeckler’s picture

Status: Needs review » Needs work
Issue tags:

Yeah I had already found that problem with NodeViewController in #2656172: Fatal errors can be triggered on content translation add routes (+ incorrect breadcrumb on add form), but forgot to mention it here.

The test looks good. What is not being tested is the bogus breadcrumb that is there. So marking "Needs work" for that.

Also maybe we can tackle the edit and delete routes here, as I mentioned in #10, but I'm also fine with doing that in a follow-up.

The last submitted patch, 13: 2542834-13.patch, failed testing.

morenstrat’s picture

FileSize
4.53 KB

Added a test for the breadcrumb links, removed the NULL language from the edit and delete routes and changed the content translation access check to perform the access checks against the unchanged entities from storage.

morenstrat’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 16: 2542834-16.patch, failed testing.

morenstrat’s picture

Status: Needs work » Needs review
FileSize
5.35 KB
swentel’s picture

+++ b/core/modules/node/src/Controller/NodeViewController.php
@@ -22,6 +22,11 @@ public function view(EntityInterface $node, $view_mode = 'full', $langcode = NUL
+      }

Hmm, we should document this somehow for other entity types out there. There's no other way we can control this more upstream in the code ?

Status: Needs review » Needs work

The last submitted patch, 19: 2542834-19.patch, failed testing.

morenstrat’s picture

Status: Needs work » Needs review
FileSize
8.82 KB

Fixed ContentTranslationManageAccessCheckTest.

tstoeckler’s picture

Re @swentel #20: Yeah, this is not the nicest code out there. I discussed this with @morenstrat in Person.

I personally found blacklisting the content translation links instead of the whitelisting even more hacky, that's why I suggested this approach.

The current code is certainly broken (i.e. even in HEAD). Its just that this patch exposes the broken links.

In General our "API" regarding entity links is very lacking, i.e. there is no way to distinguish e.g. canonical from content-translation-add.

So yeah, not sure about this, but also not sure what else to do...

tstoeckler’s picture

Looked at the patch now. I have nothing to complain; this looks good to go to me. Because this touches a couple of tricky parts, though, not setting RTBC yet but waiting for another set of eyes, especially an answer from @swentel

swentel’s picture

I don't have any better idea now either, so I won't hold this off. Feel free to RTBC :)

tstoeckler’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: -Needs tests

OK, coolio

catch’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/modules/node/src/Controller/NodeViewController.php
@@ -22,6 +22,11 @@ public function view(EntityInterface $node, $view_mode = 'full', $langcode = NUL
+      // Whitelist links to remove content translation links.

I know it's been discussed a bit, but would like to figure out if this is really the only way to do it.

What about other links not in the list that might be added? Do we know they should always be removed too?

Why can't content_translation alter its own links out of here? Then we'd need neither a blacklist nor a whitelist.

tstoeckler’s picture

Mmhh.. There's no alter hook that gets called because this directly returns the controller result. What we could do is add a #pre_render callback in hook_entity_view() which then does the unsetting for us. I'm going to try that.

DuaelFr’s picture

Thanks all for your work here.
This issues becomes a bit hard to follow. Could you move that links removal in another issue so we can focus on breadcrumbs here and get it fixed quicker?

tstoeckler’s picture

@DuaelFr: I would, if it were possible. The links that are generated in HEAD are broken already, it's just that it happens to go through without a fatal coincidentally. By fixing the bogus optionality of the arguments we are exposing that bug, by actually making the link generation fail. Thus, both bugs need to be fixed together in order to get the tests to pass.

DuaelFr’s picture

@tstoeckler Ok so you need to change the issue title and summary to reflect that fact :)
Thank you for your enlighting answer!

tstoeckler’s picture

True! Thanks for noting that.

morenstrat’s picture

@tstoeckler: are you sure we can fix this in a pre render callback? The exception is thrown when the content translation add url is added to the render array.

morenstrat’s picture

I'm not sure about "allowed" changes in patch or minor releases. Would it be an option to add an alter hook to Entity::uriRelationships() so that the content translation module could remove its links?

tstoeckler’s picture

Assigned: morenstrat » catch

@morenstrat: He, you are right, good catch. I should really know better by know than to simply claim that something is possible without trying it out... Because, generally we now have Url objects, that only get rendered when we actually hit the Twig template I thought this could actually work, but it doesn't at least not just like that.

The problem: NodeViewController and the two other places this code was copy-pasted to in core - NodePreviewController and taxonomy_page_attachments_alter() - just use $entity->url() which converts to a string directly, instead of (properly) using $entity->toUrl() which returns such a Url object. So if we change that, we can then implement hook_entity_build_defaults_alter() in Content Translation to add a #pre_render callback to the build that removes the respective links from $build['#attached']['html_head_link']. (Note that despite what I said above, I did not actually try this last part out, so beware... ;-))

...except then we hit another problem: In this particular case the Url objects don't just end up being rendered by Twig templates (which would work fine) because that would be just too easy... Instead HtmlResponseAttachmentsProcessor converts these into render placeholders but it does not account for the href key to be a Url object. I think it is in-line with our philosophy of "rendering as late as possible" to make HtmlResponseAttachmentsProcessor convert Url objects to strings if it encounters them, so after spending some quality time trying out a variety of different places to stick these 3 lines, I came up with the following "patch" for \Drupal\Core\Render\HtmlResponseAttachmentsProcessor::processHtmlHeadLink() which then should make the code suggested in the previous paragraph actually work:

  protected function processHtmlHeadLink(array $html_head_link) {
    $attached = [];

    foreach ($html_head_link as $item) {
      $attributes = $item[0];
      $should_add_header = isset($item[1]) ? $item[1] : FALSE;

+     if ($attributes['href'] instanceof Url) {
+       $attributes['href'] = $attributes['href']->toString();
+     }

      $element = array(
        '#tag' => 'link',
        '#attributes' => $attributes,
      );
      $href = $attributes['href'];
      $attached['html_head'][] = [$element, 'html_head_link:' . $attributes['rel'] . ':' . $href];

      if ($should_add_header) {
        // Also add a HTTP header "Link:".
        $href = '<' . Html::escape($attributes['href'] . '>');
        unset($attributes['href']);
        $attached['http_header'][] = ['Link', $href . drupal_http_header_attributes($attributes), TRUE];
      }
    }
    return $attached;
  }

... however, I'm not sure that's actually such a good idea - despite the late rendering (which in itself is a good thing) because $url->toString() looses cacheability metadata of the URL generation. In NodeViewController (and the other places) where this is currently being called (because $entity->url() which is actually being called is just a shorthand for $entity->toUrl()->toString) we are operating inside of the render context of the main page controller so the metadata does actually get caught in the end. In HtmlResponseAttachmentsProcessor, however, we are not in any render context as far as I know. So on top of increasing the complexity of the patch a fair bit, pursuing this direction would actually be a regression of the cacheability metadata, unless I'm missing something.

Due to all this assigning to @catch for some feedback on how we want to proceed here. I sincerely hope I am making any sense here; I apologize for being a little bit ramble-y. It's fairly late here and I just spent an amount of time larger than I'd like to admit staring at HtmlResponseAttachmentsProcessor...

And thanks again @morenstart for setting me straight!

tstoeckler’s picture

Re #34: I guess it really depends on the semantics of the uriRelationships() method whether something like that would be appropriate. Content Translation only adds those link-templates in the first place because they are used for the route generation of the content translation routes. So we want Content Translation to show up in the link templates (at least in those specific cases), and since currently $entity->uriRelationships() is literally array_keys($entity->linkTemplates()) it shows up in there as well. So I don't really know how to fix this "properly", to be honest. An alter hook might be a solution, but I'm not sure of all the consequences of this.

There is #2113345: Define a mechanism for custom link relationships which aims to provide more of a proper API for link relations (rather than the sort of "free-for-all dumping ground" we have now) but that has seen no activity in almost a yearand has no actual code... :-/

Maybe @catch or someone else who is more knowledgeable about the whole area of link relations can provide some input here.

tstoeckler’s picture

Because I still had this applied locally and played around with the site for some other purpose I just found another tidbit that we would need to adress if we were to pursue #27 and later:
I said that $entity->url() is equivalent to $entity->toUrl()->toString() and did not mention the fact that the former actually does a check for $entity->id() and simply returns an empty string if there is no ID, because I thought this check is not relevant.

It actually is, however, we currently rely on it in order for the link-generating code to not fatal. So we would have to adapt (at least) NodePreviewController for that, as well. Although, thinking about it more, I'm not sure why we even generate those links for a preview. Unless I'm missing something this seems incredibly pointless.

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

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

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

tstoeckler’s picture

tstoeckler’s picture

Status: Needs work » Needs review
FileSize
3.12 KB
8.65 KB

This is an attempt at resolving this issue by avoiding the code mentioned by @catch in #27 and instead hardcoding knowledge about the Content Translation routes in Entity::uriRouteParameters() - also not very elegant, but completely backwards compatible as far as I know.

Note that in order to provide test coverage for the new code in Entity::uriRouteParameters() this would have to be postponed on #2751395: Rewrite EntityUrlTest, but not marking as such yet to get some feedback on the approach first.

tstoeckler’s picture

Status: Needs review » Needs work

The last submitted patch, 40: 2542834-40.patch, failed testing.

tstoeckler’s picture

Status: Needs work » Needs review
FileSize
1 KB
8.88 KB

Just shooting in the dark here.

Status: Needs review » Needs work

The last submitted patch, 43: 2542834-43.patch, failed testing.

tstoeckler’s picture

Status: Needs work » Needs review
FileSize
1.19 KB
8.93 KB

Okay, only ever so slightly less elegant. Let's see if this is green.

tstoeckler’s picture

Now that #2751395: Rewrite EntityUrlTest is in, this could use some test coverage. Still leaving at Needs review, though, for some input on the general direction.

tstoeckler’s picture

FileSize
6.1 KB
12.8 KB

Decided to remove the complex language finding - it's pointless to call this anyway. Added a comment to that extent as well. Also adds some tests.

tstoeckler’s picture

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

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

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

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

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

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

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

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

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

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

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

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

dravenk’s picture

Version: 8.5.x-dev » 8.6.x-dev
Status: Needs review » Reviewed & tested by the community
FileSize
11.18 KB
+++ b/core/lib/Drupal/Core/Entity/Entity.php
@@ -12,6 +12,7 @@
+use Drupal\Core\TypedData\TranslatableInterface;

@@ -310,6 +311,19 @@ protected function urlRouteParameters($rel) {
+    // Nodes and taxonomy link to all possible link relations in the HTML head,
+    // so we need to support calling $entity->toUrl() for the content
+    // translation link relations, even though that does not make sense
+    // semantically without being able to specify the translation language.
...
+    elseif ($rel === 'drupal:content-translation-add' && $this instanceof TranslatableInterface) {
+      $uri_route_parameters['source'] = $this->language()->getId();
+      $uri_route_parameters['target'] = $this->language()->getId();
+    }
+    elseif (in_array($rel, ['drupal:content-translation-edit', 'drupal:content-translation-delete'], TRUE) && $this instanceof TranslatableInterface) {
+      $uri_route_parameters['language'] = $this->language()->getId();
+    }
+

Remove those lines, because node/2113345 was fixed.

Reroll. This patch work for me.Thanks.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 53: 2542834-54.patch, failed testing. View results

dravenk’s picture

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.

gnuget’s picture

Status: Needs work » Needs review
FileSize
11.78 KB

Here a rebase of #55 for Drupal 8.9.x.

(This might still needs work but I want to know how many tests it is going to break)

gnuget’s picture

gnuget’s picture

Assigned: catch » Unassigned
apaderno’s picture

AjitS’s picture

Rerolled for 9.3.x

AjitS’s picture

FileSize
11.52 KB

Fixed the coding standard issues.

Status: Needs review » Needs work

The last submitted patch, 67: 2542834-67.patch, failed testing. View results

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.

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.

segi’s picture

Re-rolled the patch for 9.5.x

andypost’s picture

apaderno’s picture

Yes, #2113345: Define a mechanism for custom link relationships has been fixed on January, 2017. That comment is not necessary any more.

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.

ConnBi’s picture

Create a patch for drupal 10.1.x