A custom parameter converter would probably be the best solution.
It's quite easy to implement; +
symbols tend to be quirky in URLs so this example uses commas instead:
MODULE/src/ParamConverter/NodesConverter.php
namespace Drupal\MODULE\ParamConverter;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Symfony\Component\Routing\Route;
use Drupal\Core\ParamConverter\ParamConverterInterface;
class NodesConverter implements ParamConverterInterface {
protected $entityTypeManager;
public function __construct(EntityTypeManagerInterface $entity_type_manager) {
$this->entityTypeManager = $entity_type_manager;
}
public function convert($value, $definition, $name, array $defaults) {
// Add whatever extra validation you feel is necessary here
$nids = explode(',', $value);
if (!empty($nids)) {
return $this->entityTypeManager->getStorage('node')
->loadMultiple($nids);
}
}
public function applies($definition, $name, Route $route) {
return !empty($definition['type']) && $definition['type'] == 'nodes';
}
}
MODULE/MODULE.services.yml:
services:
module_nodes:
class: Drupal\MODULE\ParamConverter\NodesConverter
arguments: ['@entity_type.manager']
tags:
- { name: paramconverter }
MODULE/MODULE.routing.yml:
custom.custom_nodes:
path: '/custom/{nodes}'
defaults:
_form: '\Drupal\custom\Form\CustomForm'
_title_callback: '\Drupal\custom\Form\CustomForm::titleCallback'
nodes: '[\d\,]+'
requirements:
_access: 'TRUE'
options:
parameters:
nodes:
type: 'nodes'
The regex for the route could probably be improved, the param could be made optional, etc; other than that it should work. The controller for the route at /custom/1,2,3 will receive an array of loaded nodes for the same IDs in the $nodes
argument (or an empty/smaller array if none/only some were found).