5

By clicking on the "My account" link that on the secondary menu on the site, the user is redirecting to the user's profile page.

In this page there are many tabs. Some tabs are there originally, and some tabs created by some modules. I understood how to add tabs to this menu (by simply create view and give it path of /user/%user/XXX).

Is there another way?
How can I remove tabs from the user's profile menu?

Why this user profile menu is not under the menus section of Drupal?

My goal is to remove the following tabs (see screenshot below): "HybridAuth", "Your Questions" and the "Points" tab. enter image description here

7 Answers 7

7

You might be looking for the Tab Tamer module:

Tab Tamer is an administration utility that provides easy re-ordering, hiding, and deactivation of tabs and subtabs. You can also rename tab labels.

9

If you don't want to use a contrib module like TabTamer then, In Drupal 7, you can use hook_menu_alter to disable the MENU TAB by using access callback


    /**
     * Implementing hook_menu_alter
     * Restrict MENU TABS access
     */
    function MODULE_NAME_menu_alter(&$items) {
        if(/* check your conditions */) {
            $items['user/%user/hybridauth']['access callback'] = FALSE;//Change the MENU PATH as per your requirement.
        }
    }

Note

  • Get the MENU PATH by printing $items variable.
2
  • It's a shame, hook_menu_alter() is not working on user page in my current Drupal installation, I don't know why
    – 118218
    Aug 25, 2014 at 11:42
  • I have the same issue,tabs are not being removed with hool_menu_alter,only the path is restricted.What am I missing?
    – Dion
    Jun 21, 2015 at 12:46
9

For Drupal 8, I was able to address this in 2 ways:

Change the name of a user account tab item / remove a tab item with hook_menu_local_tasks_alter:

/**
 * Implements hook_menu_local_tasks_alter().
 */
function MYMODULE_menu_local_tasks_alter(&$data, $route_name) {
    if ($route_name == 'entity.user.canonical') {
        foreach ($data['tabs'][0] as $type => &$tab) {
            // Replace the "View" tab name with "Hola"
            if ($type == 'entity.user.canonical' && $tab['#link']['title'] == 'View') {
                $tab['#link']['title'] = 'Hola';
            }
            unset($tab);
        }
        // Hide the "Edit" tab entirely
        unset($data['tabs'][0]['entity.user.edit_form']);
    }
}

One thing to note is that this doesn't actually make the edit user link inaccessible -- it merely hides it from the tabs at the top of the user profile. You'll need to implement routing to actually hide something.

Add a new tab item, in this case a "Status" form:

mymodule.links.menu.yml:

mymodule.account_status:
  title: 'Status'
  parent: 'entity.user.canonical'
  route_name: 'mymodule.account_status'

mymodule.links.task.yml:

mymodule.account_status:
  title: 'Status'
  route_name: 'mymodule.account_status'
  base_route: 'entity.user.canonical'

mymodule.routing.yml:

mymodule.account_status:
  path: '/user/{user}/status'
  defaults:
    _form: 'Drupal\mymodule\Form\AccountStatusForm'
    _title: 'Status'
  requirements:
    _permission: 'access content'
    user: \d+

mymodule/src/Form/AccountStatusForm.php:

namespace Drupal\subscription\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;

/**
 * Account status form
 */
class AccountStatusForm extends FormBase {

    /**
     * {@inheritdoc}
     */
    public function getFormId() {
        return 'mymodule_account_status_form';
    }

    /**
     * {@inheritdoc}
     */
    public function buildForm(array $form, FormStateInterface $form_state) {

        // TODO: Build form

        return $form;
    }

    /**
     * {@inheritdoc}
     */
    public function submitForm(array &$form, FormStateInterface $form_state) {

        // TODO: Handle submit

    }

}

This answer is pretty detailed so I'll leave it to folks to go through the D8 docs if anything is unclear. At minimum, you should understand the process of using custom forms (and/or controllers depending on what you need here) to implement this code.

1

Is there another way?

In Drupal, there's always another way. In fact, easier ways are often overlooked.

How can I remove tabs from the user's profile menu?

You could hide the Drupal generated tabs specifically from the user pages and add in your own:

  1. Go to /admin/structure/block
  2. Find "Tabs" Block in the "Content" region and click configure.
  3. Under the "Visibility" section select "Pages".
  4. Enter /user/* in the text area and select "Hide for the listed pages".
  5. Create a new menu with your desired links.
  6. At the block page used previously and select "Place Block" under the desired region.
  7. Choose your new menu.
  8. Use previous steps to only show the block on user pages.
  9. Theme the Block as needed.

Why this user profile menu is not under the menus section of Drupal?

The "Tabs" block is contextual which means that it is generated automatically depending on what page you are visiting and what modules hook into it. This is why you should only exclude them from the user pages in this case. Excluding them all together would(probably) have undesired results.

1

Renaming the tabs can be much easier in Drupal 8.

function mymodule_menu_local_tasks_alter(&$data, $route_name) {
  foreach ($data['tabs'][0] as $type => &$tab) {
    // Replace the "View" tab name with "view account"
    if ($type == 'entity.user.canonical') {
      $tab['#link']['title'] = t('view account');
    }

    // Replace the "Edit" tab name with "edit account"
    if ($type == 'entity.user.edit_form') {
      $tab['#link']['title'] = t('change password');
    }   
  }
}
0

As hook_menu_alter() was not triggered on user page in my Drupal installation, I managed to do it in another way, using hook_menu_local_tasks_alter():

function hook_menu_local_tasks_alter(&$data, $router_item, $root_path) {

    unset($data['tabs'][0]['output'][2]);

}

Where 2 is the position of the tab you want to remove.

The problem with this approach is that the position of tab you want to remove is exposed to be changed by another module I guess. Then installing more contrib modules after that, it could be problematic.

At least for my use case it's enough.

0

In a clean Drupal 8 way, you could alter tasks by using modulename_local_tasks_alter(), as described in the documentation

/**
 * Implements hook_local_tasks_alter().
 */
function modulename_local_tasks_alter(&$local_tasks) {
  // Remove unwanted tabs
  // Here, we'll remove the "Payment method" tasks from the user edit tasks
  unset($local_tasks['entity.commerce_payment_method.collection']);
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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