6

I have a ticketing system where the path aliases are set like ticket/[node ID], e.g. http://example.com/ticket/1234.

I would like to create multiple path aliases for the same node, and be able to access it also as discussion/[node ID], e.g. http://example.com/discussion/1234.

I will be using different node templates basing on the path.

Is there any way to set multiple path aliases for the same node?

3 Answers 3

1

To have a working code example for the routing approach.

First in MYMODULE.routing.yml write:

ticket.view:
  path: '/ticket/{node}'
  defaults:
    _controller: '\Drupal\node\Controller\NodeViewController::view'
  requirements:
    node: \d+
    _entity_access: 'node.view'
discussion.view:
  path: '/discussion/{node}'
  defaults:
    _controller: '\Drupal\node\Controller\NodeViewController::view'
  requirements:
    node: \d+
    _entity_access: 'node.view'

Then in MYMODULE.module you'ld add template suggestions like so:

/**
 * Implements hook_theme_suggestions_HOOK_alter().
 */
function MYMODULE_theme_suggestions_node_alter(array &$suggestions, array $variables) {

  if (\Drupal::routeMatch()->getRouteName() == 'ticket.view') {
    $suggestions[] = 'ticket'; // Would take ticket.html.twig
  }

  if (\Drupal::routeMatch()->getRouteName() == 'discussion.view') {
    $suggestions[] = 'discussion'; // Would take discussion.html.twig
  }

}

Or maybe if all it takes are some different styles simply add a body class depending on the route:

/**
 * Implements hook_preprocess_HOOK().
 */
function MYMODULE_preprocess_html(&$variables) {

  if (\Drupal::routeMatch()->getRouteName() == 'ticket.view') {
    $variables['attributes']['class'][] = 'ticket';
  }

  if (\Drupal::routeMatch()->getRouteName() == 'discussion.view') {
    $variables['attributes']['class'][] = 'discussion';
  }

}

Last but not least check out this brilliant article https://thinkshout.com/blog/2016/07/drupal-8-routing-tricks-for-better-admin-urls/, there are some more route goodies inside you may like.

2

You can set multiple path aliases for one node, this is no problem. If you can't do it with Pathauto, then it's possible with custom code when saving the node.

But in your case it might be more efficient to set up different routes for /ticket/{node} and /discussion/{node}. You can either set a fixed route parameter or use a custom node controller to set a marker, that you can use in theme name suggestion to choose the custom template.

Another solution would be to set up a View with a contextual filter for the node and two displays with different paths. Choose for each a different view mode to get different templates. Technically it's almost the same, but you need no custom module, because Views sets up the routes for you.

2
  • 1
    Or redirects. A ticket system might not need to be indexed, but in general, it is a bad idea to have multiple paths for the same content. Having redirect with route normalizing enabled will force a default path and core will eventually do that as well.
    – Berdir
    Commented Feb 25, 2017 at 17:31
  • @Berdir, good point. I based the answer mainly on the different node templates and assumed both routes would present the node in such a way that they are not duplicates.
    – 4uk4
    Commented Feb 25, 2017 at 17:57
0

Even better approach would be to still use custom routes and set different display modes for each route. With this you will have all the theme support from core with small to zero amount of custom code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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