Has anybody got it? : )

I know this comes up all the time, but nobody ever seems to really answer it. Especially a Drupal 6 solution.

What I'm after is an overide for the template.php file (or really just any way), that can remove (and possibly add?) a defined tab on a defined page. And define multiple combinations.

i.e.

Remove 'users' tab on 'search' page
Remove 'My guestbook' tab on 'user' page
Add 'blog' tab on 'user' page

Can anybody help?

Thanks

Comments

francort’s picture

I think the problem of erase tabs is nasty.
I'm not sure if for that the right solution is to redefine that path in other custom module.
If someone has other solution, please reply. If someone feels that this is the best solution, please reply too :D

I have start with this kind of problem for dupal 5

I order to do this , one needs a custom module.
Well, as i said, for erase or hide the tab i'm not sure i am giving the right solution but is the best i can imagine for my experience and the documentation i have readed.
For adding blog tab i think i've done right, but you'll need to add permisions to the function which ask for them.
I don't know what module creates that guestbook, but i'm sure that you can hide/erase it the same way as search user tab.

d6.info file:

; $Id: Exp $
name = D6
description = override tabs
core = 6.x
package = can not be more optional

d6.module file:

function d6_menu() {
  
    $items['search/user/%menu_tail'] = array(
      'title callback' => 'module_invoke',
      'title arguments' => array('user', 'search', 'name', TRUE),
      'page callback' => 'search_view',
      'page arguments' => array($name),
      'access callback' => 'd6_search',
      'access arguments' => array('user'),
      'type' => MENU_LOCAL_TASK,
    );
    $items['user/%user/blog'] = array(
    'title' => 'Blog',
    'page callback' => 'd6_get_blog',
    'page arguments' => array(1),
    'access callback' => 'd6_blog_access',
    'access arguments' => array('access content'),
    'type' => MENU_LOCAL_TASK,
  );
  return $items;
}
function d6_search(){
	return false;
}
function d6_blog_access( $user ){
	return true;
}
function d6_get_blog( $user ){
	drupal_goto('blog/'.$user->uid);
}

I think this should work as a start point but it needs more work.

I hope this will help

PS: When you're working on this, if you wanna change anything inside d6_menu() , you'll need to unenable/reenable the module

unxposed’s picture

Thanks a million for taking the time to do this, it's really helpful.

I did as above and this worked great. But to tell the truth I don't fully understand it, so I've been experimenting myself at trying to add and delete other tabs... without much success...

I have very limited php knowledge so fail to understand most of the lines in the associative arrays. I've checked out the module developer guide but this makes little sense to me as it's not written in plain english (so for a designer very hard to understand). In fact it will be quicker to tell you what I think I do understand.

$items['I think this is the path that the tab we're refering to is responsible for']
'access callback' => 'this is how we refer to our tab further down the page'
'type' => MENU_LOCAL_TASK - I think this just means it's a tab

No idea on title, title callback or title arguments - apart from it obviously reffering to the title.

Not too sure on page callback - but I think it may be irrelevent for deleting tabs.

No idea on either of the arguments!

This is what I've attempted below... don't laugh too hard... just a little.... at least I tried! The only thing that actually works is the remove content tab from search (which isn't surprising as it's almost identicle to the 'user' search removal that you provided). Removing the edit tab form node 15 is doing something, as I can't access the edit page now, but the tab is still there. However, I can't even access user pages now though so the rest are just a mess!


<?php
function d6_menu() {

/**
 * Define array to remove 'Content' tab on search pages
 */

$items['search/node/%menu_tail'] = array(
      'title callback' => 'module_invoke',
      'title arguments' => array('node', 'search', 'name', TRUE),
      'page callback' => 'search_view',
      'page arguments' => array($name),
      'access callback' => 'd6_search',
      'access arguments' => array('node'),
      'type' => MENU_LOCAL_TASK,
);

/**
 * Define array to remove 'User's Guestbook' tab on user pages
 */

$items['user/%user/guestbook'] = array(
      'title callback' => 'module_invoke',
      'title arguments' => array('user', 'user', 'name', TRUE),
      'page callback' => 'user_guestbook_view',
      'page arguments' => array($name),
      'access callback' => 'd6_guestbook',
      'access arguments' => array('user'),
      'type' => MENU_LOCAL_TASK,
);

/**
 * Define array to remove 'View' tab on user pages
 */

$items['user/%user'] = array(
      'title callback' => 'module_invoke',
      'title arguments' => array('user', 'name', TRUE),
      'page callback' => 'user_view',
      'page arguments' => array($name),
      'access callback' => 'd6_user',
      'access arguments' => array('node'),
      'type' => MENU_LOCAL_TASK,
);

/**
 * Define array to add 'Profile' tab on user pages
 */

$items['user/%user'] = array(
      'title' => 'Profile',
      'page callback' => 'd6_user_get_profile',
      'page arguments' => array(1),
      'access callback' => 'd6_profile_access',
      'access arguments' => array('access content'),
      'type' => MENU_LOCAL_TASK,
);

/**
 * Define array to remove 'Edit' tab on node 15
 */
 
 $items['node/15/edit'] = array(
      'title callback' => 'module_invoke',
      'title arguments' => array('15', 'node', 'name', TRUE),
      'page callback' => 'd6_node_edit',
      'page arguments' => array($name),
      'access callback' => 'd6_node',
      'access arguments' => array('node'),
      'type' => MENU_LOCAL_TASK,
);
  
return $items;

}

function d6_search(){
    return false;
}
function d6_guestbook(){
    return false;
}
function d6_user(){
    return false;
}
function d6_profile_access( $user ){
    return true;
}
function d6_user_get_profile( $user ){
    drupal_goto('user/'.$user->uid);
}
function d6_node(){
    return false;
}
?>

This would be a great module with a nice friendly UI by the way, anyone else agree?

Thanks again.

francort’s picture

This is tricky even if you know some php. I don't feel really secure on this ground.
That associative array lines aren't really that much php but more drupal. This array it will be added in some way to the database and it will inteact with drupal's core.
About the documentation: maybe it is hard for a designer to understand it, but is also hard if your language is spanish :)

