Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
It is currently impossible to translate a content entity using the Content Translation module that does not provide a canonical
link template.
That is because content_translation_page_attachments()
, which puts some links in the HTML head for accessibility, does not check for a link template before generating a URL to it.
Proposed resolution
Add a check for $entity->hasLinkTemplate('canonical')
.
Remaining tasks
User interface changes
API changes
Comment | File | Size | Author |
---|---|---|---|
#30 | content-translation-canonical-2479377-30-interdiff.txt | 4.59 KB | dpi |
#30 | content-translation-canonical-2479377-30.patch | 7.26 KB | dpi |
Comments
Comment #1
tstoecklerHere we go. I added
canonical
explicitly as an argument tourlInfo()
(even though it's optional), to make it clear for what this check is needed.Comment #2
tstoecklerAs adding a test for this would require a completely new entity type, of which we already have ~ a dozen, I hope that's necessary. It's totally doable, it would just be more effort (both in terms of actually writing the code but also in terms of maintenance) than the test coverage is worth, in my opinion.
Comment #3
tstoecklerThis is related to #2449457: inconsistent checks in content_translation. People using the
content_translation_ui_skip
will hit this problem when providing e.g. an edit form for their entity (if they don't add acanonical
link template).Comment #4
mgiffordRe-uploading for the bots.
Comment #6
edurenye CreditAttribution: edurenye at MD Systems GmbH commented'canonical' is the default value, no need to add it, also I suggest to change it to toUrl() as urlInfo() is deprecated.
So I'm providing a patch with this done.
This error breaks some contrib modules like courier and all based on it.
Comment #8
andypostreroll for current 8.2.x
Comment #9
mglamanThis is affecting Drupal Commerce where entities do not have canonical routes #2826693: Content translation breaks the promotion forms.
Comment #10
hitfactory CreditAttribution: hitfactory commentedAlso affects Entityqueue which recently removed its canonical link.
Subqueues should not have a canonical link in order for them to be exportable through REST
Confirming patch in #8 prevents an error from being thrown.
Comment #11
jespermb CreditAttribution: jespermb at Adapt commentedI can confirm that the issue with EntityQueues is fixed with the patch in #8.
Comment #12
amateescu CreditAttribution: amateescu as a volunteer commentedI think it's better to pass 'canonical' as an explicit parameter like @tstoeckler did in the initial patch, it makes it easier to understand the
hasLinkTemplate()
check above.Comment #13
Rajab Natshah CreditAttribution: Rajab Natshah at Vardot commentedTesting ....
Comment #14
lluvigneI confirm that patch in #8 fixed the problems here. I dont know if it's better or not to pass 'canonical' as parameter since toUrl() method have 'canonical' as default value and seems like its redundant. So, the patch in #8 looks fine to me.
Comment #15
Rajab Natshah CreditAttribution: Rajab Natshah at Vardot commentedPatch in #8 fixed the issue.
Comment #16
meramo CreditAttribution: meramo at Bright Solutions GmbH commentedI confirm. The issue is fixed now with the latest patch
Comment #17
dpiAdded test coverage for link tags.
Restored the explicit rel which was removed in #6, I agree with #1 it should remain. Other than that this new patch is exclusively new tests:
\Drupal\Tests\content_translation\Functional\ContentTranslationLinkTagTest::testCanonicalAlternateTagsMissing
.\Drupal\node\Tests\NodeTranslationUITest::doTestAlternateHreflangLinks
. The new test found in\Drupal\Tests\content_translation\Functional\ContentTranslationLinkTagTest::testCanonicalAlternateTags
uses the generic entity test entities.Comment #18
dpiTests only
Comment #21
andypostqueued retests, I think patch should go into 8.4 first and then backported to 8.3 & 8.2
Comment #23
dpiFixed PHP syntax issue. Apparently I was using a PHP 7 only feature without knowing it.
Interdiff with #17
Comment #24
tstoecklerThe code itself looks great. The test is also very awesome, very very thorough and you get extra credit for not using nodes. I think this is really close. I just have a couple minor notes for the test. Most of them are pretty minor, though, so feel free to ignore them, just sending back to "needs work" once, I promise I'll RTBC the next one ;-)
Should be
string[]
Super minor but would it make sense conceptually to move this into
setupLanguages()
?This seems a bit unnecessarily complex to first add the default langcode and then remove it for that again when using it here. It's only used in other place so maybe we could just add the default there?
That would also to statically define the list of langcodes with the variable declaration, which is nice IMO.
Yay, this is awesome. This is exactly how tests should be written IMO: making sure that the conditions for them making sense are met. Thank you!!!
Again kind of unnecessary IMO to first iterate over the langcodes and set the languag on the URL and then fetch the langcode again a couple lines below.
We could also just iterate over the langcode directly and then clone and set the language in that foreach. (Seems the
setAbsolute()
could be moved to$url_base
, right?)Comment #25
dpiThe test only patch in #23 should not have passed. During cleanup I removed the a permission, which caused the assert-missing to erroneously pass on an access denied page. Fixed in this patch by adding correct permission, and checking HTTP response code.
Thanks for the review @tstoeckler!
Done
Done
Considering the variable name could be considered to be all languages on the site I thought it made sense. Taken feedback into account, changed it to be added languages only.
I considered adding keys to $urls. The langcodes were already in the objects, keeping it functional.
Made the change anyhow.
Thanks!
Done
Keep in mind I am iterating over $urls twice, to get a multidimensional test. (Nested
foreach ($urls as $url) {
), so I need to set the URLs beforehand. Otherwise it gets messy having to create URLs 9 times, instead of 3. ...I could have misinterpreted this comment.Interdiff is vs #23
This test only patch should fail.
Comment #26
tstoecklerAwesome, looks absolutely beautiful now. Thank you a lot and for dealing with my annoying nitpicks.
Nice catch! Absolutely makes sense.
That's pretty smart. Thanks for explaining that in IRC. Learned something new today!
Comment #28
dpiGreat!
Testbot looks good.
Comment #29
alexpottRebuilding the container after attaching services to the test is a bit dangerous - if the rebuild changed these services this wouldn't work. Best thing here is to not attach the services to protected class properties at all.
Imho these methods should be be inlined into ::setUp()... it's a level of indirection that doesn't help test understandability.
Great to see complete testing of the problem space.
Comment #30
dpiAddressed feedback from #29
No problem, these were remnants of abstractions originating from its sister web tests extending
\Drupal\content_translation\Tests\ContentTranslationTestBase
.Interdiff with #25
Comment #31
andypostfeedback addressed, should be ported to 8.3
Comment #32
alexpottCommitted and pushed cd8293e to 8.4.x and 94389e7 to 8.3.x. Thanks!
As this is a bug fix and makes n o BC implicating changes backporting to 8.3.x immediately.