1

I have nodes whose content type is X that I would like to render differently based on the node path. I'd like to use the default view mode for a path alias and a custom view mode for the other path alias. These aliases were created using the Pathauto module; both of them point to the same node.

  • /url/alias1/path => /node/123 (default view mode)
  • /url/alias2/path => /node/123 (custom view mode)

I tried using mymodule.routing.yml to do this, but it does not appear to be picked up by the route system.

mymodule.program:
  path: '/url/alias2/path'
  defaults:
    _controller: '\Drupal\mymodule\Controller\RoutesController::setViewMode'
  requirements:
    _access: 'TRUE'

When I click on the alias with the custom view mode, I get the default view mode. I put a logger statement in the routes controller setViewMode function and it is not reached. This suggests that the routing is not being 'tripped'.

Am I missing something or trying to do something Drupal 8 cannot handle?

I looked at Routing and path aliases but that doesn't quite address my question.

0

3 Answers 3

1

There are many approaches in aliasing and routing, but I think splitting the task between both is the most effective:

Add an internal node route for the second view mode:

mymodule.custom_node:
  path: '/node_custom/{node}'
  defaults:
    _entity_view: 'node.custom_view_mode'
  requirements:
    _access: 'TRUE'

Then change the source path to /node_custom/123 before Pathauto saves the second alias in hook_pathauto_alias_alter().

2
  • At what point does the second alias get saved? What if I already created the pathauto alias? Do I put the hook_pathauto_alias_alter() in the custom module? Jul 20, 2019 at 1:26
  • The hook runs when the aliases are created by pathauto. After you have implemented the hook in a custom module you have to re-create the aliases.
    – 4uk4
    Jul 20, 2019 at 6:39
0

The above approach was too complex for the time crunch so I went back to my first solution which was to create a new content type that contains a field that is an entity reference to the 'original' content type that has the information to be rendered. This made it much easier to have the right view mode, title, alias, menu link, etc. I created a cron job that will periodically check to see if new content of the original content type was created and create a content of the new content type with the entity reference pointing to the original. From there I can create a new menu link and pathauto alias.

0

OK, so you got your node created and added a second alias using Pathauto. Now you can use hook_entity_view_mode_alter() to simply switch the view mode depending on the current URL pattern. And the node will be displayed in a different view mode under this URL.

/**
 * Implements hook_entity_view_mode_alter().
 */
function MYMODULE_entity_view_mode_alter(&$view_mode, Drupal\Core\Entity\EntityInterface $entity, $context) {

  if ($entity->getEntityTypeId() === 'node' && $entity->bundle() === 'page') {

    // Get the current URL and cut in parts you can later check more easily.
    $current_uri = \Drupal::request()->getRequestUri(); // '/url/alias1/path'
    $current_uri = ltrim($current_uri, '/'); // 'url/alias1/path'
    $arg = explode('/', $current_uri); // array

    // Check URL to match a certain pattern, and switch the view mode.
    if ($arg[0] === 'url' && $arg[1] === 'alias2' && $arg[2] === 'path') {
      $view_mode = 'teaser';
    }
  }
}

You could even automate multiple path alias creation using hook_entity_insert() like shown in this answer.

Not the answer you're looking for? Browse other questions tagged or ask your own question.