Problem/Motivation

In order to build a generic revision UI you need a way to upcast a revision ID in the URL to a full entity

Entity module already provides this functionality: https://github.com/fago/entity/blob/8.x-1.x/src/ParamConverter/EntityRev...

On top of that, some generic code might also want to have a route enhancer, similar to the entity one, see https://github.com/fago/entity/blob/8.x-1.x/src/RouteEnhancer/EntityRevi...

This allows to have routing definitions like:

  path: '/node/{node}/revisions/{node_revision}/view'
  options:
     parameters:
       node_revision:
         type: entity_revision:node

so it will be upcasted automatically.

Proposed resolution

Let's port it over.

Remaining tasks

User interface changes

API changes

Data model changes

Comments

dawehner created an issue. See original summary.

dawehner’s picture

Issue summary: View changes
dawehner’s picture

Issue summary: View changes
Status: Active » Needs review
StatusFileSize
new9.32 KB

Status: Needs review » Needs work

The last submitted patch, 3: 2666798-3.patch, failed testing.

dawehner’s picture

Status: Needs work » Needs review
StatusFileSize
new9.35 KB
new1.86 KB

Does this help?

Status: Needs review » Needs work

The last submitted patch, 5: 2666798-5.patch, failed testing.

dawehner’s picture

Status: Needs work » Needs review
StatusFileSize
new9.35 KB
new1.35 KB

Thank you bojanz!

wim leers’s picture

Status: Needs review » Needs work

Looks good, but I'd feel better if somebody with better routing system knowledge would review/RTBC this.

Why not use this for the node revision routes?

  1. +++ b/core/lib/Drupal/Core/ParamConverter/EntityRevisionParamConverter.php
    @@ -0,0 +1,51 @@
    + * Parameter converter for single revisions.
    

    Nit: Shouldn't it be singular revision here?

  2. +++ b/core/tests/Drupal/Tests/Core/ParamConverter/EntityRevisionParamConverterTest.php
    @@ -0,0 +1,89 @@
    +  /**
    +   * The entity manager.
    +   *
    +   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
    +   */
    +  protected $entityTypeManager;
    

    Nit: can be removed, this is never used.

dawehner’s picture

Status: Needs work » Needs review
StatusFileSize
new9.22 KB
new1.28 KB

Thank you for your review!

Why not use this for the node revision routes?

Well, every change there is a potential API break. What if someone replaced the service and extended the existing class? Given that is hard to remove anything. This issue is also NOT about making the life of node easier, but rather to enable contrib and custom modules to not get insane.

Nit: can be removed, this is never used.

Good point

wim leers’s picture

What if someone replaced the service and extended the existing class?

How can we then ever let core use improved APIs?

dawehner’s picture

How can we then ever let core use improved APIs?

For contrib / custom usages there aren't any problems. Node module is a mess, I don't see that much hope there. We can have that discussion in another issue though, this is for sure, but I just fear from a API breakage point of view this could be required to stay around.

bojanz’s picture

The code in general is solid.

The only nitpick I have is that the param converter could have more docs. Look at the Entity param converter:

/**
 * Parameter converter for upcasting entity IDs to full objects.
 *
 * This is useful in cases where the dynamic elements of the path can't be
 * auto-determined; for example, if your path refers to multiple of the same
 * type of entity ("example/{node1}/foo/{node2}") or if the path can act on any
 * entity type ("example/{entity_type}/{entity}/foo").
 *
 * In order to use it you should specify some additional options in your route:
 * @code
 * example.route:
 *   path: foo/{example}
 *   options:
 *     parameters:
 *       example:
 *         type: entity:node
 * @endcode
 *
 * If you want to have the entity type itself dynamic in the url you can
 * specify it like the following:
 * @code
 * example.route:
 *   path: foo/{entity_type}/{example}
 *   options:
 *     parameters:
 *       example:
 *         type: entity:{entity_type}
 * @endcode
 */

That provides a nice example to follow.

dawehner’s picture

StatusFileSize
new1.02 KB
new9.68 KB

Sure, here it is.

berdir’s picture

Status: Needs review » Reviewed & tested by the community

Looks good to me. Agreed on not converting node here. We can still do that later on if we want to and keep the existing class as @deprecated if anyone extends from it or something.

wim leers’s picture

Title: Add a entity revision parameter converter » Add a entity revision parameter converter & route enhancer

+1. But can we file a follow-up to update node.module to use this new parameter converter & route enhancer?

wim leers’s picture

Thanks!

tim.plunkett’s picture

None of this should hold up commit.

  1. +++ b/core/lib/Drupal/Core/ParamConverter/EntityRevisionParamConverter.php
    @@ -0,0 +1,65 @@
    + *   path: foo/{entity_example_revision}
    

    Missing leading slash path: /foo/{entity_example_revision}

  2. +++ b/core/lib/Drupal/Core/ParamConverter/EntityRevisionParamConverter.php
    @@ -0,0 +1,65 @@
    +    list (, $entity_type_id) = explode(':', $definition['type']);
    

    Should probably have , 2 just 'cause

  3. +++ b/core/lib/Drupal/Core/Routing/Enhancer/EntityRevisionRouteEnhancer.php
    @@ -0,0 +1,52 @@
    + * Contains \Drupal\Core\Routing\EntityRevisionRouteEnhancer.
    ...
    +namespace Drupal\Core\Routing\Enhancer;
    ...
    +class EntityRevisionRouteEnhancer implements RouteEnhancerInterface {
    

    Contains doesn't match the namespace. (though aren't we getting rid of that?)

  4. +++ b/core/tests/Drupal/Tests/Core/Enhancer/EntityRevisionRouteEnhancerTest.php
    @@ -0,0 +1,95 @@
    +  public function testAppliesWithNoParameters() {
    ...
    +  public function testAppliesWithNoneRevisionParameters() {
    ...
    +  public function testAppliesWithRevisionParameters() {
    

    I would have put these three in a dataProvider

dawehner’s picture

StatusFileSize
new9.59 KB
new3.89 KB

Good points, let's fix them.

Missing leading slash path: /foo/{entity_example_revision}

Yeah, this happens if you copy from \Drupal\Core\ParamConverter\EntityConverter

Contains doesn't match the namespace. (though aren't we getting rid of that?)

No idea, at which point its fine in core.

amateescu’s picture

Super minor point that can be fixed on commit:

+++ b/core/lib/Drupal/Core/ParamConverter/EntityRevisionParamConverter.php
@@ -0,0 +1,65 @@
+ * "entity_example/{entity_example}/revision/{entity_example_revision}".

For consistency with the code example below, this should have a leading slash as well :)

Otherwise the patch looks great to me as well.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.0-beta1 was released on March 2, 2016, which means new developments and disruptive changes should now be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

catch’s picture

Status: Reviewed & tested by the community » Fixed

Committed/pushed to 8.2.x and cherry-picked to 8.1.x. Thanks! Let's do the follow-up for 8.2.x.

Added review credit post-commit.

  • catch committed 1993729 on 8.2.x
    Issue #2666798 by dawehner: Add an entity revision parameter converter...

  • catch committed e56d13b on 8.1.x
    Issue #2666798 by dawehner: Add an entity revision parameter converter...
berdir’s picture

Uh, I think we missed a tiny little detail here? :)

Actually registering this new service in core.services.yml. Found while trying to make https://github.com/fago/entity/pull/38 work.

Also, looking at this again, not sure why this was added in the Routing namespace and not in Entity/Routing, like the standard entity routing enhancer?

berdir’s picture

Status: Fixed » Closed (fixed)

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