How to create an Alumni directory
I have been involved with creating several Drupal-based alumni websites. One of the most requested feature, by clients, is an alumni directory; a tabular listing of all registered alumni with links to the alumni's profile(s).
Below is a basic how to implemented an alumni directory using contributed modules. This howto is based on Drupal 5.x, however, you can use the same approach with Drupal 4.7.x.
I hope this is helpful for others who are building Drupal-based alumni websites.
Modules used
• Profile (part of core)
• Usernode
• Views
Putting it all together
Profile Module
The profile module, which is part of Drupal core, should be enabled to allow you to define custom fields (e.g., Year of Graduation, First Name, Last Name, etc...). These custom fields are then used as part of the site's registration process and ultimately used for the alumni directory. More information about extending user account information can be found at http://drupal.org/handbook/modules/profile/
The custom fields that I have created for several sites are shown in the screenshot below.
Profile Fields

As you can see in the above screenshot there are several custom fields that have been created, you may not need to create the same exact fields, as your project's needs may vary. The custom fields that will be used in the alumni directory are:
• Graduation Year (profile_grad_year);
• First Name (profile_first_name);
• Last Name (profile_last_name);
and
• Maiden Name (profile_maiden_name)
Each of the custom fields above has a "field type" which defines what type of form the user will interact with (e.g., single-line textfield and list selection). As for the Graduation Year field, I created a selection list "field type" which creates a drop down list of the graduation years to choose from. It is very simple to add additional years when needed. The first, last, and maiden names "field types" are single-line textfields. All the above custom fields, with the exception of Maiden Name, are required fields to be filled out by the alumni during the registration process.
Graduation Year field type

Another field that will be shown in the alumni directory, username, will be covered later when we get into the Views module. The benefit of adding the username field to the alumni directory is that it will provide a link to the alumni's profile.
Now that the custom fields have been created, it's time to move on to the Usernode module.
Usernode Module
Usernode creates a content page for each user. The usernode is automatically created with the user account. One of the great benefits of using the Usernode module is that Usernodes can be used in user listings with the views module; it makes available the custom fields, created by the profile module, to the Views module.
Enabling the Usernode module is all that needs to be done. There is no additional configuration needed for Usernode.
Views Module
Views is a powerful query builder for Drupal that allows you to fetch and present lists of content (posts/nodes) to the user in ways that are tailored to your site and your content.
Using Views, an administrator can create pages and blocks that list new posts of a particular type (such as forum or blog posts), create alphabetical lists by taxonomy, create weekly, monthly or yearly archive pages, create a table of posts that are flagged as unread, and much much more!
I must say, this module kicks ass. A mighty big thanks to Earl Miles (merlinofchaos) for this module. Views surely is a piece of art.
If you're not familiar with the Views module I strongly suggest that you spend some time to get to know Views, it will make you a happier Drupaler.
The Views documentation can be found at http://drupal.org/node/109604
First, you'll need to enable the Views module. You should also enable the Views UI which allows you to create and edit views. Once the module(s) have been enabled you can create a new view.
To create and administer Views, navigate to admin/build/views (Drupal 5.x), here you will be presented with a list of "Default Views" - system default views.
Creating a new view
The following steps are how you'll create the alumni directory view.
Basic Information
1) Click on the "Add" button/link (admin/build/views/add)
2) Give the view a name: alumni_directory
3) Assign who has access to the view. If you assign access to anonymous users, anyone who visits the site will be able to view the alumni directory. However, anonymous users will not be able to view the individual profiles of alumni unless you allow access to users' profiles in the "Access control" section. I usually do not allow anonymous users to access users' profiles and restrict access to profiles only to authenticated user (registered alumni).
4) Description. Give the view a description (e.g., Alumni Directory).
Page
The alumni directory view will be provided as a page.
5) Check "Provide Page View";
6) URL of the alumni directory = alumni-directory;
7) View Type is a "Table View";
8) Title. This is the title that will be shown at the top of the view (page) = Alumni Directory;
9) Check "Use Pager" so that the alumni directory will be pagenated;
10) Nodes per Page. How many alumni do you want to show per page?
11) Header. This will be shown at the top of the alumni directory. I usually put a message about the alumni directory and a link to the registration page for those who are not yet registered;
12) Footer. This will be shown at the bottom of the alumni directory;
13) Empty Text. This is where you can put text to display if a view returns no nodes;
14) Input format = Filtered HTML;
Fields
Skip down to the "Fields" section.
Here at the fields section is where you define what fields you want the ("Table View") view to display.
15) Add Field. Select the "Usernode: Name" field. This is the username link that was mentioned earlier. This will provide a direct link to the alumni's profile;
15b) Label. What is the name you want to give this filed? = "Username";
15c) Handler. Select the "themed userlink" option. This will make the username a link to the alumni's profile;
15d) Sortable. If you'd like to make the usernames' sortable, than choose "Yes";
15e) Default Sort = None;
16) Add Field. Select the "Profile: Graduation Year". This is the custom field (profile_grad_year) that was created using the profile module as mentioned in the "Profile Module" section above;
16b) Label. What is the name you want to give this filed? = "Class";
16c) Sortable = Yes;
16d) Default Sort = Ascending. This will sort the alumni directory by class year in ascending order;
17) Add Field. "Profile: First Name". Again, this is the custom field (profile_first_name) that was created using the profile module as mentioned in the "Profile Module" section above;
17b) Label = "First Name";
17c) Sortable = Yes;
17d) Default Sort = None;
18) Add Field. "Profile: Last Name" - this is the custom field (profile_last_name);
18b) Label = "Last Name";
18c) Sortable = Yes;
18d) Default Sort = None;
19) Add Field. Select the "Profile: Maiden Name" - this is the custom field (profile_maiden_name);
19b) Label = "Maiden Name";
19c) Sortable = Yes;
19d) Default Sort = None;
Views Field

