Hi all

The default tab menu provided for user profiles is one with a "Account Settings" heading.

1)What if I want to change this header?

2) What if I want to place some of the fields in here to other groups (ie other tabs defined for user profiles??)
For example, the location module provides in the "Account Settings" section a form to enter location detail.
Now, I want to create a new group "Personal Information" and place the location stuff in this tab.

Can anyone point me out to solving these kinf of problems?

Thanks in advance

Comments

carlmcdade’s picture

Create module and use the the pathways to the user module in the menu code. This is an example that will and a tab and child links to the users tabs when they visit their account. This is for 4.7 so you will have to moddify it to suit 5.0 or 6.0.

$items[] = array('path' => 'user/'. arg(1) .'/edit/forum', 'title' => t('forum profile'),
        'callback' => 'forum_profile_edit', 'access' => $user->uid == arg(1) || user_access('administer users'),
        'type' => MENU_LOCAL_TASK);
        
      $items[] = array('path' => 'user/'. arg(1) .'/edit/personal', 'title' => t('personal profile'),
        'callback' => 'forum_profile_edit', 'access' => $user->uid == arg(1) || user_access('administer users'),
        'type' => MENU_LOCAL_TASK);
        
      $items[] = array('path' => 'user/'. arg(1) .'/edit/work', 'title' => t('work profile'),
        'callback' => 'forum_profile_edit', 'access' => $user->uid == arg(1) || user_access('administer users'),
        'type' => MENU_LOCAL_TASK);
        
      $items[] = array('path' => 'user/'. arg(1) .'/forum', 'title' => t('forum profile'),
        'callback' => 'forum_profile_view', 'access' => $user->uid > 0,
        'type' => MENU_LOCAL_TASK);
      
      $items[] = array('path' => 'user/'. arg(1) .'/forum/personal', 'title' => t('personal profile'),
        'callback' => 'forum_profile_view', 'access' => $user->uid > 0,
        'type' => MENU_LOCAL_TASK);
        
      $items[] = array('path' => 'user/'. arg(1) .'/forum/work', 'title' => t('work profile'),
        'callback' => 'forum_profile_view', 'access' => $user->uid > 0,
        'type' => MENU_LOCAL_TASK);
	  $items[] = array('path' => 'forum/node', 'title' => t('forums'),
	      'callback' => 'forum_node',
	      'access' => user_access('access content'),
	      'type' => MENU_CALLBACK);
	  $items[] = array('path' => 'forum/comment/reply', 'title' => t('forums'),
	      'callback' => 'post_comment_form',
	      'access' => user_access('post comments'),
	      'type' => MENU_CALLBACK);
	  $items[] = array('path' => 'forum/moderate', 'title' => t('forum moderation'),
	      'callback' => 'forum_moderate',
	      'access' => $access,
	      'type' => MENU_CALLBACK);
	  $items[] = array('path' => 'forum/moderate/comment', 'title' => t('forum moderation'),
	      'callback' => '_forum_comment_moderate',
	      'access' => $access,
	      'type' => MENU_CALLBACK);
   
  }

Hiveminds Magazine | FireOrb | Drupal Street | Drupal offline manual

brollo’s picture

Hey, thanks

Could you be a bit more specific though. I know your code goes in the hook_menu for some module.. but..

What module do I create? Isn't changing drupal user module good enough in this case?

carlmcdade’s picture

You could change the user.module but I don't recommend it. Just create a module of any type or name. You could also add code to another contirbuted module. Unless you consider yourself satisfied with the version you are using or a Drupal expert, you want to leave a core file like user.module alone.

The syntax for drupal 6


