Problem/Motivation
Previewing a node that does not exist yet causes a WSOD and an error "Drupal\Core\Entity\EntityMalformedException: The "node" entity cannot have a URI as it does not have an ID in Drupal\Core\Entity\EntityBase->toUrl()".
Steps to reproduce
- Enable the default RRSSB set for the "Basic Page" content type
- Visit node/add/page to start creating a new basic page
- Fill in the title and body and click on "Preview" button in order to preview the new page
Proposed resolution
A quick fix could be to unset the url mapping in rrssb_get_buttons() function when in preview mode, since the node doesn't exist yet and the same is true for the url. In this case the buttons are rendered with the url value being [rrssb:url] e.g. https://twitter.com/intent/tweet?text=test&url=[rrssb:url]
$mapping = [
'url' => ['[node:url]', '[current-page:url]'],
'title' => ['[node:title]', '[current-page:title]'],
'image' => $image_tokens,
];
if($node->in_preview) {
unset($mapping['url']);
}
Comments
Comment #2
adamps commentedThanks for the report. Yes your fix makes sense, I would adjust slightly:
- start with a mapping that excludes the url
- add the url except if the node is new (has no ID)
If you can upload a patch then I will review and commit.
Comment #3
plessas commentedI have created a patch checking if the node id exists. However, I 've left the unset approach intact, since when previewing a node and the RRSSP block is used, the $node object is empty and I was not sure if there are any side-effects in this case.
This is my first Drupal patch, so I hope I've done everything right (fingers crossed)!
Comment #4
adamps commentedThanks, congratulations on posting your first patch😃. It would work as you wrote it, though we could maybe tidy it up a bit. I think we could keep the
[current-page:url]and just shift off the[node:url]. Something like this:What do you think?
Comment #5
plessas commentedI am uploading a new patch. I hadn't noticed the existence of the isNew() function in D8/9 (I think in D7 there was the $node->is_new property). The patch follows your approach on keeping [current-page:url], however rendering the icons using the current (preview) page url instead of the placeholder doesn't make much difference in the preview page. Thanks a lot for your guidance!
Comment #6
adamps commentedThat's looking good thanks.
Do we definitely need this line? What can $node be if not NodeInterface?
if ($node instanceof \Drupal\node\NodeInterface)If we do need it, then please change it to this, and add a use statement.
if ($node instanceof NodeInterface)Comment #7
plessas commentedWithout this check, when previewing new content for a content type for which the RRSSP block is enabled from the block layout, the following error occurs: Error:
Call to a member function isNew() on null in rrssb_get_buttons(). It seems that $node is empty in this case.In order to catch this scenario, I have slightly changed the approach, as you can see in the new patch.
Comment #8
adamps commentedGood idea, I like the new patch. If we want to guard against the node being empty then we should use the PHP
empty()function, or even justif ($node). Also can combine the 2 if statements:Comment #9
plessas commentedWell, I have confirmed that $node is NULL when previewing and RRSSB are rendered as a block. I have updated the patch accordingly.
Comment #10
adamps commentedGreat. The use statement that was added is no longer needed. If you can fix that then it's ready to commit.
Comment #11
plessas commentedYou are right about the use statement, I forgot to remove it.
Comment #12
adamps commentedComment #14
adamps commentedGreat thanks and congratulations on your first commit to Drupal.org
Comment #16
plessas commentedThere is one case for which the solution does not work. When the icons are placed as a block in a node page and the user tries to access an older revision, the $node var holds the numeric value of the node id and consequently the isNew() method cannot be applied.
To fix this: