मैं किसी अन्य मॉड्यूल द्वारा परिभाषित मार्ग को कैसे बदल सकता हूं?


14

दूसरे शब्दों में, Drupl 8 hook_menu_alter () के बराबर क्या है ?

Drupal 8 अभी भी hook_menu () का उपयोग करता है , लेकिन जो मैं देख सकता हूं, उसके लिए दी गई जानकारी हुक से अलग है Drupal 7 में हुक क्या लौटा है। उदाहरण के लिए, user_menu () में उपयोगकर्ता के लिए दी गई परिभाषा निम्नलिखित है।

  $items['user'] = array(
    'title' => 'User account',
    'title callback' => 'user_menu_title',
    'weight' => -10,
    'route_name' => 'user_page',
    'menu_name' => 'account',
  );

User_rout.yml फ़ाइल में प्रविष्टि के लिए मार्ग_नाम संपत्ति लिंक ।

user_page:
  pattern: '/user'
  defaults:
    _content: '\Drupal\user\Controller\UserController::userPage'
  requirements:
    _access: 'TRUE'

यह सिम्फनी के साथ किए गए कार्य से अलग है, और यह मुझे भ्रमित करता है कि एक मॉड्यूल दूसरे उपयोगकर्ता से परिभाषित मार्ग को कैसे बदल सकता है।

एकमात्र फ़ंक्शन जो अभी भी इनवॉइस कर रहा hook_menu_alter()है menu_router_build () है , लेकिन उस फ़ंक्शन में अभी भी कोड है जिसे अपडेट करने की आवश्यकता है, क्योंकि यह अभी भी पदावनत का उपयोग कर रहा है drupal_alter()

  // Alter the menu as defined in modules, keys are like user/%user.
  drupal_alter('menu', $callbacks);
  foreach ($callbacks as $path => $router_item) {
    // If the menu item is a default local task and incorrectly references a
    // route, remove it.
    // @todo This may be removed later depending on the outcome of
    // http://drupal.org/node/1889790
    if (isset($router_item['type']) && $router_item['type'] == MENU_DEFAULT_LOCAL_TASK) {
      unset($callbacks[$path]['route_name']);
    }
    // If the menu item references a route, normalize the route information
    // into the old structure. Note that routes are keyed by name, not path,
    // so the path of the route takes precedence.
    if (isset($router_item['route_name'])) {
      $router_item['page callback'] = 'USES_ROUTE';
      $router_item['access callback'] = TRUE;
      $new_path = _menu_router_translate_route($router_item['route_name']);

      unset($callbacks[$path]);
      $callbacks[$new_path] = $router_item;
    }
  }

जवाबों:


6

मौजूदा मार्गों को बदलना और गतिशील लोगों के आधार पर नए मार्गों को जोड़ना देखें ; यह मेरे लिए खोज मॉड्यूल द्वारा नियंत्रित / खोज को हटाने के लिए अच्छी तरह से काम करता है। मेरे मामले में, मैंने निम्नलिखित कोड का उपयोग किया।

<?php
/**
 * @file
 * Contains \Drupal\ua_sc_module\Routing\SearchAlterRouteSubscriber.
 */

namespace Drupal\ua_sc_module\Routing;

use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;

/**
 * Listens to the dynamic route events.
 */
class SearchAlterRouteSubscriber extends RouteSubscriberBase {

  /**
   * {@inheritdoc}
   */
  public function alterRoutes(RouteCollection $collection) {
    // Remove the /search route.
    $collection->remove('search.view');
  }

}

12

मौजूदा रूटिंग आइटम को ओवरराइड करने की अनुमति दें

