I'm trying to add a tab to the user profile page. The hook_menu() documentation states that menu items of the type MENU_LOCAL_TASK is rendered as a tab by default. I implemented the following hook_menu() in my module

//implementation of hook_menu()
function modulename_menu()
{      $items['user/%user/listing'] = array(
		'title' => 'Module Name',
		'page_callback' => '_display_content',
		'access arguments' => array('access content'), //only users who have the permission 'access content' can access this menu resource
		'type' => MENU_LOCAL_TASK,
	);	
        
       return $items;
}

This hook displays the appropriate tab on the user profile page right next to the 'view' and 'edit' tabs. But when I click on the tab I get the following error -

Fatal error: require_once() [function.require]: Failed opening required 'sites/all/modules/modulename/user.pages.inc' (include_path='.;C:\xampp\php\pear\') in C:\xampp\htdocs\irp\includes\menu.inc on line 346

Why does this error show up? And why does the module require a user.pages.inc file? Also does this error have something to do with the missing menu item type MENU_DEFAULT_LOCAL_TASK ?

Please help..

** Edited **
Added the return statement on Budrick's suggestion.

Comments

zbricoleur’s picture

(I could be wrong but) the code you posted looks fine. And in fact it does work as intended, as you say--it creates the tabs. I think the problem lies with your callback function.

Jaypan’s picture

Seconded.

hkvd’s picture

The problem was occuring because I had made a mistake while typing. I had typed 'page_callback' instead of 'page callback'. I changed it and now the code works perfectly fine...

Thanks a lot for helping out.. :)

Budrick’s picture

For those who came here just to know how to add a new tab on user profile page, dont forget to add "return $items" in the end of modulename_menu().

scalp’s picture

I've spent the better part of the day trying to implement this with no luck. I've looked at every post I can find on it and tried every piece of advice I could find, but no matter what I do i cannot get a new tab to show up on the user profile page. Here's what I've ended up with in a customs.module file:

<?php
function customs_menu() {
    $items = array();
    // additional 'shortcut' tab (uses drupal_goto)
    $items['user/%user/customs'] = array(
    'title' => 'Invite',
    'page callback' => 'customs_user_customs_redirect',
    'type' => MENU_LOCAL_TASK,
    ); 
    return $items;
}

function customs_user_customs_redirect() {
    drupal_goto("node/add/invitation");
}
?>

Any advice would be helpful and appreciated. The goal is to place a tab on a user's profile page that would link to the node creation page for a content-type called invitation. If I can get this working I want to auto populate a user reference field in that form with the username from the profile the user came from.
The above code does nothing. The module's being seen because I can print from it. I tried moving the weight of the module around thinking that would do it, but it didn't help.

just_fixed_it’s picture

set access arguments, rebuild menus?
can you see the entry in your database?
try typing the url into your browser ... can you see the page?

scalp’s picture

You got my brain working. Here's what I ended up with:

<?php
function customs_menu() {
    $items = array();
    // additional 'shortcut' tab (uses drupal_goto)
    $items['user/%user/customs'] = array(
    'title' => 'Invite',
    'access callback' => 'user_access',
    'access arguments' => array('create invitation content'),
    'page callback' => 'customs_user_customs_redirect',
    'type' => MENU_LOCAL_TASK,
    ); 
    return $items;
}

function customs_user_customs_redirect() {
    drupal_goto("node/add/invitation");
}
?>

Trying to access /user/%user/customs gave me an access denied error. The looking in the DB was the key. menu_router table for anyone else that's looking. Comparing the entry that this was making to the others that had user/% as a parent tab did the trick.
Thank you!

scalp’s picture

Now I'm trying to do something similar to:

$uid = arg(1);
$user = user_load($uid);
if (in_array('2', $user->roles)) {.....

so that the new tab I've created will only show up if the user profile being viewed has a certain role. I'm guessing this has to be done in the access callback/argument combo. Any ideas how I could get this to work off of the user being viewed instead of the logged in user?

just_fixed_it’s picture

custom access callback, pass in user id ...

scalp’s picture

Just in case anyone is interested in adding a tab to a user profile page, having that tab only show on profiles of users of a certain role, and having that tab link to a node/add form that pre-populates a field with the uid of the profile you just came from, here you go:

<?php
function yourmodule_menu() {
    $items = array();
    // additional 'shortcut' tab (uses drupal_goto)
    $items['user/%user/pathyouwanttolinkto'] = array(
    'title' => 'New Tab',
    'access callback' => 'custom_tab_access',
    'page callback' => 'yourmodule_user_yourmodule_redirect',
    'type' => MENU_LOCAL_TASK,
    ); 
    return $items;
}

function custom_tab_access() {
   $uid = arg(1);
   $user = user_load($uid);
  // replace SomeRoleName with the name of the role to check for
   if (in_array('SomeRoleName', $user->roles))
   return 'TRUE';
}

function yourmodule_user_yourmodule_redirect() {
   // replace content-type with the content-type add form you want to redirect to
    drupal_goto("node/add/content-type", "uid=".arg(1));
}

// prepopulate field with username on content-type add form
function yourmodule_form_alter(&$form, $form_state, $form_id) {
   if (isset($form['type']) && isset($form['#node']) && $form['type']['#value'] .'_node_form' == $form_id) {
   $uid = $_GET['uid'];
   // I'm populating a userreference field here
   $form['field_provider']['0']['#default_value']['uid'] = $uid ;
   // You can use something like print_r($form['field_provider']); to find what value you need here
}
}
?>

It's pretty specific to my needs, but by replacing some things here and there it should be usable to others. Thanks just_fixed_it for all the help on this!

just_fixed_it’s picture

you're most welcome

chamme’s picture

function custom_tab_access() {
   $uid = arg(1);
   $user = user_load($uid);
  // replace SomeRoleName with the name of the role to check for
   if (in_array('SomeRoleName', $user->roles))
   return 'TRUE';
}

You better not test user roles in the code like that, because you will couple your code with some finite pre-defined user roles. The better way is using "user_access" library function to test user's right for the specific functionality, which can be assigned to any user role by administrator.
Please refer to this post for example:
http://drupal.org/node/122262

jaysonragasa’s picture

ok I have new Tab in user... then what?

How do I put contents inside that tab? in case I don't like redirecting .. ?

D2ev’s picture

create view of type page display and in path setting give page like " user/%user/pagepath ". In menu setting you can chose " Menu tab " option.

fraweg’s picture

Hello,

one question... does this code work with drupal 7?

Best regards
Frank