Issue #2138665 by dawehner: Allow to specific route parameters to be defined via the views UI.

8.0.x
Nathaniel Catchpole 2014-01-06 11:32:45 +00:00
parent c17906e3f9
commit 075521d0b2
2 changed files with 49 additions and 1 deletions

View File

@ -145,6 +145,8 @@ abstract class PathPluginBase extends DisplayPluginBase implements DisplayRouter
$argument_ids = array_keys($view_arguments);
$total_arguments = count($argument_ids);
$argument_map = array();
// Replace arguments in the views UI (defined via %) with parameters in
// routes (defined via {}). As a name for the parameter use arg_$key, so
// it can be pulled in the views controller from the request.
@ -155,6 +157,13 @@ abstract class PathPluginBase extends DisplayPluginBase implements DisplayRouter
$arg_id = 'arg_' . $argument_ids[$arg_counter++];
$bits[$pos] = '{' . $arg_id . '}';
}
elseif (strpos($bit, '%') === 0) {
// Use the name defined in the path.
$parameter_name = substr($bit, 1);
$arg_id = 'arg_' . $argument_ids[$arg_counter++];
$argument_map[$arg_id] = $parameter_name;
$bits[$pos] = '{' . $parameter_name . '}';
}
}
// Add missing arguments not defined in the path, but added as handler.
@ -190,6 +199,9 @@ abstract class PathPluginBase extends DisplayPluginBase implements DisplayRouter
// particular important for altering routes.
$route->setOption('_access_mode', 'ANY');
// Set the argument map, in order to support named parameters.
$route->setDefault('_view_argument_map', $argument_map);
return $route;
}
@ -445,7 +457,7 @@ abstract class PathPluginBase extends DisplayPluginBase implements DisplayRouter
$form['path'] = array(
'#type' => 'textfield',
'#title' => t('Path'),
'#description' => t('This view will be displayed by visiting this path on your site. You may use "%" in your URL to represent values that will be used for contextual filters: For example, "node/%/feed".'),
'#description' => t('This view will be displayed by visiting this path on your site. You may use "%" in your URL to represent values that will be used for contextual filters: For example, "node/%/feed". If needed you can even specify named route parameters like taxonomy/term/%taxonomy_term'),
'#default_value' => $this->getOption('path'),
'#field_prefix' => '<span dir="ltr">' . url(NULL, array('absolute' => TRUE)),
'#field_suffix' => '</span>&lrm;',

View File

@ -179,6 +179,42 @@ class PathPluginBaseTest extends UnitTestCase {
$this->assertSame($collection->get('test_route_2'), $route_2);
}
/**
* Tests the collectRoutes method with a path containing named parameters.
*
* @see \Drupal\views\Plugin\views\display\PathPluginBase::collectRoutes()
*/
public function testCollectRoutesWithNamedParameters() {
/** @var \Drupal\views\ViewExecutable|\PHPUnit_Framework_MockObject_MockObject $view */
list($view) = $this->setupViewExecutableAccessPlugin();
$view->expects($this->once())
->method('initHandlers');
$view->argument = array();
$view->argument['nid'] = $this->getMockBuilder('Drupal\views\Plugin\views\argument\ArgumentPluginBase')
->disableOriginalConstructor()
->getMock();
$display = array();
$display['display_plugin'] = 'page';
$display['id'] = 'page_1';
$display['display_options'] = array(
'path' => 'test_route/%node/example',
);
$this->pathPlugin->initDisplay($view, $display);
$collection = new RouteCollection();
$result = $this->pathPlugin->collectRoutes($collection);
$this->assertEquals(array('test_id.page_1' => 'view.test_id.page_1'), $result);
$route = $collection->get('view.test_id.page_1');
$this->assertTrue($route instanceof Route);
$this->assertEquals('/test_route/{node}/example', $route->getPath());
$this->assertEquals('test_id', $route->getDefault('view_id'));
$this->assertEquals('page_1', $route->getDefault('display_id'));
$this->assertEquals(array('arg_nid' => 'node'), $route->getDefault('_view_argument_map'));
}
/**
* Tests alter routes with parameters in the overriding route.
*/