Filter
Skip down to the "Filters" section.
Here at the filter section is where you define how you want to filter the view. I created three filters that will filter the view so that only active alumni are listed, therefore filtering out any alumni that are either pending registration approval or blocked from access to the site.
The second filter that I created displays alumni who are registered with the site and are part of a graduation class. In other words, I'm filtering out non-alumni users from the alumni directory (e.g., site ops, administrators, etc).
The third filter is filtering by role. I only want members of the "alumni" role to be in my alumni directory. This third filter is a little over kill, but it gets the job done.
20) Add Filter. Select the "Usernode: Active" field;
20b) Operator. Select the "Is Equal To" operator;
20c) Value. Select the "active" value;
21) Add Filter. Select the "Profile: Graduation Year" field;
21b) Operator. Select the "Is One Of" operator;
21c) Value. Multiple select all the years.
Views Filter

Exposed Filers
To view by a individual class, I created a "Exposed Filter" which will allow visitors to select, from a drop down list, a specific class to view.
To create a selection list of classes, you'll need to create an "exposed filter" as follows:
22) Back in the "Filters" section click on the "Expose" button for the "Profile: Graduation Year". In the "Exposed Filters" section, you should now see the newly created exposed filter for the profile "Graduation Year".
22b) In the "exposed Filters" section, give the exposed filter a "Label" - I labeled my exposed filter "Select a Class to view";
22c) Check the "Optional", "Force Single", and "Lock Operator" boxes

At this point it's now time to save the view by clicking the "Save" button.
You will then be redirected back to the Views administration page and you should now see the newly created alumni directory view in the "Existing Views" list.
You can go to the alumni directory by clicking on the URL link (for the alumni directory view). If all went well you should be brought to the alumni directory.
The Alumni Directory

Attached is the exported view of the alumni directory that I created.
| Attachment | Size |
|---|---|
| alumni-directory-view.txt | 4.01 KB |

