Last updated October 19, 2015. Created on April 7, 2014.
Edited by hansfn, drupaledmonk, awasson. Log in to edit this page.

Drupal's user profile page or user's account page in its OEM form seems somewhat bland when compared with the rest of Drupal and it also seems a bit limited when compared to the theming capabilities that are available for the majority of a Drupal sites pages and content. This article discusses techniques that can be used to improve the customization options for developers/themers to personalize user profile pages without writing reams of spaghetti code; in particular when Drupal is used with CiviCRM.

This page is in no way the complete and definitive method for customizing the user profile so please correct, update and add to it as required : )

Custom user-profile.tpl.php

If you want to make a lot of changes to the Drupal user profile page, you'll want to customize the user template page by copying the existing one at /modules/user/user-profile.tpl.php to your theme to customize it to your liking. I like to use the $user_profile or the global $user object in keeping with OOP techniques and render the fields that I need to use where I want to use them. As you add custom profile fields to your site, they will become available in the $user_profile array and rather than just rendering the complete array, you can choose what fields to place where. More information about the user profile template with a discussion about customizing it can be found here:!user!user-profile.tpl.php/7

Using CiviCRM Custom Data Profiles

If your Drupal website is integrated with CiviCRM, you have an opportunity to bring much more personalized content into the Drupal user profile page through CiviCRM's Contact Record Fields. The most straight forward way to bring CiviCRM contact record data to the Drupal user profile page is by configuring the appropriate CiviCRM Custom Data Profiles to be visible in the Drupal user profile page. This can be done by being logged in with permissions to administer CiviCRM, navigating to CiviCRM -> Administer -> Custom Data and Screens -> Profiles. Edit the Profile you would like to expose in the user profile page and adjust the setting for it to be used for: View/Edit Drupal User Account. You can also use these settings to remove CiviCRM content from the Drupal user profile page by un-setting it to be used for the Drupal User Account.

Custom Code

In order to take your Drupal user profile page to the next level, you'll want to get into a little custom coding. There are many ways to go about customizing a user profile with custom code. This article will present a method where the developer/themer will create a custom module to access the CiviCRM Contact Record fields and then expose them to the user-profile.tpl.php through the global variable. This will enable the developer/themer to add CiviCRM data to the user profile page in a clear and succinct manner, keeping the user profile template clean and easy to understand.

Acquiring CiviCRM Contact Record Fields

The first thing we need to do is create a module that will connect to CiviCRM and expose the data we're looking for. The following is a brief description of just such a module built according to the current CiviCRM V3 API. We'll call the module civicrm_custom_user_profile and all of the files will be in a directory called: civicrm_custom_user_profile
Every module needs an info file so create a file called as follows and place it into the civicrm_custom_user_profile directory. Our module will require CiviCRM to be active so we add dependencies[] = civicrm. This means that the module will not be able to be installed without CiviCRM being present.

name = CiviCRM Custom User Profile
description = Exposes CiviCRM Contact Record Fields to the Drupal User Profile Page.
core = 7.x
package = Custom
dependencies[] = civicrm

Our module is quite simple and all it needs to do is figure out who's profile page we're looking at, ask CiviCRM for the Contact Record fields and then expose those fields so that we can use them.

The first thing I want to do is change the title of the user profile page. By default, Drupal will provide a title for the profile page that consists of just the user name by itself. I would rather it said something a little more intuitive like my organizations name and something about it being a profile page so that new users get a feel for what the page is for. We'll do that with the following file that will be saved as civicrm_custom_user_profile.module

Note: I've borrowed the code for the civicrm_custom_user_profile_get_contact() function from a module called the CiviCRM Realname module which can be found here:


* Retrieves a CiviCRM contact by Drupal user ID.
function civicrm_custom_user_profile_get_contact($uid) {
  $contacts = &drupal_static(__FUNCTION__);
  if (isset($contacts[$uid])) {
    return $contacts[$uid];
  if (!isset($contacts)) {
    $contacts = array();
  $contacts[$uid] = FALSE;
  require_once 'api/api.php';
  $res = civicrm_api('uf_match', 'get', array('uf_id' => $uid, 'version' => 3));
  if ($res['is_error'] || empty($res['id']) || empty($res['values'][$res['id']])) {
    return FALSE;
  $id = $res['values'][$res['id']]['contact_id'];
  $res = civicrm_api('contact', 'get', array('contact_id' => $id, 'version' => 3));
  if ($res['is_error']) {
    return FALSE;
  $contacts[$uid] = $res['values'][$res['id']];
  return $contacts[$uid];

* Implements hook_user_view().
* We'll modify the title on the user profile
* and add a global $civi_user variable that we can
* expose in the profile page template
function civicrm_custom_user_profile_user_view($account, $view_mode, $langcode) {
  global $civi_user;
  $user = user_load(arg(1));
  $uid = $user->uid;
  $civi_user = civicrm_custom_user_profile_get_contact($uid);

  if ($civi_user['display_name']) {
    drupal_set_title('My Organization Profile - ' . $civi_user['display_name']);

When added to a Drupal CiviCRM website, the module described above will change the Drupal user profile page title from the plain username to "My Organization User Profile - display_name". In the case of my user profile it would change from the plain: awasson to: My Organization User Profile - Andrew Wasson

Exposing CiviCRM Fields in the Profile Page

In the custom module described above we also added a global variable called $civi_user that can be invoked within the user-profile.tpl.php file to expose all of the available CiviCRM Contact Record fields.

In order to get an idea of what CiviCRM Contact Record fields are available in the user profile page, you can install the Devel module ( or you can recursively print $civi_user to the page with the following couple of lines of code within the user-profile.tpl.php file:


 global $civi_user;
 print '<pre>';
 print '</pre>';


Using the module described above the developer/themer can ignore the way the existing template file renders Drupal and CiviCRM fields and instead use the global $civi_user variable along with Drupal's $user_profile variable to render or print the fields any way they choose.

Feel free to update and improve this page as necessary.

Looking for support? Visit the forums, or join #drupal-support in IRC.


sonicthoughts’s picture

A new module CiviCRM Entity is a great way to enhance Drupal integration. Rather than code, you can use rules or other Drupal entity tools (Like EVA, Bean, etc.) and grab the data you want. Soon you can work with Civicrm entities directly.

bsetzer’s picture

Good stuff - thanks!

Can this custom module be used to expose the CiviCRM Fields in other places on the site? For example, if I want to create a custom welcome block that outputs the Civi display name (i.e. Welcome, John Doe), is the global civi_user available?

Thanks much!

awasson’s picture

@bsetzer, you can definitely pull the $civi_user info into other pages of the site. You could extend the module code I stubbed out in the article to create a block and then place the block in the desired region. You'll want to run a conditional to make sure there is something to display but it should be a pretty simple addition to the code to do so.

All you need is hook_block() and the global $civi_user;

Andrew (awasson)