Skip to content

Instantly share code, notes, and snippets.

@vijaycs85
Last active December 14, 2015 00:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vijaycs85/4997345 to your computer and use it in GitHub Desktop.
Save vijaycs85/4997345 to your computer and use it in GitHub Desktop.
<h2>Wildcard paths</h2>
<h3>Drupal 7</h3>
in modules/book/book.module:
<?php
function book_menu() {
$items['book/export/%/%'] = array(
'page callback' => 'book_export',
'page arguments' => array(2, 3),
'access arguments' => array('access printer-friendly version'),
'type' => MENU_CALLBACK,
'file' => 'book.pages.inc',
);
$items['node/%node/outline'] = array(
'title' => 'Outline',
'page callback' => 'book_outline',
'page arguments' => array(1),
'access callback' => '_book_outline_access',
'access arguments' => array(1),
'type' => MENU_LOCAL_TASK,
'weight' => 2,
'file' => 'book.pages.inc',
);
...
return $items;
}
?>
<h3>Drupal 8</h3>
in modules/book/book.routing.yml:
<code>
book_export:
pattern: '/book/export/{type}/{node}'
defaults:
# What's being returned is the entire response (not HTML, or even if HTML, we don't want additional blocks around it), so use _controller instead of _content.
_controller: '\Drupal\book\BookController::export'
requirements:
_permission: 'access printer-friendly version'
book_node_outline:
pattern: '/node/{node}/outline'
defaults:
_controller: '\Drupal\book\BookController::outline'
requirements:
# Indicates that the book outline access access system should be invoked.
_book_outline_access: TRUE
</code>
If you want to handle access logic on the controller, as you might need some values of the URL use '_access: TRUE' and throw exceptions on the controller
function.
If you want to define custom wildcard, refer converters section
<h3>converters </h3>
<strong>It is not recommended to define customer converters in D8 as most of them will be covered as entity or configentity. </strong>
There are two steps to create a custom converter (apart from entity and configentity)
<ol>
<li>Implement ParamConverterInterface</li>
<li>Register converter in a bundle</li>
</ol>
<h4>1. Implement ParamConverterInterface</h4>
<code>
File: core/modules/views/views_ui/lib/Drupal/views_ui/ParamConverter/ViewUIConverter.php
<?php
/**
* @file
* Contains \Drupal\views_ui\ParamConverter\ViewUIConverter.
*/
namespace Drupal\views_ui\ParamConverter;
use Symfony\Component\Routing\Route;
use Drupal\Core\ParamConverter\ParamConverterInterface;
use Drupal\user\TempStoreFactory;
use Drupal\views\ViewStorageInterface;
use Drupal\views_ui\ViewUI;
/**
* Provides upcasting for a view entity to be used in the Views UI.
*/
class ViewUIConverter implements ParamConverterInterface {
/**
* Stores the tempstore factory.
*
* @var \Drupal\user\TempStoreFactory
*/
protected $tempStoreFactory;
/**
* Constructs a new ViewUIConverter.
*
* @param \Drupal\user\TempStoreFactory $temp_store_factory
* The factory for the temp store object.
*/
public function __construct(TempStoreFactory $temp_store_factory) {
$this->tempStoreFactory = $temp_store_factory;
}
/**
* Tries to upcast every view entity to a decorated ViewUI object.
*
* The key refers to the portion of the route that is a view entity that
* should be prepared for the Views UI. If there is a non-null value, it will
* be used as the collection of a temp store object used for loading.
*
* Example:
*
* pattern: '/some/{view}/and/{foo}/and/{bar}'
* options:
* converters:
* foo: 'view'
* tempstore:
* view: 'views'
* foo: NULL
*
* The values for {view} and {foo} will be converted to view entities prepared
* for the Views UI, with {view} being loaded from the views temp store, but
* it will not touch the value for {bar}.
*
* Note: This requires that the placeholder either be named {view}, or that a
* converter is specified as done above for {foo}.
*
* It will still process variables which are marked as converted. It will mark
* any variable it processes as converted.
*
* @param array &$variables
* Array of values to convert to their corresponding objects, if applicable.
* @param \Symfony\Component\Routing\Route $route
* The route object.
* @param array &$converted
* Array collecting the names of all variables which have been
* altered by a converter.
*/
public function process(array &$variables, Route $route, array &$converted) {
// If nothing was specified to convert, return.
$options = $route->getOptions();
if (!isset($options['tempstore'])) {
return;
}
foreach ($options['tempstore'] as $name => $collection) {
// Only convert if the variable is a view.
if ($variables[$name] instanceof ViewStorageInterface) {
// Get the temp store for this variable if it needs one.
// Attempt to load the view from the temp store, synchronize its
// status with the existing view, and store the lock metadata.
if ($collection && ($temp_store = $this->tempStoreFactory->get($collection)) && ($view = $temp_store->get($variables[$name]->id()))) {
if ($variables[$name]->status()) {
$view->enable();
}
else {
$view->disable();
}
$view->locked = $temp_store->getMetadata($variables[$name]->id());
}
// Otherwise, decorate the existing view for use in the UI.
else {
$view = new ViewUI($variables[$name]);
}
// Store the new view and mark this variable as converted.
$variables[$name] = $view;
$converted[] = $name;
}
}
}
}
?>
</code>
<h4>2. Register converter in a bundle</h4>
<code>
file: core/modules/views/views_ui/lib/Drupal/views_ui/ViewsUiBundle.php
<?php
/**
* @file
* Contains \Drupal\views_ui\ViewsBundle.
*/
namespace Drupal\views_ui;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\Reference;
/**
* Views UI dependency injection container.
*/
class ViewsUiBundle extends Bundle {
/**
* Overrides \Symfony\Component\HttpKernel\Bundle\Bundle::build().
*/
public function build(ContainerBuilder $container) {
$container->register('paramconverter.views_ui', 'Drupal\views_ui\ParamConverter\ViewUIConverter')
->addArgument(new Reference('user.tempstore'))
->addTag('paramconverter');
}
}
?>
</code>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment