background image
HomeRecent PostsDrupalSearchTagsRSSContactAboutAccount

Adding functionality to allow users to select different profile themes

Eric.London's picture

In this blog entry, I'll show you how you can add some module code to allow users to select different themes for their profile page. I decided to use the standard user-profile.tpl.php as the base template. I copied this file into my theme folder and replicated it a few times. I named the files:

user-profile-version-1.tpl.php
user-profile-version-2.tpl.php

For my example, I simply added the text "Version 1" and "Version 2" to the top of these files to show it's working, but you could revise the layout, add CSS, etc.

Next, I created a module to contain all the following code. I defined a hook_perm() and hook_menu() function to add a menu local task (tab) to the user page.

<?php
function MYMODULE_perm() {
  return array(
   
'choose profile theme'
 
);
}

function
MYMODULE_menu() {
 
 
$items = array();
 
 
$items['user/%user/choose-profile-them'] = array(
   
'title' => 'Choose Profile Theme',
   
'page callback' => '_MYMODULE_callback_choose_profile_theme',
   
'page arguments' => array(1),
   
'access callback' => 'user_access',
   
'access arguments' => array('choose profile theme'),
   
'type' => MENU_LOCAL_TASK,
  );
 
  return
$items;
 
}
?>

user profile tab

Next, I defined the page callback to create a list of available templates for the user to choose from.

<?php
function _MYMODULE_callback_choose_profile_theme($user) {

 
// create an empty strong variable for page html
 
$html = "";

 
// define a list of available profile templates
 
$profileTemplates = array(
   
'user-profile-version-1' => 'Version 1',
   
'user-profile-version-2' => 'Version 2'
 
);
 
 
// loop through templates and ensure they exist
 
foreach ($profileTemplates as $template => $name) {
    if (!
file_exists(path_to_theme() . '/' . $template . '.tpl.php')) {
      unset(
$profileTemplates[$name]); 
    }
  }
 
  if (
count($profileTemplates)) {
   
$html .= drupal_get_form('_MYMODULE_callback_choose_profile_theme_form', $user, $profileTemplates);
  } else {
   
$html .= "No profile themes currently exist.";
  }
 
  return
$html;
 
}
?>

The following functions define the form array, and validation and submit handlers. When the form is submitted, the template option is saved to the user account variables using the user_save() function.

<?php
function _MYMODULE_callback_choose_profile_theme_form($form_state, $user, $profileTemplates) {

 
$form = array();
 
 
// add a select input element
 
$form['profileTemplate'] = array(
   
'#type' => 'select',
   
'#title' => t('Profile Template'),
   
'#options' => $profileTemplates,
   
'#default_value' => $GLOBALS['user']->profileTemplate
 
);
 
 
// add a submit button
 
$form['submit'] = array(
   
'#type' => 'submit',
   
'#value' => t('Submit')
  );
 
 
// add hidden element for userID
 
$form['userID'] = array(
   
'#type' => 'hidden',
   
'#value' => $user->uid
 
);
 
  return
$form;
}

function
_MYMODULE_callback_choose_profile_theme_form_validate($form, &$form_state) {
 
// TODO: add your additional form validation here
 
  // ensure userID submitted matches current user
 
if ($form_state['values']['userID']!=$GLOBALS['user']->uid) {
   
form_set_error('', t('Error processing form.')); 
  }
 
}

function
_MYMODULE_callback_choose_profile_theme_form_submit($form, &$form_state) {

 
// load user object
 
$user = user_load($form_state['values']['userID']);
 
 
// save profile template to user variables
 
user_save($user, array('profileTemplate' => $form_state['values']['profileTemplate']));
 
 
// set a message
 
drupal_set_message('Your profile template has been set.');
 
}
?>

user profile form

Last, I defined the preprocess function to see if a template has been set in the user variables, and add the templates suggestion to change the user profile template.

<?php
function MYMODULE_preprocess_user_profile(&$variables) {

 
// ensure the template file exists, and is set in the user object
 
if (file_exists(path_to_theme() . '/' . $variables['user']->profileTemplate . '.tpl.php') && $variables['user']->profileTemplate) {

   
// set a templates suggestion
   
$variables['template_files'][] = $variables['user']->profileTemplate;
  }
 
}
?>

As you can see below, when I choose the "Version 2" template option, the file "user-profile-version-2.tpl.php" is being loaded, and the text "Version 2" is displayed at the top of the page.

user profile selected

Template files inside module directory

Hi Eric, in this article you copied the template files inside the theme directory. Do you think it is possible to put them inside the module directory instead? I've been trying to do that but my template file inside the module directory is not read. I know it is a 'candidate', using the Devel module, but at the end the default user-profile template is used.

Thank you!

I sure could use some further clarification...

Thank you so much for sharing your ideas and great functionality here. I was soooo impressed to see this writeup that I tried it right away, but I think I must have gotten lost along the way, as it did not work for me.

I made the two new versions of user files. Then I copied all of your code into a mod file called my_mod.mod. I know that I must obviously missing something really smart because positively nothing happened.

Could you please - kindly - elaborate a bit further for those of us who only wish we were coders??? Thank you sooo much :-)

AB

Eric.London's picture

module

Hi AB,

Let me know how far you got with this functionality. Were you able to create a working module, set permissions, and get to the new tab to choose a profile theme?

Regards,
Eric

Thank you

Hi itry to integrate your module to my website.

but i don't know in witch page you put

1- the page callback to create a list of available templates for the user to choose from

2- The following functions define the form array

3- the preprocess function to see if a template has been set in the user variables

Could you help me :-)

I just create a folder .module and .info. I put the perm fonction in the file .module

but i don't know where i have to put this tree part of code :-(

Rank