About your code:
1.- try not to use 'title callback' and 'title arguments' but just 'title'
2.- create a function like d6_always_false(){return false;} and use it for every 'access callback'
3.- don't use 'access arguments' ( since your "always_false" function doesn't need them )

i hope your code would start to work after that

Maybe in a distant future when i fully understand how this specific thing works i would think in doing a friendly module :) This is a part of drupal( hook_menu ) in which i don't feel comfortable.

unxposed’s picture

Great! Thanks for the pointers, I'll give this a go tomorrow morning and report back.

Thnaks again.

unxposed’s picture

Okay I feel like I'm quite close... but I'm sill having a few issues...

In the code below I'm trying to:

a.) Remove the view tab from users pages and replace it with a 'Profile' tab (basically just rename it).
b.) Keep the profile whilst on the the blog pages, so it's easy to get back to the users profile.
c.) Add a blog tab on user profile pages, also have this on the blog pages
d.) Only show the blog tab if the user is of a specific role (i.e. actually has the permissions to have a blog)

Currently the code:

a.) Is not removing the view tab.
b.) It IS adding a profile tab and a blog tab to both profile and blog pages, that actually work - but they are not 'active' when on the relevent pages!
d.) When I add the role specific conditional (as below), the blog tab dissapears altogether, even from users profiles of that role.

Any help would be reallllllllllly appreciated. Thanks!

<?php
function d6_menu() {

   $items['user/%user/'] = array(
    'title' => 'View',
    'page callback' => 'remove_user_view',
    'page arguments' => array($name),
    'access callback' => 'd6_remove_user_view',
    'type' => MENU_LOCAL_TASK,
    );
 
   $items['user/%user/'] = array(
    'title' => 'Profile',
    'page callback' => 'd6_get_profile',
    'page arguments' => array(1),
    'access callback' => 'd6_profile_access',
    'access arguments' => array('access content'),
    'type' => MENU_LOCAL_TASK,
	'weight' => '-45',
  );

   $items['blog/%user/user'] = array(
    'title' => 'Profile',
    'page callback' => 'd6_get_profile_02',
    'page arguments' => array(1),
    'access callback' => 'd6_profile_access_02',
    'access arguments' => array('access content'),
    'type' => MENU_LOCAL_TASK,
	'weight' => '-45',
  );
  
  $items['user/%user/blog'] = array(
    'title' => 'Blog',
    'page callback' => 'd6_get_blog',
    'page arguments' => array(1),
    'access callback' => 'd6_blog_access',
    'access arguments' => array('access content'),
    'type' => MENU_LOCAL_TASK,
	'weight' => '-40',
  );
  
    $items['blog/%user/blog'] = array(
    'title' => 'Blog',
    'page callback' => 'd6_get_blog_02',
    'page arguments' => array(1),
    'access callback' => 'd6_blog_access_02',
    'access arguments' => array('access content'),
    'type' => MENU_LOCAL_TASK,
	'weight' => '-40',
  );
  
  return $items;
}

function d6_remove_user_view(){
    return false;
}

function d6_profile_access( $user ){
    return true;
}