function page_example_menu() {
  // This is the minimum information you can provide for a menu item.
  $items['foo'] = array(
    'title' => 'Foo',
    'page callback' => 'page_example_foo',
    'access arguments' => array('access foo'),
  );

  // By using the MENU_CALLBACK type, we can register the callback for this
  // path but not have the item show up in the menu; the admin is not allowed
  // to enable the item in the menu, either.
  //
  // Notice that the 'page arguments' is an array of numbers. These will be
  // replaced with the corresponding parts of the menu path. In this case a 0
  // would be replaced by 'bar', a 1 by 'baz', and like wise 2 and 3 will be
  // replaced by what ever the user provides. These will be passed as arguments
  // to the page_example_baz() function.
  $items['bar/baz/%/%'] = array(
    'title' => 'Baz',
    'page callback' => 'page_example_baz',
    'page arguments' => array(2, 3),
    'access arguments' => array('access baz'),
    'type' => MENU_CALLBACK,
  );

  return $items;
}

Hiveminds Magazine | FireOrb | Drupal Street | Drupal offline manual

brollo’s picture

So what a module that only implements a menu hook? (apart from other non-harming ones: help, perm, etc.. )

And somehow make it override the user defaults? I still am not clear about how this would be done..

I am still searching for the total illumination

Thanks anyways

carlmcdade’s picture

What version of Drupal are you using?

Hiveminds Magazine | FireOrb | Drupal Street | Drupal offline manual

brollo’s picture

Drupal 5.7; linux ubuntu.

brollo’s picture

Ok , I kind of managed to get it working even though the workflow is still not going right.

I have a module with just the hook_menu implemented. Just by the Paths that are entered the right tabs and submenus get automatically generated in the user profile page.

The question is now:
How do I change which fields appear under each tab menu?

For example, I'd like to put the user profile picture field into a single separte tag called "User Picture". How do I do that ?

brollo’s picture

Hey

I kind of am getting something now.

But I am still not really understanding how the whole work flow goes.

Example: For the user picture/avatar being rendered into a different tab menu item, I have now the following code in the costum module and hook_menu function


      $items[] = array('path' => 'user/'. arg(1) .'/edit/picture', 'title' => t('Picture'),
        'callback' => 'SOME_FUNCTION', 'callback arguments' => array( 'user_edit'), 
	'access' => $user->uid == arg(1) , 'type' => MENU_LOCAL_TASK);

So, I added the "/picture" to the path key.. I dont know if this is right, I just made it up.

Then I put the callback in and this can be redirected to a function to render the appropriate form ..
I got the user profile for if I callback to a function such as :

function my_module_change_form(){
  if (variable_get('user_pictures', 0) && !$register) {
    $form['picture'] = array('#type' => 'fieldset', '#title' => t('Picture'), '#weight' => 1);
    $picture = theme('user_picture', (object)$edit);
    if ($picture) {
      $form['picture']['current_picture'] = array('#value' => $picture);
      $form['picture']['picture_delete'] = array('#type' => 'checkbox', '#title' => t('Delete picture'), '#description' => t('Check this box to delete your current picture.'));
    }
    else {
      $form['picture']['picture_delete'] = array('#type' => 'hidden');
    }
    $form['picture']['picture_upload'] = array('#type' => 'file', '#title' => t('Upload picture'), '#size' => 48, '#description' => t('Your virtual face or picture. Maximum dimensions are %dimensions and the maximum size is %size kB.', array('%dimensions' => variable_get('user_picture_dimensions', '85x85'), '%size' => variable_get('user_picture_file_size', '30'))) .' '. variable_get('user_picture_guidelines', ''));
  }

 // $form['picture']['picture_submit'] = array('#type'=> submit, '#value' => t('Submit'));
 $form['#submit']['picture_submit'] = array();

  $output = drupal_render(theme('table', $form['header']['#value'], $rows));
  $output.= drupal_render($form); // Process any other fields and display them
  return $output;

}

The problems are that:
1) No submit button or submit button not working..
2) Still I dont understand how this whole thing can be handled.. For example: User location fields. (location.module) ; here I need to hack through the location module because it is the responsable for placing location form into the "account" tab!!

brollo’s picture

This what I have written so far for trying to customize the layout under each user tab.

The thing I try here is to place the "user picture/avatar" field in a different tab "Picture" .

