When a revision exists in a node and the user goes to the revisions tab and views the revision by clicking it's link the contextual links on the node show both the "quick edit" and "edit" options. This creates the odd behavior that, although the user is viewing the text of the revision, when they quick edit or edit the node the text changes to the text of the current version. Also when they click "delete" the delete screen for the node (not the revision) is shown.
Proposed solution
When the user is viewing a revision
- Use "node_revision" as group for contextual links. This results in no longer adding the following three links
- Remove "edit" from the contextual links so that the user does not think they can edit the revision without reverting
- Remove "quick edit" from the contextual links so that the user does not think they can edit the revision in place without reverting
- Remove "delete" from the contextual links so that the user will not delete a node thinking they are deleting the revision
Tested in chrome on mac yosemite
| Comment | File | Size | Author |
|---|---|---|---|
| #115 | interdiff-2362435-108-115.txt | 615 bytes | markdorison |
| #115 | when_viewing_a-2362435-115.patch | 5.54 KB | markdorison |
| #108 | interdiff.txt | 3.2 KB | amateescu |
| #108 | 2362435-108.patch | 5.57 KB | amateescu |
| #106 | interdiff-2362435-102-106.txt | 558 bytes | markdorison |
Comments
Comment #1
tkoleary commentedComment #2
wim leersGreat catch!
Comment #3
nlisgo commentedThe proposed behaviour would be consistent with the behaviour in Drupal 7.
Comment #4
nlisgo commentedThis patch addresses the removal of the Edit and Quick Edit links.
Comment #6
wim leersI think you want to use
isDefaultRevision().Comment #7
tim.plunkettComment #8
Palashvijay4O commentedA test patch .
Comment #10
Alienpruts commentedComment #11
Alienpruts commentedFailed testing because of missing ;
Tested code, looks good. However, no contextual links are shown at all. Is this an acceptable solution?
Comment #12
Alienpruts commentedGoofed up, here is the correct patch.
That will teach me to work on two issues at the same time :)
Comment #14
wim leersI think my request to use
isDefaultRevision()confused you a bit :)We already have an
$entityobject. Since this isNodeViewBuilder(which is responsible for building a render array to view a node), we now that we're dealing withNodeentities.In the code for
Nodeyou see this:which leads us to
NodeInterface, in whose code you see this:And this then leads us to
ContentEntityInterface, whose code looks like this:Conclusion: all
Nodeentities are guaranteed to implementRevisionableInterface.It is
RevisionableInterfacethat requiresisDefaultRevision()to be implemented. Hence that method is available directly on all objects that implementRevisionableInterface, of which theNodeclass is one, and hence allNodeentity objects also have it.In other words, the
$revision = entity_load(…)is unnecessary;$entityalready is of a certain revision.And calling on
ContentEntityBase::isDefaultRevision()is definitely wrong: you can only call methods like that if they're static. Static methods are bound to the class, not objects (instances of the class), and hence cannot access$this.It's much, much simpler, actually :) You can simply call
$entity->isDefaultRevision()— that's it! :)Comment #15
Alienpruts commentedTnx Wim,
wow, didn't thought this far. I have some good OOP knowledge, but it escaped my mind to go look for this specific method.
Will patch this.
In retrospect, do you have any tips for me for 'remembering' to check all methods an object has access to? I think I was misled because my IDE didn't have isDefaultRevision() as an autocomplete, so I did not remember to check all interfaces. Do you know of a technique or something so you can check this?
Tnx,
Comment #16
Alienpruts commentedPatched previous patch, tnx to Wim Leers #14
Comment #17
wim leersTo ensure that an IDE *can* correctly autocomplete, we add
/** @var \namespace\interface $variable_namecomments in the code. This is necessary when typehints are set to a generic interface (likeEntityInterface), which allows implementations of that interface to be passed in… but an implementation is not limited to a single interface, and therefore doesn't know if e.g.RevisionableInterfaceis also implemented.That's the general explanation. Hence the general advice would be: look whether the object you're receiving implements additional interfaces.
However, in this case, such a comment does exist! So it looks like your IDE is kind of broken, because that comment does exist and does have the expected effect for me:
$entity->isautocompletes toisDefaultRevision().Not sure what's wrong in your IDE.
Manually tested the patch. Works correctly :)
Unfortunately, there is one small problem in the patch preventing me from RTBC'ing this. Please fix it and then this is RTBC :)
This use statement is no longer necessary.
Comment #18
Alienpruts commentedTnx Wim Leers, indeed strange that the IDE (Netbeans in this case) is not able to 'autocomplete' these methods. Not that I'm so dependant on that feature, but it is nice just to be able to look at all the methods on any given object. I've noticed some other oddities with Netbeans lately, so I'm going to take a look under the hood, so to speak.
Your patch is coming up :)
Comment #19
Alienpruts commentedHere you go.
Took a bit longer than expected : had to reroll the patch.
One conflict (duh) : the use line was removed for the patch to be able to be applied.
Hope all is wel from here on :)
Comment #20
wim leersPerfect, thanks!
Comment #21
tstoeckler$entity->isDefaultRevision()can returnTRUEeven though$entity->id()will returnFALSE. So it seems wrong to remove the$entity->id()check. I might be missing something...Comment #22
wim leers#21: I thought the same: I thought that
->id()would still be necessary. To prevent contextual links from showing up in previews, right? Turns out contextual links already show up in previews in HEAD. This diff doesn't affect that. To fix that, we need to check for$node->in_preview, but that's out of scope.That's what we get for ever using
if ($entity->id()) {…}in the first place: it makes very little sense…Comment #23
sdelbosc commentedHere is a patch for the entire proposed solution.
Note that though I have not seen any case where id() returns FALSE I have kept the test.
Comment #24
sdelbosc commentedComment #26
wim leers@sdelbosc: is it possible that you're using an amazingly ancient version of Drupal 8? "Quick Edit" module was still called "Edit" in your patch, which happened more than half a year ago, in April: https://www.drupal.org/node/2242711.
Could you reroll against the latest Drupal 8, or shall I do that for you?
Comment #27
wim leersOh, and wait, you're proposing to add "Revert to revision" and "Delete revision" contextual links! That's fine, but that belongs in a new issue. This means that comments #23—#26 should be ignored.
Reuploading #19 which IMHO is still RTBC worthy. Pinging tstoeckler for feedback.
Comment #28
sdelbosc commentedYes, I used 8.x branch and realised the mistake when my patch failed testing.
Regarding the Revert to revision and Delete revision links, I think we should update the description of the issue as it is confusing.
Otherwise, from what I have seen the patch from #19 is fine for me in the sense that I have not found any use case where id() is FALSE (on 8.x branch at least).
By the way, if you could confirm that 8.0.x is the branch I should use it would be great.
Comment #29
wim leersAha, heh :)
Clarified the title.
Yes,
8.0.xis the one you want. And just to make sure: please do open a new issue for what you want to do :)Comment #30
sdelbosc commentedDo you know the issue number of the other issue you are talking about?
The one supposed to show Revert and Delete contextual links on revisions.
Comment #31
wim leers@sdelbosc: there isn't one, please create one :)
Comment #32
sdelbosc commentedSorry misunderstanding on my side. However, when reading the proposed solution in the description of this ticket, it seems to me that adding these 2 links is part of this ticket and not a new one.
Comment #33
wim leers#32: it's not. I already clarified the title in #29.
Comment #34
jibranCan we add some quick test for this?
Comment #35
jibransorry added wrong tag.
Comment #36
sdelbosc commentedFor info. I have created [2389341] according to the previous comments.
@Wim, would be great if you could check that this is what you expected.
Comment #37
tstoecklerIt still seems strange to me to remove the
id()check. Even if it's incorrect, IMO we should fix that in a separate issue including dedicated tests for that.In any case marking needs work due to the "Needs tests" tag.
Comment #38
hampercm commentedWriting tests for this issue...
Comment #39
hampercm commentedHere is what I have so far for the tests. I added the new test code to an existing function in NodeRevisionsTest.php, as that seemed to be the most relevant existing test class. This allowed me to take advantage of some existing test set-up functionality in that class.
In the process of creating these tests, however, I found that I had some concerns with the patch from #27:
1) I agree with @tstoeckler that the
if( $entity->id() )check should be left in. I see no justification for removing it. It seems quite likely that removing it will create problems elsewhere.2) If I'm understanding things correctly, the patch in #27 removes the quickedit, edit, and delete contextual links when viewing revisions by completely disabling the creation of the contextual links "popup menu". This will create problems if other contextual links need to be displayed when viewing a revision, and thus seems like a poor solution.
Interestingly, the patch from the related issue #2389341 removes the quickedit, edit, and delete contextual links (in addition to adding new links for reverting and deleting revisions). My brain is pretty fried at this point, so it's not clear to me exactly how it accomplishes that, but perhaps that patch can be adapted to be a solution for this issue?
Comment #40
hampercm commentedHere is an alternative patch for this issue, derived from the patch by @sdelbosc in related issue #2389341. Instead of completely disabling contextual links for revisions, this patch fixes the issue by giving revisions their own separate contextual links, which are currently empty.
I also updated my test code to account for the return of the contextual links menu for revisions.
Comment #44
tadityar commentedRe-rolled
Comment #46
tadityar commentedIsn't this supposed to be tested against 8.0.x-dev? Or was it correct to test it against 8.0.0-beta2? Please correct me if I'm wrong.
Comment #48
hampercm commentedAfter further examination, I realized that I needed to include a bit more of @sdelbosc's patch in order to prevent the "Quick Edit" link from appearing under certain circumstances. Sorry for the confusion on this.
Comment #49
gippy commentedI applied when_viewing_a-2362435-48.patch using a clean install of D8 and the patch correctly removed all three contextual links when displaying the older revision. Tested with Yosemite and Chrome.
Comment #50
gippy commentedComment #51
wim leersI don't understand why this is necessary. It feels very hacky. Can you please explain it?
Comment #52
hampercm commentedIn response to #51, this code's purpose is to explicitly disable the addition of a "Quick Edit" contextual link. Without this code, the quick edit link will be incorrectly added to the context menu for node revisions in the case where there are other contextual links (for example, those proposed to be added by #2389341: When viewing a revision the Reverted or Deleted links should be available in contextual links). There might be other ways of doing the same thing that would feel less hack-ish. I'm certainly open to ideas.
I originally adapted this code from @sdelbosc's patch for that issue (as mentioned in #40) because it seemed to be a good solution to this issue, without breaking contextual links entirely for revisions.
Looking at the code again, the JS code could be cleaned up quite a bit, to something more like:
Comment #53
alvar0hurtad0Let me help, this is the patch on #48 with #52 fix.
Comment #54
kerby70 commented#53 removes the 3 links and test passed.
Screen shot before on revision page:

Screen shot after on revision page:

Comment #55
kerby70 commentedComment #56
kerby70 commentedComment #57
wim leersThese aren't formatted consistently.
Just "contextual" would be sufficient, the parent class' modules are also enabled automatically (IIRC).
We put the assertion messages on the same line.
Nit: newline after the last method.
Comment #58
wim leersAlso, still not convinced by this approach — sorry.
This is too late in the process.
Also, why do we even need
quickEdit=0? Zero contextual links are defined on that route! AFAICT this also works, and is much, much simpler.Comment #59
disasm commentedLets get the screenshots added to the issue summary above.
Comment #60
sher1 commentedI am at DrupalCon LA. This patch no longer applies. It will need to be re-rolled. I will review the patch and see if I can re-roll it.
Comment #61
sher1 commentedre-saved comment
Comment #62
sher1 commentedI can't see how I would re-roll it, (newbie issues).
Comment #63
wim leersIf this needs a reroll, it needs to be marked as "needs work".
Comment #64
deepakaryan1988Comment #65
deepakaryan1988@Wim @sher1 I have re-rolled #58 . Please check it.
Attaching interdiff also.
Comment #66
martin107 commentedComment #67
googletorp commentedTesting the patch alone, to see if it fails as expected.
Comment #68
timmillwoodRe-rolled the patch
Comment #69
legolasboOnly a review of the code, I haven't looked at the functionality.
renderContextualLinkscould just take the node as an argument to reduce code duplication.Instead of returning the raw response,
renderContextualLinkscould return the json object to reduce code duplication.These should be on one line, not two.
Comment #70
DickJohnson commentedAssigning to myself, working for this on DrupalCon Barcelona.
Comment #71
dawehnerAdded a PR for entity module to generalize that bit: https://github.com/fago/entity/pull/23
Comment #72
wim leers<3
Comment #73
Crell commentedWe ran into a closely related issue with Workbench Moderation a while back. Our solution was here: #2635890: Quick Edit integration. Basically, we disable quick edit entirely when showing any revision other than the latest revision, as doing otherwise leads to unexpected branching and unmanaged weirdness. Dropping a link here for context.
Comment #74
wim leersComment #75
lokapujya#69
1.) Yes, but the input varies: "node:node=" vs . "node_revision::node="
2, 3.) done.
Comment #77
lokapujyaremove leftover parenthesis.
Comment #78
samiullah commentedComment #79
samiullah commented@lokapujya, I am able to reproduce the issue. For the revision when click on contextual menu, Drop down is not reflecting.
Comment #80
samiullah commentedComment #81
lokapujyaHmm, I guess this never worked completely as shown by the missing "Delete" in the screenshots in comment #54.
Comment #82
lokapujyaCan anyone confirm that the delete link should show up. At least, the contextual links probably shouldn't be empty like they do in the #54 screenshot, right?
Comment #84
hampercm commentedRerolled patch from #77.
@lokapujya, the Delete link should not be showing up, as it will delete the entire node rather than the revision that is being viewed. This would most likely be unexpected behavior for users. #2389341: When viewing a revision the Reverted or Deleted links should be available in contextual links is intended to add back a "Delete revision" contextual link.
I've changed the title to match the intent of this issue.
Comment #85
hampercm commentedComment #86
lokapujyaThe contextual links are still empty though. What should happen in this case?
Comment #87
markdorisonNodeRevisionsTestRE: $modules array declaration: "If the line declaring an array spans longer than 80 characters, each element should be broken into its own line."Comment #88
adamzimmermann commentedThe links are hidden for me as intended, but as #86 noted, it now has the odd empty contextual links behavior.
Comment #89
adamzimmermann commentedComment #90
hampercm commentedThe empty contextual links is the result of a separate Drupal Core bug: #2650910: Contextual links button is always rendered even when no links are available (with warm client-side cache) Once that is fixed, the empty contextual links visible in #88 will go away.
Comment #91
markdorisonComment #92
alexpottDiscussed with @catch, @xjm, @dixon, @amateescu, @berdir, @effulgentsia, @timmillwood - we decided to promote this to critical as the user is not editing what they think they are editing when quick editing a revision - this could result in data lose and is certainly unexpected and confusing.
Comment #93
wim leersThe first case has
changedin its metadata, the revision one should too, because revisions can also be edited without creating a new revision.Nit: strange wrapping here.
Nit:
string[]Nit: s/ids/IDs/
Nit: s/Json/JSON/
Nit: s/array()/[]/
Comment #94
hampercm commentedMaking changes from review in #93...
Comment #95
markdorisonSuggestions from #93 implemented as well as some additional array syntax changes for new code. Patch and interdiff attached.
Comment #96
wim leersI'm afraid #95 introduced a new array syntax case:
s/array()/[]/
Comment #97
martin107 commenteda little fix.
Comment #99
deepakaryan1988Comment #100
deepakaryan1988Rerolled it.
Comment #102
markdorisonUpdated array syntax.
Comment #104
xjmComment #105
xjmThis issue is also critical for phase A of the Workflow Initiative.
Comment #106
markdorisonUpdated remaining array syntax. I am having trouble parsing the failing test results.
Comment #107
xjmThe most recent test failure was caused by #2749955: Random fails in UpdatePathTestBase tests so not the result of this patch.
Comment #108
amateescu commentedThere were a few code style issues left, otherwise this patch looks ready to me.
Comment #109
wim leersRTBC++
Comment #110
xjmIn general I prefer that we not reformat arrays like this when changing lines for other reasons, because it makes word diffs unusable. Not going to block a critical on that, though. ;)
I tested this patch manually and confirmed there are no more dangerous edit/delete links on past revisions! Yay!
However, it introduces a different bug. With the patch, the contextual links "friendly pencil" is displayed, but expands to an empty dropdown:

That's a better bug to have, but it is still a bug I think.
Comment #111
markdorison@xjm The issue you are describing is being handled in #2650910: Contextual links button is always rendered even when no links are available (with warm client-side cache).
Comment #112
amateescu commentedBack to RTBC per #111.
Comment #115
markdorisonAttached patch undos reformatting of
$modulesarray as requested by @xjm in #110.Comment #116
amateescu commentedLooks good, thanks @markdorison :)
Comment #117
alexpottI guess the question now is should #2650910: Contextual links button is always rendered even when no links are available (with warm client-side cache) block this. I don't think so but it'd be good to get more opinions on this.
Comment #118
wim leersI vetted the patch at #2650910: Contextual links button is always rendered even when no links are available (with warm client-side cache), see #2650910-23: Contextual links button is always rendered even when no links are available (with warm client-side cache). In short: it's ready, it just needs JS test coverage. I've also written a comprehensive IS.
Comment #119
dawehnertried to understand the patch and updated the change record for that. I hope that makes a bit more sense to more than just me.
Comment #120
xjmAha! Thanks for the issue link.
I think that that bug is less bad than this bug, so I do not think it should block this issue. That bug is a "huh wtf?" but this one is a "huh wtf and lol I deleted my node". :)
Comment #123
xjmCommitted 4668a26 and pushed to 8.2.x and 8.1.x. Thanks!
Comment #124
wim leers#120 Nice summary :D