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

  1. Enable the default RRSSB set for the "Basic Page" content type
  2. Visit node/add/page to start creating a new basic page
  3. 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

plessas created an issue. See original summary.

adamps’s picture

Thanks 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.

plessas’s picture

Status: Active » Needs review
StatusFileSize
new608 bytes

I 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)!

adamps’s picture

Thanks, 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:

if ($node->isNew()) {
  // New nodes (in preview) don't yet have a URL.
  array_shift($mapping ['url']);
}

What do you think?

plessas’s picture

StatusFileSize
new543 bytes

I 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!

adamps’s picture

That'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)

plessas’s picture

StatusFileSize
new1.07 KB

Without 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.

adamps’s picture

Good 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 just if ($node). Also can combine the 2 if statements:

// New nodes (in preview) don't yet have a URL.
if ($node && !$node->isNew()) {
  array_unshift($mapping['url'], '[node:url]');
}
plessas’s picture

StatusFileSize
new1.02 KB

Well, I have confirmed that $node is NULL when previewing and RRSSB are rendered as a block. I have updated the patch accordingly.

adamps’s picture

Great. The use statement that was added is no longer needed. If you can fix that then it's ready to commit.

plessas’s picture

StatusFileSize
new767 bytes

You are right about the use statement, I forgot to remove it.

adamps’s picture

Title: New node preview causes 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()" » New node preview causes error
Status: Needs review » Fixed

  • AdamPS committed ec51d22 on 8.x-2.x authored by plessas
    Issue #3246811 by plessas, AdamPS: New node preview causes error
    
adamps’s picture

Great thanks and congratulations on your first commit to Drupal.org

Status: Fixed » Closed (fixed)

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

plessas’s picture

There 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:

if (is_numeric($node)) {
  array_shift($mapping['title']);
}
elseif ($node && !$node->isNew()) {
  array_unshift($mapping['url'], '[node:url]');
}