1

In a custom module I have implemented hook_menu() using the following code.

function MYMODULE_menu() {
  $items = [];

  $items['%/review'] = [
    'page callback' => 'review',
    'page arguments' => [0],
    'access arguments' => ['access content'],
    'type' => MENU_CALLBACK,
  ];

  return $items;
}

Wildcard should be existing node. I am trying to access mydomain.com/product1/reviews (where product1 is node/1) and then print some related product data on reviews page.

I'm getting a 404 error. If I change $items['%/review'] to $items['abc/%'] everything works. What can be the problem?

Note: I don't want to change node route. I want to access this path mydomain.com/product1/reviews where product1 is an existing node.

  • 2
    You can't have a wildcard as the first argument. – Kevin Nov 1 at 21:16
  • @Kevin how should I target for example path mydomain.com/product1/reviews (product1 being node/1) ? Thank you – loparr Nov 1 at 21:39
  • Why change the node route? – Kevin Nov 2 at 1:01
  • 1
    You want a path alias for that. – Jaypan Nov 2 at 1:48
  • 1
    You still cannot have a wildcard as the first argument. It would have to be node/%node/reviews or product/%node/reviews. – Kevin Nov 2 at 12:13
1

Since your products are nodes, this is what you need to do

  $items['node/%node/review'] = [
    'page callback' => 'my_module_review',
    'page arguments' => [1],
    'access arguments' => ['access content'],
    'type' => MENU_CALLBACK,
  ];

In your callback

function my_module_review($node) {
  // since you used %node you have access directly to the $node object here as param
}

So basically right now you can only access it via /node/{nid}/review similarly how you can access the edit form via /node/{nid}/edit

Now, install & enable Sub-pathauto

For example, if user/1 is aliased to users/admin, this module rewrites the link to the user contact page user/1/contact to use the aliased URL users/admin/contact instead. This also includes Views URLs taking a node as argument (e.g. node/%/yourview)

So it converts it to /{node-alias}/review and also you'll now be able to access the node edit form via /{node-alias}/edit

0

Wildcards may not be used as the first component of a route path in hook_menu. https://api.drupal.org/api/drupal/modules%21system%21system.api.php/function/hook_menu/7.x

what can you do if you want this feature, the solution is kind of tricky solution like

function MYMODULE_menu() {
  $items = [];
 $myItems =  // load what do you have
foreach($myItems as $myItem){
  $items[$myItem.'/review'] = [
    'page callback' => 'review',
    'page arguments' => [0],
    'access arguments' => ['access content'],
    'type' => MENU_CALLBACK,
  ];
}

  return $items;
}
  • Interesting creative solution, but if you have lots of $myItems, when there is no cache yet (cache is invalidated/flushed for whatever reason), the site will load slow until all those menu items get cached. Also, the cache table for these menus items will be larger. – No Sssweat Nov 2 at 11:17
  • @NoSssweat, yes, it has this limitation, but when he/she want this it seems there is no more option. as I deduced from the question number of the items are not alot. – Yusef Nov 2 at 11:49
  • See my answer for the better way. – No Sssweat Nov 2 at 11:58
  • @NoSssweat node/%node/review, this is another tricky solution and particularly for node and other entities and it never works for custom routes. btw, it's working for his/her case ;-). thank you. – Yusef Nov 3 at 9:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.