I try it in two different ways, with the _user hook and with the _menu hook.

I cannot get in one way the Submit button to actually submit and in other case ..

Can anyone help me fix this out please?

<?php
// $Id: user_profile_menu.module,v 1.745.2.26 2008/01/07 02:30:35 drumm Exp $



/**
 * Implementation of hook_menu().
 */
function user_profile_menu_menu($may_cache) {
  global $user;

  $items = array();
/**/
  $admin_access = user_access('administer users');
  $access_access = user_access('administer access control');
  $view_access = user_access('access user profiles');

  if ($may_cache) {

    // Your personal page
    if ($user->uid) {
      $items[] = array('path' => 'user/'. $user->uid, 'title' => t('My account'),
        'callback' => 'user_view', 'callback arguments' => array(arg(1)), 'access' => TRUE,
        'type' => MENU_DYNAMIC_ITEM);
    }

    $items[] = array('path' => 'logout', 'title' => t('Log out'),
      'access' => $user->uid,
      'callback' => 'user_logout',
      'weight' => 10);
  }


  else {
    // Add the CSS for this module. We put this in !$may_cache so it is only
    // added once per request.
    drupal_add_css(drupal_get_path('module', 'user') .'/user.css', 'module');
    if ($_GET['q'] == 'user' && $user->uid) {
      // We want to make the current user's profile accessible without knowing
      // their uid, so just linking to /user is enough.
      drupal_goto('user/'. $user->uid);
    }

    if (arg(0) == 'user' && is_numeric(arg(1)) && arg(1) > 0) {
      $account = user_load(array('uid' => arg(1)));

      if ($user !== FALSE) {
        // Always let a user view their own account
        $view_access |= $user->uid == arg(1);
        // Only admins can view blocked accounts
        $view_access &= $account->status || $admin_access;


        $pic_category = array('name' => "picture" , 'title' => 'Picture', 'weight' => 2 );
        $categories = _user_categories($account) ;
        array_push(  $categories, $pic_category )  ; 

        if (arg(2) == 'edit') {
          if ($categories && (count($categories) > 1)) {

            foreach ($categories as $key => $category) {

              $items[] = array(
                'path' => 'user/'. arg(1) .'/edit/'. $category['name'],
                'title' => $category['title'] ,
                'type' => $category['name'] == 'account' ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
                'weight' => $category['weight'],
                'access' => ($admin_access || $user->uid == arg(1)));
            }
          }
        }
      }
    }






     $items[] = array('path' => 'user/'. arg(1) .'/edit/image', 'title' => t('Image'),
        'callback' => 'user_profile_menu_edit_form', 'callback arguments' => array( 'user_edit'), 
	'access' => $user->uid == arg(1) , 'type' => MENU_LOCAL_TASK);


  }

  return $items;
}


/**
 * Implementation of hook_user().
 */

function user_profile_menu_user($op, &$edit, &$account, $category = NULL) {

  if ($op == 'form' ) {

	 // Picture/avatar:
	  if (variable_get('user_pictures', 0) && !$register) {
	    $form['picture'] = array('#type' => 'fieldset', '#title' => t('Picture'), '#weight' => 1);
	    $picture = theme('user_picture', (object)$edit);
	    if ($picture) {
	      $form['picture']['current_picture'] = array('#value' => $picture);
	      $form['picture']['picture_delete'] = array('#type' => 'checkbox', '#title' => t('Delete picture'), '#description' => t('Check this box to delete your current picture.'));
	    }
	    else {
	      $form['picture']['picture_delete'] = array('#type' => 'hidden');
	    }
	    $form['picture']['picture_upload'] = array('#type' => 'file', '#title' => t('Upload picture'), '#size' => 48, '#description' => t('Your virtual face or picture. Maximum dimensions are %dimensions and the maximum size is %size kB.', array('%dimensions' => variable_get('user_picture_dimensions', '85x85'), '%size' => variable_get('user_picture_file_size', '30'))) .' '. variable_get('user_picture_guidelines', ''));
	  }
	  
	return $form;
  }



  if (($op == 'update' || $op == 'insert' || $op == 'submit') ) {
	return _user_edit_submit(arg(1), $edit);
  }
}

