24

Can I hide the

Edit | View

tabs on top of each node ?

I've searched for this option in theme settings (both global and standard theme but I couldn't find it).

I still want to be able my customer to edit / administer content, so I cannot just remove the permission for it.

thanks

aneuryzm
  • 55,858
  • 96
  • 259
  • 471
  • 1
    I don't see any reason to remove the edit link, if then users are still allowed to edit nodes. The view tab will disappear if there are not other tabs, as the view tab is the default one. – kiamlaluno Aug 20 '10 at 15:17
  • 1
    I have been asked stranger things by clients in the past than removing the edit link! It is, after all, easy enough to edit content using the filter at /admin/content/node. Perhaps the OP should jump in and clarify why they wish to do this, however either way the question has been answered IMHO. – CitrusTree Aug 20 '10 at 15:27
  • 1
    Yeah.. I don't want the front-end layout to change. That's why I want to remove them. But of course, I want my customer being able to edit them from back-end. – aneuryzm Aug 20 '10 at 15:37

11 Answers11

19

here is a very easy solution for you. (Drupal 7)

  • Open your page.tpl.php in your current template and search for the $tabs variable.

  • Remove the render code if you want to hide it completely.

  • If you want to display it only to administrators use this code

    <?php if ($tabs and $is_admin): ?>
    <div class="tabs">
      <?php print render($tabs); ?>
    </div>
    

    The above code checks if the user is administrator. If it is it will render the tabs. If not it wont render them.

ANDiTKO
  • 437
  • 4
  • 8
  • Drupal will only print ANY tabs if there are two or more, and the only reason an Edit tab will show up is if the user has permission to edit the page (e.g. user is an admin)... so, it would be better to simply control access to editing this particular type of content on the permissions page than to perform a redundant check on the theme layer. Makes the site more secure at the same time. – geerlingguy Jan 18 '12 at 22:05
  • 1
    What a nose-bleedingly easy-to-implement and elegant answer. Or maybe this merely answers the precise question I was thinking. Regardless, thanks! – Screenack Aug 22 '12 at 13:30
  • This is an old post but I needed it today! Just wanted to mention to close the if statement. This worked perfect:
    – C13L0 Feb 12 '14 at 21:36
16

This really is a presentational thing, not a functionality thing, so it should be done at the theme level.

The problem with overriding theme_menu_local_tasks() is that you override/take a hatchet to the entire local task display, when you really just want to get in there with a scalpel to remove two specific local tasks. So, you need to get a little more specific.

theme_menu_local_tasks() gets the current page's local tasks and passes them to menu_local_tasks(). Here, two theme functions are used:

  1. theme_menu_item_link(), which gets the link markup for the task
  2. theme_menu_local_task(), which gets the <li> element for the task.

So, you can get rid of the View and Edit local tasks in a really robust way by overriding theme_menu_item_link() and theme_menu_local_task() to include your check for them:

function mytheme_menu_item_link($link) {
  // Local tasks for view and edit nodes shouldn't be displayed.
  if ($link['type'] & MENU_LOCAL_TASK && ($link['path'] === 'node/%/edit' || $link['path'] === 'node/%/view')) {
    return '';
  }
  else {
    if (empty($link['localized_options'])) {
      $link['localized_options'] = array();
    }

    return l($link['title'], $link['href'], $link['localized_options']);
  }
}

function mytheme_menu_local_task($link, $active = FALSE) {
  // Don't return a <li> element if $link is empty
  if ($link === '') {
    return '';
  }
  else {
    return '<li '. ($active ? 'class="active" ' : '') .'>'. $link ."</li>\n";  
  }
}

This way, you're relying on the menu router path, not modifying the menu router item, and achieving the result you want with minimal changes to core functionality or theming.

9

On the module side, you could do something that decouples the Edit's menu entry from the local tasks for the node:

function custom_menu_alter(&$items) {
  $items['node/%node/edit']['type'] = MENU_CALLBACK;
}

The edit path is still there, but now it is not associated with the View tab. This includes the edit page itself--no View tab there.

Grayside
  • 3,804
  • 17
  • 23
9

there is a module for that: tab tamer allows to hide or disable tabs and rename them as well.

uwe
  • 3,496
  • 10
  • 32
  • 47
1

For all the people stumbling upon this question while looking for a D7 solution: As stated on https://drupal.stackexchange.com/a/77964/15055 it's hook_menu_local_tasks_alter()

/**
 * Implements hook_menu_local_tasks_alter() to unset unwanted tabs
 */
function MYMODULE_menu_local_tasks_alter(&$data) {
  foreach ($data['tabs'][0]['output'] as $key => $value) {
    if ($value['#link']['path'] == 'node/%/view') {
      unset($data['tabs'][0]['output'][$key]);
    }
  }
}
Community
  • 1
  • 1
leymannx
  • 4,420
  • 4
  • 35
  • 42
1

I use the following in template.php by theme (which is perhaps a little hacky, I feel I should be considering unsetting $tabs instead):

function THEME_NAME_menu_local_tasks() {
  return '';
}

Or you could ommit:

if ($tabs) echo $tabs;

from your page.tpl.php...