function d6_get_profile( $user ){
    drupal_goto('user/'.$user->uid);
}

function d6_profile_access_02( $user ){
    return true;
}

function d6_get_profile_02( $user ){
    drupal_goto('user/'.$user->uid);
}

function d6_blog_access( $user ){
    if (in_array('administrator', array_values($user->roles))) {
    	return true;
	} else {
		return false;
	}
}

function d6_get_blog( $user ){
    drupal_goto('blog/'.$user->uid);
}

function d6_blog_access_02( $user ){
    	return true;
}

function d6_get_blog_02( $user ){
    drupal_goto('blog/'.$user->uid);
}

?>
unxposed’s picture

Ah, changing the above section to this removes Views!

   $items['user/%user/view'] = array(
    'title' => 'View',
    'page callback' => 'remove_user_view',
    'page arguments' => array($name),
    'access callback' => 'd6_remove_user_view',
    'type' => MENU_LOCAL_TASK,
    );

Getting profiles & blogs tabs active is the priority now.

francort’s picture

a) use locale module with a custom language( core optional module )
1.- Enable "Locale" module
2.- Go to Administer › Site configuration > Localization and add a custom lenguaje and set it as default( keep english active anyway )
3.- Go to "manage strings"( same page ) and search for the string you want to change( e.g. Anonymous )
4.- Change the caption of that label with something you like ( one space if you don't want it to appear , o something like "user" )

Always if there are text in a module or theme like: t('some text') , you can change that text throught Locale module
b) You can't give 2 equal keys like 'user/%user/' and 'user/%user/blog'. Change those keys.
c) ? i suppose that's working
d) maybe b) problem

nice work :D

unxposed’s picture

Okay I give up!

This is far hard than it should be! Thanks for your help though : )

I've decided to do something like this instead

http://drupal.org/node/328073

Thanks again

francort’s picture

:(

nirenj’s picture

Can this be done in v 5.x also. Can I just use this in my v 5.9 code also.

Thanks.

francort’s picture

First of all, upgrade your Drupal 5 to the latest version ( today 5.12 )
It is just a bit different. In drupal 5 it has a $may_cache variable.
You can see more about the differences in
http://api.drupal.org/api/function/hook_menu
http://api.drupal.org/api/function/hook_menu/5

nirenj’s picture

Thanks for your reply.

It is very difficult to upgrade to 5.12 now, bcos I have done many modifications to the existing system, and so much content is already created inside.

I also see $may_cache inside the code of 5.9.

Is there any way to implement this tab method you mentioned above into the 5.9 version.

Thanks a lot.

dman’s picture

... It's finding to bit to change that takes all the time!

That approach is one way, but there's a small issue.

I think hook_menu_alter() is the right way to make changes to existing menu constructs. Not hook_menu.
It's possible that you can get inconsistent behavior because the menu gets built by the different modules in an unspecified order. (The order can be specified in the system table, but anyway...)
This means that sometimes the real menu definition will overwrite this modified version. Sometimes.

Anyway, I think that is what hook_menu_alter is for. To change other module AFTER they've been defined.

Here is the ULTRA-MINIMAL tweak needed :-)
tweakmenu.module

/**
 * @file Change the available menu options
 * 
 * So far, just totally disables 'search user'
 */

function tweakmenu_menu_alter(&$items) {
  unset($items['search/user/%menu_tail']); 
}
; $Id: Exp $
name = tweakmenu
description = Adjust menu and disable tabs
core = 6.x

... This can be made better with an admin setting or two, or a permissions setting so you can disable them on a per-role basis.
This is just a simple sample, and could probably be general-cased and worked into another existing module.

No, it's different for D5. This is why D6 is cooler ;-)

.dan.
if you are asking a question you think should be documented, please provide a link to the handbook where you think the answer should be found.
| http://www.coders.co.nz/ |

francort’s picture

Thanks dman for joining
I didn't know that hook for d6
My life is easier now :)

akolahi’s picture

Why not use css to hide (display: none) the core tabs and create your own menu simply by theming the user template page?

francort’s picture

Because that way I can't have access control and also every time a new module that generates tabs is added, I would need to add a new tab manually each time.
I would prefer to have a general solution that works in any case.

Bilalx’s picture

- You can use user permissions
- You can play with $tabs in page.tpl.php to add remove what you want with string functions
- You can havea look at http://drupal.org/node/68792#comment-1004484 and http://drupal.org/node/68792#comment-1119244

Magilas’s picture

Being new here, I could very well be wrong to think
that "definitive" (not "definative") was meant.

There! I opened my mouth.

"Better to remain silent and be thought a fool,
than to open your mouth and remove all doubt."

Magilas