Updated as of #50

Problem/Motivation

Found in #2006606-46: Views rendering ignores entity language, eg: Identical nodes rendered in views when nodes have translations. When an entity (eg. node) is rendered in a language that is different from the page's language, the links are still rendered in the page's language, so the node title, read more link, etc. will lead to the version of the entity in the language of the page instead of the language displayed on the prior page.

With a view displaying different language copies of the same node:

Proposed resolution

Initial proposed solution: The links generated need the language passed on explicitly, so the right language version links are generated.

Now proposed solution: load the right translation of the node at the start, that then passes on the right information for the links code. (See interdiff in #35). still pass the language as it might be used for something else.

This issue is not about fixing the duplicates on the front page view. That would be #2161845: Node views (front page, admin) do not use the proper language filter.

Remaining tasks

  • (done) Get read more links pointing to correct language
  • (?) Figure out if more affected places exist.
  • (done) Write tests.
  • Review
  • open follow-ups (at least see #66, read other comments also)

User interface changes

Links fixed.

API changes

None.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Gábor Hojtsy’s picture

Gábor Hojtsy’s picture

Issue summary: View changes

Status: Needs review » Needs work

The last submitted patch, 1: 2149649.patch, failed testing.

Gábor Hojtsy’s picture

Project: (Obsolete) configuration translation for Drupal 8 » Drupal core
Version: 8.x-1.x-dev » 8.x-dev
Component: Code » theme system
Status: Needs work » Needs review

Should have been filed against core :)

Gábor Hojtsy’s picture

1: 2149649.patch queued for re-testing.

Status: Needs review » Needs work

The last submitted patch, 1: 2149649.patch, failed testing.

herom’s picture

Status: Needs work » Needs review
FileSize
1.79 KB

langcode is language()->id. right?

Status: Needs review » Needs work

The last submitted patch, 7: 2149649-7.patch, failed testing.

herom’s picture

FileSize
1.77 KB
herom’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 9: 2149649-9.patch, failed testing.

Gábor Hojtsy’s picture

The language option needs the FULL language object, not just the langcode. We made a concerted effort to name arguments that expect a langcode a 'langcode'/$langcode, so if you see 'language', you can be sure that takes an object :)

plach’s picture

Status: Needs work » Needs review
Issue tags: +Needs tests
FileSize
1.76 KB

Let's try again

Status: Needs review » Needs work

The last submitted patch, 13: entity-link_language-2149649-13.patch, failed testing.

vijaycs85’s picture

Status: Needs work » Needs review
Issue tags: +LONDON_2014_JANUARY, +SprintWeekend2014

Updating path alias test to work with this change...

vijaycs85’s picture

Gábor Hojtsy’s picture

I know @plach was not entirely happy with this approach, but what better could we do? I think its not a big thing to ask to pass on language for the link generation and making the translation entity object somehow pass along may not be practical? Looks good to me.

plach’s picture

Let's move forward with this for now. If there is a way (and time) to improve things later we will try :)

Gábor Hojtsy’s picture

Status: Needs review » Reviewed & tested by the community

All right, looks good to me then. Thanks @plach for the confirmation.

Xano’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
3.81 KB

Re-roll because of EntityInterface::url().

Gábor Hojtsy’s picture

Status: Needs review » Reviewed & tested by the community
alexpott’s picture

Issue summary: View changes
Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs reroll

drupal_2149649_20.patch no longer applies.


Xano’s picture

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

Re-roll.

Gábor Hojtsy’s picture

Status: Needs review » Reviewed & tested by the community

Thanks!

xjm’s picture

Issue summary: View changes

.

vijaycs85’s picture

Issue tags: -Needs reroll

Removing 'Needs reroll' as the latest patch apply without any conflict.

YesCT’s picture

Status: Reviewed & tested by the community » Needs work
FileSize
232.55 KB
222.52 KB
242.42 KB
242.77 KB

I took a look at the test changes, but I dont see where it is testing to make sure the title (or read more) link goes to the language the node is being shown in.

I tried it out, and it seems to help the title, but not the read more.

A
With head

on front page /af, all links (title and read more) go to /af/node/1

B
With patch

on front page /af, title goes to /af/node/1,
but read more goes to /node/1
which is not what I expected

C
with just #2006606: Views rendering ignores entity language, eg: Identical nodes rendered in views when nodes have translations (note I didn't run into the error that was last reported there, sent that issue for retest.)