यदि आप किसी रूट से जुड़ी जानकारी को बदलना चाहते हैं, तो मेनू नहीं, जैसे कि वास्तविक उपयोग किया गया नियंत्रक, या आवश्यकताएं (अनुमति / भूमिका आदि) आप Drupal द्वारा प्रदान की गई घटना का उपयोग कर सकते हैं:

  <?php

  use Drupal\Core\Routing\RouteBuildEvent;
  use Drupal\Core\Routing\RoutingEvents;
  use Symfony\Component\EventDispatcher\EventSubscriberInterface;

  class RouteSubscriber implements EventSubscriberInterface {

   /**
    * {@inheritdoc}
    */
   public static function getSubscribedEvents() {
      $events[RoutingEvents::ALTER] = 'alterRoutes';
     return $events;
   }

  /**
   * Alters existing routes.
   *
   * @param \Drupal\Core\Routing\RouteBuildEvent $event
   *   The route building event.
   */
  public function alterRoutes(RouteBuildEvent $event) {
    // Fetch the collection which can be altered.
    $collection = $event->getRouteCollection();
    // The event is fired multiple times so ensure that the user_page route
    // is available.
    if ($route = $collection->get('user_page')) {
      // As example add a new requirement.
      $route->setRequirement('_role', 'anonymous');
    }
  }

  }

इसके अतिरिक्त आपको इस वर्ग के लिए 'event_subscriber' टैग के साथ एक सेवा पंजीकृत करनी होगी।



7

जब से मैंने यह सवाल पूछा, ड्रुपल 8 कोर बदल गया, और मार्गों के बारे में कुछ मुद्दे तय किए गए हैं।

hook_menu()Drupal 8 से अब उपयोग नहीं किया जाता है; एक मॉड्यूल का उपयोग करने वाले मार्गों को .rout.yml फ़ाइल (जैसे user.rout.yml ) में परिभाषित किया गया है । अल्टर हुक अभी भी उपयोग किए जाते हैं, लेकिन चूंकि hook_menu()ड्रुपल कोर से अब उपयोग नहीं किया जाता है, hook_menu_alter()न तो उपयोग किया जाता है।

अन्य मॉड्यूल से परिभाषित मार्ग को बदलने के लिए आवश्यक कदम निम्नलिखित हैं:

  • एक सेवा को परिभाषित करें

    services:
      mymodule.route_subscriber:
        class: Drupal\mymodule\Routing\RouteSubscriber
        tags:
          - { name: event_subscriber }
  • एक कक्षा बनाएँ जो कक्षा का विस्तार करे RouteSubscriberBase

    namespace Drupal\mymodule\Routing;
    
    use Drupal\Core\Routing\RouteSubscriberBase;
    use Symfony\Component\Routing\RouteCollection;
    
    /**
     * Listens to the dynamic route events.
     */
    class RouteSubscriber extends RouteSubscriberBase {
    
      /**
       * {@inheritdoc}
       */
      protected function alterRoutes(RouteCollection $collection) {
        // Change the route associated with the user profile page (/user, /user/{uid}).
        if ($route = $collection->get('user.page')) {
          $route->setDefault('_controller', '\Drupal\mymodule\Controller\UserController::userPage');
        }
      }
    
    }

ध्यान दें कि पहले की Drupal 8 रिलीज़ की तुलना में, कुछ विवरण बदल दिए जाते हैं।

  • मार्ग का नाम से बदल दिया गया user_pageहैuser.page
  • उस मार्ग की आवश्यकताओं को इससे बदल दिया _access: 'TRUE'गया_user_is_logged_in: 'TRUE'
  • एक मार्ग के नियंत्रक को सेट करने की संपत्ति से बदल _contentगया_controller

यदि आप कई मार्गों से मेल खाना चाहते हैं, तो क्या एक $ मिलान किए गए चर को गलत पर सेट करने की तुलना में अधिक सुरुचिपूर्ण तरीका है, तो एक समय में उन सभी के माध्यम से चलना $collection->get()? मैं कोई स्पष्ट तरीके नहीं देख सकता।
विलियम टरेल

@WilliamTurrell के साथ आप एक ArrayIteratorवस्तु प्राप्त कर सकते हैं RouteCollection::getIterator(); कि सभी वस्तुओं पर पुनरावृति करना आसान होगा $collection। तुम भी में सभी मार्गों प्राप्त कर सकते हैं $collectionके साथ RouteCollection::all()जो एक सरणी देता है,।
kiamlaluno
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.