very helpful
thank you very much.
this is a really good tutorial
Alumni Mailing Address Listing Using Views - 6.10
I have been tearing a lot of hair out trying to get an alumni website going. After six weeks, I've learned a lot. Here's something that you may want to do -- print a list of alumni mailing addresses. This is printing to the screen.
I am assuming that you've played around some with views and attempted/succeeded doing some things with that module.
How do you get the data output like this:
Al Alumni
123 Awesome Way
Auburn, AL 00000
Colleen Cheerleader
456 Cul-de-sac Court
Cryptonite, CA 00000
Here's how:
Administer » Site building » Views
Add tab
View name: I called mine "mailing_list" -- this is the machine readable alpha and underscore stuff.
View description: Alumni Mailing List (or whatever is descriptive to you -- this appears on the Views main page in the view listings.
View tag: I don't have enough views to have to worry about finding them by tag (yet).
View type: User (I cannot tell you how hard I was trying to make "Node" work in this situation. BTW, it doesn't :-)
Click Next
Name: Defaults
Title: Mailing Address Listing
Style: Unformatted
Row style: Fields
Use AJAX: No
Use pager: Yes
Items per page: 25 (You may want fewer or more alumni addresses to appear.
More link: No
Distinct: No
Access: Class Representative
Exposed form in block: No
Header: None
Footer: None
Empty text: None
Theme: Information
Relationships
None defined
Arguments
None defined
********* Here's the place to format the output -- you might have differently named fields for these ********
My fields are as follows:
Profile: First Name
Profile: Last Name
Profile: Address 1
Profile: Address 2
Profile: City
Profile: State
Profile: Zip Code
To add these fields and format them properly,
click on the plus (+) in the Fields area.
Under Groups, select Profile to see only the profile fields.
Select Profile: First Name
Click the Add button
Label: DELETE THE LABEL for every field -- you do not want a label showing.
Exclude from display -- CHECK THIS -- you'll see why in a moment. Note that it excludes the field from display but still loads it for use.
Click the Update button.
Click the + to add another field.
Under Groups, select Profile to see only the profile fields.
Select Profile: Last Name
Click the Add button
Label: DELETE from each field created.
DIFFERENT from First name!
Rewrite the output of this field -- CHECK THIS
A Text box opens.
Look down below the text box for this:
Replacement patterns
The following substitution patterns are available for this display. Use the pattern shown on the left to display the value indicated on the right. Note that due to rendering order, you cannot use fields that come after this field; if you need a field not listed here, rearrange your fields.
Fields
This is the information you need to align your full name line of the address :-) Note that your value labels may be numbered differently. Just make sure to use the correct one for the field you want.
In the Text box, enter:
[value] [value_1]<br>(there's a space between the values -- the<br>causes a break to the next line.The result of this is a properly aligned name on its own line.
SO, for every line you want in your address list, you want to first add all the fields for that line, excluding all but the last field on the line from being displayed. It's in the last field where you will see all the previous fields' replacement values.
CONTINUING --
Click the Update button.
Click the + to add another field.
For the street address line(s), you can just add the field(s) without checking any of the boxes.
The cool thing about this is that if a field is empty, it will not cause a blank line.
Add fields for City and State -- Exclude them from Display.
Add field for Zip
Click "Rewrite the output of this field."
The replacement values are [value_4], [value_5] and [value_6].
So, in the Text box, I enter:
[value_4], [value_5] [value_6]<br><br>The double break is to put a blank line between different user addresses. If you put the zip on a separate line from the City and State fields, you'd probably still want to rewrite the output to get the double break:
[value_6]<br><br>. And in that case, you'd not have a double break after the City, State fields.There are probably still some things to do: Set sort criteria and filter your results.
Sort criteria -- click the +
Add Profile: Last Name asc -- or however you want the sort. You might want to sort by zip code if you want to copy the list to mailing labels.
For filters, I wanted to exclude Unregistered, Missing or Deceased alumni (our Class Reps "register" everyone in the class on the site, but we have checkboxes for these special circumstances so we can do filtering like this).
I also wanted to exclude addresses that do not have the street address line. So I filter for addresses that are not = to blank.
Finally, I want the graduation year exposed so a Class Rep can filter just for his/her class.
Filters -- click the +
Profile: Deceased False
Profile: Missing False
Profile: Address 1 !=
Profile: Graduation Year exposed
This is written to thank the many people who posted what some might consider "simpleton" explanations. I needed (and still need) those explanations and want to try to add to them.
If you know a good way to export this view to a file for importing into labeling/word processing software, please let me know. CVS module would work if it would do bulk export.
Bobby de Composer
why enable the usernode module?
I don't see what difference it makes.
okay. it creates a node for each user which is blank. if you click on the title it links to the user's profile.
okay. you are using that to create a view. it's step 20.
Usernode makes available the custom fields
Usernode makes available the custom fields, created by the profile module, to the Views module. Without usernode, you would not be able to create a view using the custom profile fields (e.g Profile: Graduation Year - profile_grad_year). Usernode creates users nodes (users as nodes) which can be accessed by the views module.
Steps 15 - 19d (Fields) is where you define what fields you want the view to display (Class, First Name, Last Name, etc).
Step 20 - 22b (Filters) is where you define how you want to filter the view (e.g. display only class members who are active)
views on a class by class basis
You can also create views on a class by class basis. Say if you want to break up the alumni directory into classes, you can create a view for each class and filter the view to only display one class. This is very useful if your dealing with a school alumni site that contains all graduating classes.
View is empty
For some reason my view only shows the usernames - the other columns are empty. I tried to follow the instructions, but I'm stumped.
Also, I noticed that I could not get the Profile fields to show up in the 'fields' drop down until I enabled the View modules before enabling usernode. The first time, i tried enabling them both at the same time, but none of the profile fields were available.
Resubmit the custom profile info
With Drupal 5.x, in order for the user to show up in the alumni directory (view), you'll need to goto the custom profile section for the user (within the user's account settings) and click on the "submit" button; essentially resubmitting the user's info.
This isn't the case with Drupal 4.7.x. Users are automagically added to the view without having to resubmit their custom profile info.
This is a slight flaw in the newer (5.x) version of the usernode module.
Perhaps I should file a bug report with the maintainer of Usernode.
Does anyone know how to fix this?
Does anyone know how to fix this?
I'm building an alumni Web site, and I'm having the same problem. Nothing shows in the Views until someone resubmits his user info.
Knowing my audience, I know they won't bother. So a fix would be really nice.
Solved
OK - Figured it out.
The problem is with the profile module, not with Usernode.
You'll find a patch to solve this problem here.
Brilliant!
Thanks for tracking this down. The patch works like a charm.
Profile module fixed with Drupal 5.2
The profile module has been fixed as of Drupal 5.2 and no longer has this problem. :)
Input format for multi-line text fields?
I have a situation just like this, but I am running into a problem with Input Formats for multi-line text fields. I have a biography field, like your "Tell Us About You" field. When the user uses any html markup fields (mostly Italics markup), it gets escaped on output and shows the html markup in the output. Any way to tell views how to treat the content in the views fields?
Customising the user profile layout
What I've done is created a custom user profile layout and added to my custom layout:
<?php print check_markup($user->profile_about_you) ?>This will convert the markup.
Read more about:
Customizing the user profile layout
and
Handling multi-line profile fields
Views without Profiles, and multiple entries - question
Two questions:
can a View use field names not derived from the Profile?
My Views module snarfs up Profile fields nicely, but I want a directory without giving everyone listed on it a user account.
Is it a matter of creating custom content and (somehow) getting that content to show up in the pop-up box in View>Fields ?
I made a test Page View for a directory page; right now I'm the only listed person (it uses my Profile).
I'm listed five times (5 nodes per page).
Anyone seen this? I'm not sure what to call this so not sure how to search for information about it. Is it a case of not ticking the right box, or a bug, or a feature?
TIA for anyone's time.
CCK is your friend
You could create a custom content, alumni profile, which you can then use to create the alumni directory. Obviously, you would filter the fields of the custom content type (in views) instead of filtering the profile_fields (created by the profile module).
I don't know why you are having the above-mentioned problem of being listed five times. Perhaps you should double check your filters to make sure there isn't any redundancy.
Search/browse by years
One question:
How can I make an easy search or browse by Year of Graduation?
In Profiles I have profile_grad_year
but in Views I see no way I can make it clickable, so when I user clicks on the Graduation year the list is sorted.
Any ideas?
Updated HowTo - Exposed Filters added
I have updated the HowTo above to include the "exposed filter" which allows you to view by class.
Usernode and View?
I am using Drupal 5.1 and I cannot for the life of me find or locate the usernode or views module?
Any help would be greatly appreciated.
Oooop's nevermind ... I just saw where these modules must be downloaded.
Change Username to Real Name?
Is there a way to convert a users "username" to their "real name" on their profile and in the memberslist?
Any help would be greatly appreciated.
Override the theme function theme_username
By adding the following to your theme's template.php file (create a template.php if your theme does not have), overriding the theme function theme_username, you can have full names instead of usernames displayed (e.g., a list of "New Members" in a block).
<?php
/**
* profile first and last display instead of username
*/
function phptemplate_username($object, $link = TRUE) {
if ( !$object->profile_first_name ) {
if ( $object->uid && function_exists('profile_load_profile') ) {
profile_load_profile($object);
}
}
if ( $object->profile_first_name ) {
$name = $object->profile_first_name . " " . $object->profile_last_name;
if ( $link && user_access('access user profiles')) {
return l($name, 'user/'. $object->uid, array('title' => t('View user profile.')));
}
else {
return check_plain($name);
}
}
// Profile field not set, default to standard behavior
if ($object->uid && $object->name) {
// Shorten the name when it is too long or it will break many tables.
if (drupal_strlen($object->name) > 20) {
$name = drupal_substr($object->name, 0, 15) .'...';
}
else {
$name = $object->name;
}
if ( $link && user_access('access user profiles')) {
$output = l($name, 'user/'. $object->uid, array('title' => t('View user profile.')));
}
else {
$output = check_plain($name);
}
}
else if ($object->name) {
if ($object->homepage) {
$output = l($object->name, $object->homepage);
}
else {
$output = check_plain($object->name);
}
$output .= ' ('. t('not verified') .')';
}
else {
$output = variable_get('anonymous', 'Anonymous');
}
return $output;
}
?>
Civicrm Profiles
I have Civicrm 1.7 runing on Drupal 4.7. I have civicrm profiles Personal, Alumni and Group. Is it possible to use Civicrm profiles to create a Alumni Directory above.
Thanks
Great How To...!!!
I have spent a while figuring how to create a list of participants with the views. Without the usernode module I was getting a list of posts by participants.
I followed your how-to and has worked wonderfully. Thanks!
Dynamic filters
Is it possible to for the Graduating Year filter only show those options which actually exist? For example, if only alumni from 1970, 1972, 2000, 2004 have joined the site, can the Graduating Year filter be made to only show those years? But as soon as someone joins from 1985, the filter also automagically shows 1985?
Anybody know how to do this?
How can I have the Class
How can I have the Class view default to the user's graduating class? Right now it just shows everyone in the directory.
Multiple entries - question revisited
I have encountered a similar phenomenon as meles. In the directory table, each username appears eight times.
The displayed columns in the table (after username) are first_name (1), last_name (2), and maiden_name (3). Each of the eight rows shows a combination of fields either filled in with correct data or left blank, in this pattern:
Row 1: All 3 columns blank
Row 2: Column 3 filled in
Row 3: Column 2 filled in
Row 4: Cols. 2 and 3 filled in
Row 5: Column 1 filled in
Row 6: Cols. 1 and 3 filled in
Row 7: Cols. 1 and 2 filled in
Row 8: All 3 columns filled in
And the cycle repeats for each succeeding username.
I've followed Jay's magnificent example, using the same fields in my view. Filters are "Usernode:Active is equal to Active" and "Usernode:Role is one of Alumnus."
Anyone with any ideas on how to get only Row 8?
multiple entries - same issue
This is a fairly old thread, but I'm having the same issue with usernode and views. Each field added to the view from the "profile" (but not those added from the usernode) results in the user showing up in the list or table an additional time. Data behavior follows the same pattern as mpeal above. The problem seems to be merging data from the usernode with data from the profile, but I'm unsure how to address it.
Running drupal 5.11 and usernode 5.x-1.4.
Any thoughts?
Getting Errors
I've followed the procedure to create an alumni directory view, but having some issues.
I'm getting this error when I click on the alumni-directory URL in Site Building - Views
* user warning: The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET SQL_MAX_JOIN_SIZE=# if the SELECT is okay query: SELECT count(node.nid) FROM node node INNER JOIN usernode usernode ON node.nid = usernode.nid LEFT JOIN users usernode_users ON usernode.uid = usernode_users.uid INNER JOIN users users ON node.uid = users.uid LEFT JOIN profile_values profile_class_of ON users.uid = profile_class_of.uid AND profile_class_of.fid = '1' LEFT JOIN profile_values profile_first_name ON users.uid = profile_first_name.uid AND profile_first_name.fid = '2' LEFT JOIN profile_values profile_last_name ON users.uid = profile_last_name.uid AND profile_last_name.fid = '3' LEFT JOIN profile_values profile_current_name ON users.uid = profile_current_name.uid AND profile_current_name.fid = '4' WHERE (usernode_users.status = '1') in /home/waynealu/public_html/cms/includes/database.mysql.inc on line 172.* user warning: The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET SQL_MAX_JOIN_SIZE=# if the SELECT is okay query: SELECT node.nid, usernode_users.name AS usernode_users_name, usernode_users.uid AS usernode_users_uid, profile_class_of.value AS profile_class_of_value, profile_first_name.value AS profile_first_name_value, profile_last_name.value AS profile_last_name_value, profile_current_name.value AS profile_current_name_value FROM node node INNER JOIN usernode usernode ON node.nid = usernode.nid LEFT JOIN users usernode_users ON usernode.uid = usernode_users.uid INNER JOIN users users ON node.uid = users.uid LEFT JOIN profile_values profile_class_of ON users.uid = profile_class_of.uid AND profile_class_of.fid = '1' LEFT JOIN profile_values profile_first_name ON users.uid = profile_first_name.uid AND profile_first_name.fid = '2' LEFT JOIN profile_values profile_last_name ON users.uid = profile_last_name.uid AND profile_last_name.fid = '3' LEFT JOIN profile_values profile_current_name ON users.uid = profile_current_name.uid AND profile_current_name.fid = '4' WHERE (usernode_users.status = '1') ORDER BY profile_class_of_value ASC LIMIT 0, 50 in /home/waynealu/public_html/cms/includes/database.mysql.inc on line 172.
Any ideas?
Brian
Update for Drupal 6.X
Is there any way to accomplish this in Drupal 6.X? It doesn't look like Usernode is available for current installations.
You don't need Usernode in D6
You don't need Usernode in D6. Views 2 can access the custom fields created by the profile module w/out Usernode.
Advance Profile Kit
I'm seriously looking at using the Advanced Profile Kit in place of the standard profile.
Question about "themed userlink" option
Hi,
As I've been going through the steps to create the Alumni Directory...once I got to the part about the "Handler"...I don't have a "themed userlink" option. Here are the choices that I am presented with:
Group Multiple Values
Do Not Group Multiple Values
Show first value only
Show last value only
Do you have a recommendation on what I can do to have the "themed userlink" as one of my options? I am using Drupal version 5.15.
Thank you very much for your time.
Sincerely,
Michael M.
Also have a question about "themed userlink" option...
I am also experiencing the missing option. Does anyone have any idea why it might be absent?