CitrusTree
  • 184
  • 1
  • 10
  • You should never change functionality with a theme. That is bad practice that will, at some point, lead to problems. It is "just not right coding practice". – berkes Aug 20 '10 at 14:09
  • I agree to some extent, but the OP does not want to affect the functionality, they want the links not to show, which to me is a theme issue. – CitrusTree Aug 20 '10 at 14:29
  • But "not showing the links" is similar to "affecting the functionality". Why else do you want to hide some interface-item that has a clear functionality attached? – berkes Aug 20 '10 at 14:47
  • I don't believe it is. The OP asked simply "how do I hide the links" - but still wants to allow his customer to be able to edit the content (or view it!) - so what functionality are you suggesting should be removed? :0) – CitrusTree Aug 20 '10 at 14:49
  • 1
    Thanks for answering. I actually want the customer to edit the pages only from back-end, and not using the tabs link in the front-end. So, I want the functionality but not in the front-end. – aneuryzm Aug 20 '10 at 15:31
  • However, removing $tabs from the template is too general solution. I only want to remove "Edit and View" and not all tabs (i.e. user login page | create account). Maybe I should go with css rather than php ? – aneuryzm Aug 20 '10 at 15:34
1

View and Edit are functional features. They have a reason for being there.

The best way to "remove" them, is to "remove" that functionality alltogether. After all: why remove the interface of a piece of functionality, but not the functionality itself? Besides, simply not printing the tabs, does not remove the url endpoints. In other words: if you don't print the edit tab, people can still access the edit page.

Again: best is to remove that functionality: The fact that you don't want the edit tab, sounds as if you don't want the edit functionality for certain users. If so, then just remove that permission for that role. That is all. The tabs will be gone.

If, however, you simply wish to display these tabs differently, Drupal is your friends. As you may have noticed, they are called local tasks and not tabs. That is because the theme decides how to render them: The theme is the thing that decides to show them as tabs.

Simply override the theme_menu_local_tasks() to create your own HTML for the "local-tasks". And in your page-tpl, simply move the $tabs variable around to a place, where you want them.

But again: Don't try to change the behavior of the app, by removing interface-elements. That is not the right thing to do: you should change the behavior, in order to change the behavior :)

berkes
  • 25,081
  • 21
  • 107
  • 188
  • 1
    The OP does not want to remove the functionality, as explicitly stated - just hide the links. – CitrusTree Aug 20 '10 at 14:32
  • 1
    The title of the question says _disable_, and the question asks for hiding the links. In both the cases, the result would be that nobody would be able to edit a node, which is a functional feature. If there is the need to hide the edit link, then it is possible to not give the permission to edit a content type to some rules. I don't think that unconditionally hide the edit link (which would mean to hide it even to the user #1) would be a good idea. To me, it seems the question is asked because a misunderstanding of how Drupal works. – kiamlaluno Aug 20 '10 at 15:15
  • Whether the title says disable or hide, it still refers to the [tabs] - not the functionality. Whether the tabs should be hidden, or not, is not the question, and nor is whether the functionality should therefore be removed - the question is how the links are disabled / hidden etc. I'm sure you agree that in some cases we do things which are not 'correct' in our opinions, for example a client insisting these tabs are hidden for their own reasons. Whether the reason is this, or another reason, I see no valid argument that states these tabs must stay if the functionality still exists. – CitrusTree Aug 20 '10 at 15:24
  • "the result would be that nobody would be able to edit a node" How so? what about /admin/content/node ? If you remove permission in order to hide the edit link, the user cannot edit from here either... Again, the OP stated the user in question should still be able to edit the content. – CitrusTree Aug 20 '10 at 15:31
  • I'm sorry "disabling" was not the correct word. I meant hiding the links, and keep the functionality enabled. – aneuryzm Aug 20 '10 at 15:38
  • Not all users have access to `/admin/content/node`; removing those tabs would not help an authenticated user, who should manually write the link to the edit page. If the purpose is to hide the tabs to show the link in a different way, that is fine; it's not fine to remove the tabs without to show the edit links in a different way. – kiamlaluno Aug 20 '10 at 23:37
  • Of course, if I remove the tabs, I'm planning to provide access to the content from back-end. I'm not letting the user to type by himself the path. – aneuryzm Aug 23 '10 at 09:16
0

This is not the answer to the question of what the author asked. But somehow it might be useful for others user who facing the similar problem with me. Please let me know if this is not suitable to put in here.

I get the answer from @grayside and modified a bit to hide the view | edit tab from node based on the content type I want.

    function MYMODULE_menu_alter(&$items) { 
      $items['node/%node/view']['access callback'] = 'MYMODULE_disable_node_view';
      $items['node/%node/view']['access arguments'] = array(1); 
    } 

    function MYMODULE_disable_node_view($node){
      if($node->type == 'product'){
        return false;
      }
    }

product is the machine name of my content type, I don't want anywant to access it including root user.

cww
  • 471
  • 7
  • 14
0

The simplest solution to hide the tabs is to add this class in your theme css

.tabs{ display:none;}
Fahad Ur Rehman
  • 348
  • 1
  • 5
  • 18
0

Thanks for the last answer. But be aware of this detail: if you try it as-is it cannot work: literals should be just rounded with " or ', not both of them altogether. So it should be:

/**
 * Implements hook_menu_local_tasks_alter() to unset unwanted tabs
 */
function MYMODULE_menu_local_tasks_alter(&$data) {
  foreach ($data['tabs'][0]['output'] as $key => $value) {
    if ($value['#link']['path'] == "node/%/view") {
      unset($data['tabs'][0]['output'][$key]);
    }
  }
}

Once taken care of it, it works :)

oscaral
  • 1
  • 1
  • Please use the comment function instead the answer function if you want to say something to an existing answer. – leymannx Jan 07 '16 at 08:53
0

D8 solution: If you want to hide all "local" tabs on certain pages, remember that "Tabs" is listed in the block library: find it in the "Content" region and exclude by content type, page URL or user role.

William Turrell
  • 2,940
  • 6
  • 33
  • 52