Problem/Motivation

The "Preview" functionality does not work on forward revisions. The following error gets thrown:

Uncaught PHP Exception Symfony\\Component\\Routing\\Exception\\InvalidParameterException: "Parameter "node_revision" for route "entity.node.revision" must match "[^/]++" ("" given) to generate a corresponding URL." at .../docroot/core/lib/Drupal/Core/Routing/UrlGenerator.php line 199, referer: http://localhost/node/5/edit

Steps to Reproduce

While this error applies to any module that creates forward revisions, it was noticed in Workbench Moderation and for convenience I will write steps using that module.

Here are steps to reproduce using Workbench Moderation:

  1. Install and enable Workbench Moderation (tag 8.x-1.0-beta1 OR branch 8.x-1.x)
  2. Make a content type moderated, with all moderation states checked, and default moderation state as "Draft"
  3. Create a node for that type and click "Save and Create New Draft"
  4. Edit it and click "Save and Create New Draft"
  5. Edit it again and click "Preview"
  6. You will see the error described above

You can also create this error after publishing the node, creating a forward revision, and then previewing the forward revision.

Recommended Solution

Remove the generation of HTML head links in the NodePreviewController.

Comments

snufkin created an issue. See original summary.

josephdpurcell’s picture

Assigned: Unassigned » josephdpurcell
Priority: Normal » Major
Issue summary: View changes
Status: Active » Needs work

I can reproduce this issue. Updating the description with steps to reproduce. Also setting to Major.

josephdpurcell’s picture

Issue summary: View changes

I've confirmed this is also an issue with the latest code, 8.x-1.x branch.

josephdpurcell’s picture

Project: Workbench Moderation » Drupal core
Version: 8.x-1.x-dev » 8.1.x-dev
Component: Code » entity system
Assigned: josephdpurcell » Unassigned
Issue summary: View changes

After investigation, it appears the error is due to core not handling previews for forward revisions. Updating the description to clarify what is happening and moving to core.

I have added a recommended solution to remove the generation of HTML meta information on the preview page. It is a straightforward solution with low impact: the HTML meta information is likely superfluous given the previewed content does not yet exist.

josephdpurcell’s picture

Title: Preview after state transition throws an error » Preview on forward revisions throws an error

Updating title to be more relevant. And pointing to relevant code:

Here is the method that is setting the "node_revision" URL parameter to null: Drupal\Core\Entity\Entity::urlRouteParameters($rel). The relevant lines are:

314     if ($rel === 'revision') {
315       $uri_route_parameters[$this->getEntityTypeId() . '_revision'] = $this->getRevisionId();
316     }

Since the entity doesn't yet exist, $this->getRevisionId() returns null, and since the "entity.node.revision" route does not allow the "node_revision" path segment to be null, the route generation fails.

larowlan’s picture

Status: Needs work » Needs review
Issue tags: +Needs tests
StatusFileSize
new1.82 KB

Fix attached

Status: Needs review » Needs work

The last submitted patch, 6: 2684213-node-forward-revision-preview.patch, failed testing.

jibran’s picture

Title: Preview on forward revisions throws an error » Preview on forward node revisions throws an error
shell_cm’s picture

Issue tags: +neworleans2016

I am looking at this issue to replicate.

shell_cm’s picture

I am unable to reproduce this using 8.2x drupal and 8.x-1.0+2-dev version of workbench moderation. Very possible I'm missing something...?

rooby’s picture

I have this problem on Drupal 8.1.1 and Workbench Moderation 8.x-1.0 and the patch in #6 seems to fix it.

amateescu’s picture

Component: entity system » node system
Status: Needs work » Needs review
Issue tags: -Needs tests +Workflow Initiative, +DevDaysMilan
StatusFileSize
new1.17 KB
new2.28 KB

Discussed this issue with @dawehner and we agreed that outputting link templates when previewing a node doesn't make any sense, so we should simply remove that code.

Also added a test for this. Since we can not get in this situation through the current core UI, the test just uses API calls.

The last submitted patch, 12: 2684213-12-test-only.patch, failed testing.

dawehner’s picture

+++ b/core/modules/node/src/Tests/PagePreviewTest.php
@@ -296,6 +296,18 @@ function testPagePreviewWithRevisions() {
+    // Check that previewing a forward revision of a node works. This can not be
+    // accomplished through the UI so we have to use API calls.
+    $this->drupalPostForm(NULL, [], t('Save'));
+    $node = $this->drupalGetNodeByTitle($edit[$title_key]);
+    $node->setNewRevision(TRUE);
+    $node->isDefaultRevision(FALSE);
+
+    /** @var \Drupal\Core\Controller\ControllerResolverInterface $controller_resolver */
+    $controller_resolver = \Drupal::service('controller_resolver');
+    $node_preview_controller = $controller_resolver->getControllerFromDefinition('\Drupal\node\Controller\NodePreviewController::view');
+    $node_preview_controller($node, 'default');

Can you please create a dedicated kernel test? We want to get rid of executing php code in our tests.

amateescu’s picture

@dawehner, the reason I kept the test there even if it's doing only API calls is that at some point we'll be able to test this in the UI, for example when #2725533: Add experimental content_moderation module lands.

How about I add a @todo to change the code to use the UI when we're able to create forward revisions in core?

dawehner’s picture

+++ b/core/modules/node/src/Tests/PagePreviewTest.php
@@ -296,6 +296,18 @@ function testPagePreviewWithRevisions() {
+    /** @var \Drupal\Core\Controller\ControllerResolverInterface $controller_resolver */
+    $controller_resolver = \Drupal::service('controller_resolver');
+    $node_preview_controller = $controller_resolver->getControllerFromDefinition('\Drupal\node\Controller\NodePreviewController::view');
+    $node_preview_controller($node, 'default');

This otherwise trows an exception. Let's use a try catch + $this->fail()

amateescu’s picture

StatusFileSize
new2.55 KB
new1.23 KB

Improved the comments in the test a bit and added the @todo.

amateescu’s picture

This otherwise trows an exception. Let's use a try catch + $this->fail()

Discussed this on IRC but I'll post here for everyone else: the try / catch pattern is for cases when we expect to get an exception, which is not the case here.

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

You are right. Thank you @amateescu

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed cd87bb1 and pushed to 8.1.x and 8.2.x. Thanks!

  • alexpott committed c5bfca6 on 8.2.x
    Issue #2684213 by amateescu, larowlan, josephdpurcell, dawehner: Preview...

  • alexpott committed cd87bb1 on 8.1.x
    Issue #2684213 by amateescu, larowlan, josephdpurcell, dawehner: Preview...
tstoeckler’s picture

tstoeckler’s picture

Status: Fixed » Closed (fixed)

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