function user_profile_menu_edit_form($uid, $edit, $register = FALSE) {
  $admin = user_access('administer users');

  // Account information:
  $form['account'] = array('#type' => 'fieldset',
    '#title' => t('Account information'),
  );


  // Picture/avatar:
  if (variable_get('user_pictures', 0) && !$register) {
    $form['picture'] = array('#type' => 'fieldset', '#title' => t('Picture'), '#weight' => 1);
    $picture = theme('user_picture', (object)$edit);
    if ($picture) {
      $form['picture']['current_picture'] = array('#value' => $picture);
      $form['picture']['picture_delete'] = array('#type' => 'checkbox', '#title' => t('Delete picture'), '#description' => t('Check this box to delete your current picture.'));
    }
    else {
      $form['picture']['picture_delete'] = array('#type' => 'hidden');
    }
    $form['picture']['picture_upload'] = array('#type' => 'file', '#title' => t('Upload picture'), '#size' => 48, '#description' => t('Your virtual face or picture. Maximum dimensions are %dimensions and the maximum size is %size kB.', array('%dimensions' => variable_get('user_picture_dimensions', '85x85'), '%size' => variable_get('user_picture_file_size', '30'))) .' '. variable_get('user_picture_guidelines', ''));
  }


  $form = _user_forms($edit, $account, $category);
  $form['_category'] = array('#type' => 'value', '#value' => $category);
  $form['_account'] = array('#type' => 'value', '#value' => $account);
  $form['submit'] = array('#type' => 'submit', '#value' => t('Submit'), '#weight' => 30);
  if (user_access('administer users')) {
    $form['delete'] = array('#type' => 'submit', '#value' => t('Delete'), '#weight' => 31);
  }
  $form['#attributes']['enctype'] = 'multipart/form-data';

//  return $form;
  $output = drupal_render(theme('table', $form['header']['#value'], $rows));
  $output.= drupal_render($form); // Process any other fields and display them
  return $output;
}



function generate_user_picture_form(){

	 // Picture/avatar:
	  if (variable_get('user_pictures', 0) && !$register) {
	    $form['picture'] = array('#type' => 'fieldset', '#title' => t('Picture'), '#weight' => 1);
	    $picture = theme('user_picture', (object)$edit);
	    if ($picture) {
	      $form['picture']['current_picture'] = array('#value' => $picture);
	      $form['picture']['picture_delete'] = array('#type' => 'checkbox', '#title' => t('Delete picture'), '#description' => t('Check this box to delete your current picture.'));
	    }
	    else {
	      $form['picture']['picture_delete'] = array('#type' => 'hidden');
	    }
	    $form['picture']['picture_upload'] = array('#type' => 'file', '#title' => t('Upload picture'), '#size' => 48, '#description' => t('Your virtual face or picture. Maximum dimensions are %dimensions and the maximum size is %size kB.', array('%dimensions' => variable_get('user_picture_dimensions', '85x85'), '%size' => variable_get('user_picture_file_size', '30'))) .' '. variable_get('user_picture_guidelines', ''));
	  }
	  
	$form['_category'] = array('#type' => 'value', '#value' => $category);
	  $form['_account'] = array('#type' => 'value', '#value' => $account);
	  $form['submit'] = array('#type' => 'submit', '#value' => t('Submit'), '#weight' => 30);
	  if (user_access('administer users')) {
	    $form['delete'] = array('#type' => 'submit', '#value' => t('Delete'), '#weight' => 31);
	  }
	  $form['#attributes']['enctype'] = 'multipart/form-data';

  $output = drupal_render(theme('table', $form['header']['#value'], $rows));
  $output.= drupal_render($form); // Process any other fields and display them
  return $output;

}
gausarts’s picture

