1

I have nodes in Drupal for News Articles that generates this automatic URL alias.

screenshot

I also have a view for News nodes.

screenshot

This is the data.

screenshot

The problem is that I can't use Content: Path (url) or Content: Path (Path) as contextual filter.

sync/newslist/1234, where 1234 is node ID, works. I would like to pass the path or the URL to the contextual filter, so that sync/newslist/world-first-chart-alerts-non-artists will return that node.

1
  • 2
    This is not a contextual filter issue. The problem is you never reach the View via the path alias because it doesn't match. You could write your own path processor for the partial match or try a contrib module like drupal.org/project/subpathauto
    – 4uk4
    Jun 1, 2022 at 7:13

1 Answer 1

4

You can for example create a custom ViewsArgumentValidator and transform the given alias to the Node ID.

<?php

namespace Drupal\my_module\Plugin\views\argument_validator;

use Drupal\path_alias\AliasManagerInterface;
use Drupal\views\Plugin\views\argument_validator\ArgumentValidatorPluginBase;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Validates whether an alias is a valid node alias and transform it to the nid.
 *
 * @ViewsArgumentValidator(
 *   id = "node_alias",
 *   title = @Translation("Node ID by alias")
 * )
 */
class NodeAlias extends ArgumentValidatorPluginBase {

  /**
   * The alias manager.
   *
   * @var \Drupal\path_alias\AliasManagerInterface
   */
  protected $aliasManager;

  /**
   * {@inheritdoc}
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, AliasManagerInterface $alias_manager) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->aliasManager = $alias_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('path_alias.manager'),
    );
  }

  /**
   * {@inheritdoc}
   */
  public function validateArgument($argument) {
    // Prepend slash.
    $argument = '/' . ltrim($argument, '/');
    $path = $this->aliasManager->getPathByAlias($argument);

    if (preg_match('/node\/(\d+)/', $path, $matches)) {
      $this->argument->argument = $matches[1];
      return TRUE;
    }
    return FALSE;
  }

}

In the validateArgument function we are checking if an internal path for a node can be found with that alias and transform the given argument to the corresponding Node ID.

Add this file named NodeAlias.php to you custom module in src/Plugin/views/argument_validator directory and clear the cache.

After that, you can use the Content: Nid contextual filter and select in the "When the filter value is in the URL or a default is provided" section the new Validator Node ID by alias.

enter image description here

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.