on front page /af, all links (title and read more) (of the one showing en title and body, and of the one showing af title and body) goes to /af/node/1
which is kind of ok. the question is does this issue fix things once with the case of having that patch applied?

D
with patch and #2006606: Views rendering ignores entity language, eg: Identical nodes rendered in views when nodes have translations

on front page /af, it does fix the title link for the english displaying node to go to /node/1, but the read more links are both /af/node/1 (and when front page /, they are both /node/1)

------
So, I think this patch helps, but still needs work to make other links (read more) know the language also, and for tests to test it.

Gábor Hojtsy’s picture

Indeed, the read more link does not seem to be affected based on looking at the patch.

webchick’s picture

Priority: Normal » Critical

This is a major regression from 7.x, so bumping.

YesCT’s picture

Issue summary: View changes

#2006606: Views rendering ignores entity language, eg: Identical nodes rendered in views when nodes have translations was committed, so we can just work on this directly. Right now, the read more links are what we need to get working.

Gábor Hojtsy’s picture

Anybody can help with that? :)

Gábor Hojtsy’s picture

Status: Needs work » Needs review

@YesCT: I looked at this to fix, but seems like both the node title and the read more link are covered in the same way:

  1. +++ b/core/modules/node/lib/Drupal/node/NodeViewBuilder.php
    @@ -118,6 +118,7 @@ protected static function buildLinks(NodeInterface $entity, $view_mode) {
             'href' => 'node/' . $entity->id(),
    +        'language' => $entity->language(),
             'html' => TRUE,
    

    This line is supposed to make the read more link point to the right place.

  2. +++ b/core/modules/node/node.module
    @@ -652,7 +652,9 @@ function template_preprocess_node(&$variables) {
    -  $variables['node_url'] = $node->url();
    +  $variables['node_url'] = $node->url('canonical', array(
    +    'language' => $node->language(),
    +  ));
    

    This is supposed to make the title link point to the right place.

Can you still reproduce the read more link pointing at the wrong place with the patch? (#2006606: Views rendering ignores entity language, eg: Identical nodes rendered in views when nodes have translations was committed in the meantime).

Gábor Hojtsy’s picture

FileSize
3.45 KB

BTW here is a reroll since this did not cleanly apply anymore.

Gábor Hojtsy’s picture

FileSize
3.44 KB
687 bytes

Also when trying this, noticed a Fatal error: Call to a member function language() on a non-object in /home/s551122e341a9c85/www/core/modules/comment/comment.module on line 468 which is obviously because the comment link has no $entity variable anymore, but a $node.

Gábor Hojtsy’s picture

FileSize
3.85 KB
691 bytes

The node read more links and the comment add links were incorrect indeed. Reason being the node was loaded as-is without regards to the language context. Then the language context was passed on to the links alter but not considered. If we just load the right translation of the node at the start, that then passes on the right information for the links code.

Needs tests since the above passed tests although it should not have, given the read more and the comment links were not good.

Gábor Hojtsy’s picture

FileSize
183.89 KB

Proof that this works well :) Now should only need more tests and should be good to go hopefully. Who can help with tests?

The last submitted patch, 33: drupal_2149649_33.patch, failed testing.

The last submitted patch, 34: drupal_2149649_34.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 35: drupal_2149649_35.patch, failed testing.

Gábor Hojtsy’s picture

Uhm, this segfaulted. Not sure how that would be related:

Segmentation fault
FATAL Drupal\toolbar\Tests\ToolbarAdminMenuTest: test runner returned a non-zero error code (139).

Also don't think there would be things related there. So retesting. BTW the reason for leaving the prior patches to get tested was to see if a simple reroll vs. the fixes would fail at a point. Since those were cancelled, we don't know anymore.

Gábor Hojtsy’s picture

35: drupal_2149649_35.patch queued for re-testing.

Gábor Hojtsy’s picture

Issue tags: +Random fail

#35 now passed, so need more tests. Tagging as random fail for #40, the full fail message is there.

YesCT’s picture

Status: Needs work » Needs review
Issue tags: -Random fail
FileSize
2.69 KB
7.33 KB
3.47 KB

just the readmore link tested.

copied from NodeAccessBaseTableTest
looked up the preg_match | syntax, but still not sure if it's needed. kept it in the copy and pasted code.

test only patch should fail. (fails locally)
patch should pass (the new tests pass locally)

---

while I was looking into this, I wondered why there is a $node->save(); after the hunk making translations. that is unrelated to this issue, but if it's not needed, would be a good novice issue to deal with it.

---
next, the comment (and remove the @var, which I was experimenting with)

YesCT’s picture

Issue tags: +Random fail

adding tag back.

Status: Needs review » Needs work

The last submitted patch, 43: drupal_2149649_42.patch, failed testing.

The last submitted patch, 43: drupal_2149649_42-testsonly.patch, failed testing.

YesCT’s picture

fail from #40 (see #2216701: Random test failure in ToolbarAdminMenuTest), but also

CollapsedDrupal\system\Tests\Common\RenderTest	137	6	0
Message	Group	Filename	Line	Function	Status
The token attribute was found in the cached child element markup	Other	RenderTest.php	909	Drupal\system\Tests\Common\RenderTest->testDrupalRenderChildElementRenderCachePlaceholder()	
The tokens are identical for the child element	Other 	RenderTest.php	914	Drupal\system\Tests\Common\RenderTest->testDrupalRenderChildElementRenderCachePlaceholder()	

and some similar ones.

retesting though, since the previous patch passed, and this one only changed a test.

YesCT’s picture

43: drupal_2149649_42.patch queued for re-testing.

YesCT’s picture

I thought of doing this, but the pattern for the default language (en in the test), is also present in the other langcode's hrefs, so it counts more than one.

    // Check the frontpage for 'Add new comment' links that include the
    // language.
    $comment_form_href = '/node/' . $node->id() . '#comment-form';
    foreach ($this->langcodes as $langcode) {
      $num_match_found = 0;
      if ($langcode == 'en') {
        // Site default language does not have langcode prefix in the URL.
        $expected_href = $comment_form_href;
      } else {
        $expected_href = '/' . $langcode . $comment_form_href;
      }
      $pattern = '|' . $expected_href . '$|';
      foreach ($this->xpath("//a[text()='Add new comment']") as $link) {
        if (preg_match($pattern, (string) $link['href'], $matches) == TRUE) {
          $num_match_found++;
        }
      }
      $this->assertTrue($num_match_found == 1, 'There should be 1 new comment link for the ' . $langcode . ' translation of a node on the frontpage. (Found ' . $num_match_found . '.)');
    }

so, went back to check checking it found at least one of each..

    // Check the frontpage for 'Add new comment' links that include the
    // language.
    $comment_form_href = '/node/' . $node->id() . '#comment-form';
    foreach ($this->langcodes as $langcode) {
      $match_found = FALSE;
      if ($langcode == 'en') {
        // Site default language does not have langcode prefix in the URL.
        $expected_href = $comment_form_href;
      } else {
        $expected_href = '/' . $langcode . $comment_form_href;
      }
      $pattern = '|' . $expected_href . '$|';
      foreach ($this->xpath("//a[text()='Add new comment']") as $link) {
        if (preg_match($pattern, (string) $link['href'], $matches) == TRUE) {
          $match_found = TRUE;
        }
      }
      $this->assertTrue($match_found, 'There is an Add new comment link for the ' . $langcode . ' translation of a node on the frontpage.');
    }

but that makes the check for en silly. (it wont fail if the en is not on the front page)

YesCT’s picture

ah, on retest, #42 passes.

ok. @sun suggested using a[starts-with( in xpath. But since I wanted to check both the link text and the ref, used the xpath to get the matches to the link text and then preg_match to check the ref.

@jhodgdon mentioned that they might have written a function that checks for matches both the text and ref at one point for drupal 7, but I didn't get details of where that might be.

This uses base_path(). And makes sure there are exactly 1 matches.

I dont use the $matches variable that is passed to preg_match(), so maybe that should be taken out.

Also, The two hunks of code could be merged so we loop just once through the languages.

But those are kinda small things.

Putting this out there for people to check if it's even the right place for tests and going in the right direction.

Removing the needs tests tag since this adds tests.

Since people will ask why there are duplicates on the front page anyway, adding the related issues from the parent here as well.

Status: Needs review » Needs work

The last submitted patch, 50: drupal_2149649_50-tests-only.patch, failed testing.

YesCT’s picture

Status: Needs work » Needs review

the tests only failed as expected.

needs review. (we are very close, so look at everything, solution and tests)

jhodgdon’s picture

I just added a related issue:
#2217569: Fields row plugin: Translation is non-uniform for base fields, Field UI fields, links; no way to choose "this row's language"
which has to do with field rendering in views (if instead of using "teasers" as the output, you select the "fields" row plugin and display the Body field for instance). Just pointing it out as people on this issue may be interested in the other one too...

Gábor Hojtsy’s picture

@plach / @vijaycs85 what do you think?

Wim Leers’s picture

Patch looks sane :)

Sweetchuck’s picture

Assigned: Unassigned » Sweetchuck
Issue tags: +Needs reroll

The patch #50 cannot be applied to the latest 8.x any more.
I am going to reroll.

Sweetchuck’s picture

FileSize
7.35 KB

Reroll patch #50

Sweetchuck’s picture

Without the patch I experience the same problem as described in the issue summary.

I added 3 different languages (English, Hungarian, Polish)
I enabled the translation support for node:article on page admin/structure/types/manage/article.
And I enabled the translation support for some of the fields of the article on page admin/config/regional/content-language.
I created an Article with English language.
Translate to Hungarian
Translate to Polish, used the English version as source of the translation.
Both of them are promoted to front page. (Issue 2006606)
When I visit the front page the node title is points to the proper link, but the "read more" link is points to the current interface language version of the given node, even if such translation is not exists.

With the patch every "read more" link points to the proper language variants of the given node.

Sweetchuck’s picture

Issue tags: -Needs reroll
jhodgdon’s picture

Status: Needs review » Reviewed & tested by the community

Thanks Sweetchuck for testing!

So it sounds like the patch now applies and has been manually tested to work.

I looked over the code and tests, and I think the code looks good (all 6 lines or so that changed), and the test changes also make sense.

In #50, there was also a test-only patch, which failed where it was expected to fail (I looked at the test result page, and the test definitely was finding the bug reported on this issue).

Wim in #55 also deemed the patch to be "sane".

The issue summary even reflects the current status of the issue.

So... I think this can be marked RTBC. Great work!

  • Commit 0a8e34c on 8.x by alexpott:
    Issue #2149649 by Gábor Hojtsy, YesCT, Xano, herom, vijaycs85,...
alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed 0a8e34c and pushed to 8.x. Thanks!

Gábor Hojtsy’s picture

Issue tags: -sprint

Great to see this in :) Thanks all!

droplet’s picture

Assigned: Sweetchuck » Unassigned
Status: Fixed » Needs review
FileSize
633 bytes
2.14 KB
1.52 KB

Enhanced tests to catch Node title link [$node->url()] errors.

The last submitted patch, 64: RED-fail-test.patch, failed testing.

alexpott’s picture

Status: Needs review » Fixed

@droplet can you open a new issue to do the enhanced testing - definitely looks like an improvement but it's not as critical as the original work.

droplet’s picture

sun’s picture

Issue tags: -Random fail +Random test failure
YesCT’s picture

Issue summary: View changes
Issue tags: +Needs followup

tagging needs followup per #66

Status: Fixed » Closed (fixed)

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

jhodgdon’s picture

Status: Closed (fixed) » Needs work

I do not think this was fixed. It seems like the title links are still all going to node/1 not fr/node/1 or whatever. This issue was I think repurposed to only be about links. I'm reopening to see if anyone else agrees that it is not actually fixed.

Gábor Hojtsy’s picture

Status: Needs work » Closed (fixed)

@jhodgdon: the scope of this issue was about links in the node entity display. I think you are referring to field links in views not with entity displays? Please reopen if the scope of this issue is not fixed, that is if the title and/or read more links on nodes do not lead to the proper page when displayed as an entity in teaser or full view.

jhodgdon’s picture

Oh sorry, my mistake indeed! I was referring to Views. I'll see if there's an open issue...

Gábor Hojtsy’s picture

No, well, this IS a views page (front page) but it uses entity rendering NOT field rendering. Is that the combination you have issues with?

jhodgdon’s picture

The problem I am seeing is this:

If I make a view of nodes (which is really a view of node translations). I display it using Fields. I put in the Title field, and check the "Link this to the entity".

All of the links go to node/1, not to a translation page.

Gábor Hojtsy’s picture

Yeah all the changes and scope of this patch is/was focusing on rendering the node as an entity (node_links hook changes, NodeView.php fixing, etc). Not as fields. I don't think we have an issue for that. Hopefully that should not be too bad, since the field rendering should also get the field language passed (and even use the right translation based on that?). But it should be a different issue. Happy to help there :)

jhodgdon’s picture

OK, I did a quick test and confirmed that if you use Content/display mode in Views, the links are correct. I think the links being wrong at field level are probably part of #2217569: Fields row plugin: Translation is non-uniform for base fields, Field UI fields, links; no way to choose "this row's language" and I'll make a note there. Thanks for the clarification!