Have you tried avatar module from http://chapter3llc.com/? There is a tutorial and a module for your need there, no official release as I know this far, but the module just works fine if you only need to move user picture.

love, light n laughter

drupalina’s picture

I have been struggling with this for a very long time. But I'm nearly zero at coding.

Would you be so kind as to attach your version of the custom module? or maybe upload it somewhere and provide the link.

Thanks

rsm08’s picture

The problem is, that the individual contrib modules themselves choose in which category (tab) to put their fields, using the 'form' op of the hook_user function. Your module can even create your own categories with the 'categories' op.

It seems to me that there are no way no override the category choice of the different modules, so the only solution would be to hack each module's hook_user function and change the category each place! ... UGH!

Anybody got suggestion for another method?!

Plazmus’s picture

Below code will display Picture form under new tab "Picture" (Drupal 6):

// $Id$

/**
 * Implementation of hook_user()
 */
function custom_module_user($op, &$edit, &$account, $category = NULL) {
    switch($op) {
      case 'categories':
        $categories = array();
        $categories['picture'] = array(
          'name' => 'picture',
          'title' => 'Picture',
          'weight' => 5,
        );
        return $categories;             
        break;
      case 'form':
          if ($category == 'picture') {   
              $form['_category'] = array('#type' => 'value', '#value' => $category);
              $form['_account'] = array('#type' => 'value', '#value' => $account);
                   
              if (variable_get('user_pictures', 0)) {
                  $form['picture'] = array('#type' => 'fieldset', '#title' => t('Picture'), '#weight' => 1);
                  $picture = theme('user_picture', (object)$edit);
                   if ($edit['picture']) {
                      $form['picture']['current_picture'] = array('#value' => $picture);
                      $form['picture']['picture_delete'] = array('#type' => 'checkbox', '#title' => t('Delete picture'), '#description' => t('Check this box to delete your current picture.'));
                   }
                   else {
                      $form['picture']['picture_delete'] = array('#type' => 'hidden');
                   }
                  $form['picture']['picture_upload'] = array('#type' => 'file', '#title' => t('Upload picture'), '#size' => 48, '#description' => t('Your virtual face or picture. Maximum dimensions are %dimensions and the maximum size is %size kB.', array('%dimensions' => variable_get('user_picture_dimensions', '85x85'), '%size' => variable_get('user_picture_file_size', '30'))) .' '. variable_get('user_picture_guidelines', ''));
                  $form['#validate'][] = 'user_profile_form_validate';
                  $form['#validate'][] = 'user_validate_picture';
                  $form['#uid'] = $account->uid;
              }
              return $form;
          }
          break;

      case 'submit':
          if($category == 'picture') {
          return _user_edit_submit((isset($account->uid) ? $account->uid : FALSE), $edit);
          }
          break;
                  
  }
}

/**
 * Implementation of hook_form_alter()
 */
function custom_module_form_alter(&$form, $form_state, $form_id) {
    switch ($form_id){
        case 'user_profile_form':
            if(arg(3) == NULL) {
          unset($form['picture']);
            }
            break;
    }
}
drupalina’s picture

Hi,

Thanks for the code. But where are we supposed to put it?
I've pasted it in my theme's template.php , but nothing changed...

Thanks

Plazmus’s picture

You should place it in your module it will not work from template.php

How to create module you can find here http://drupal.org/node/206753 , you will only need custom_module.info and custom_module.module files, this code should go to .module file :)

jday’s picture

I'm trying to modify Plazmus's picture-to-tab code to try an move the user locations fieldset to a profile tab but I'm getting this error

warning: Illegal offset type ....

has anyone done this before?

gone404’s picture

The best way to go about this is to:

1) Create a new view
2) Ceate a page display
3) Set the menu option in page settings to Tab (secondary links)
4) Go from there

I found this out after trying multiple programmatic ways of getting a tab in the user profile. I think you will be pleasantly surprised, especially if you are proficient with views.

saurabh.bhambry’s picture

This certainly seems like an interesting work around.. A few more details would be appreciated . Thanks