35 - An Alternate Staff Directory Using the ExpressionEngine Member Management Module

In the last post I outlined the advantages and disadvantages of building a church Staff Directory using either ExpressionEngine‘s built in Member Management Module or another weblog.  While I chose the weblog approach for my sample site, I thought I would build out an alternate version using the Member Management Approach in case that would also be valuable.

Download the EE Code for 35 - An Alternate Staff Directory Using the ExpressionEngine Member Management Module

Query Module Required
This build approach does require the query module, which is not available in the Core version of EE. 

Overall Build Approach
At a high level the build approach here is the same - I need to create structures to hold content, then do some content entry, then code some templates to draw that content out.  The difference with this approach is that the structures that hold the content are a new member group and some member profiles, vs. a weblog and weblog posts like in the previous build.

Create a New Member Group

I created a new member group called “Staff”.  I configured it such that the group would have access to the Control Panel (so that staffers would be able to login and maintain their profile via the “My Account” tab) but locked down everything else - no access to any other area.

When done creating your new member group - note it’s ID - the number can be found in the center column on the Member Group index page:

Admin ›  Members and Groups ›  Member Groups

In my case the ID for the new group is 8.  This will be important later on.

Created Custom Profile Field
I noted that the default profile fields don’t include one for a phone number, so I had to add a custom profile field. This can be done in the CP under:

Admin ›  Members and Groups ›  Custom Profile Fields

I added a field with the following name, display name, type, and formatting:
phone, Phone, Text Input, formatting=None

I also set “Visible in Registration Page” to Yes, so that when new staffers join the church they could use EE’s default new member registration page (see the docs for how to link to that registration form) and be able to fill in the phone number on it.

Member Image Configuration
I need two images for this design - a thumbnail for the index page and a bigger image for the profile page.  I decided to use EE’s avatar spot for the thumbnail, and the member photo for the larger one.  An alternative would be to use only the member photo, and then use the Image Sizer plugin for the smaller one.  Make sure both avatars and member photos are enabled, paths are correct, and size limits will work in the design.  These settings are configured under:

  • Admin ›  Members and Groups ›  Membership Preferences › Avatar Preferences
  • Admin ›  Members and Groups ›  Membership Preferences › Member Photo Preferences

Member Registration
I then registered Members into the New Staff Group using the Control Panel Form. Once the basics were in I edited each members profile to add their title (in the occupation field), bio, phone number fields, and both images.

Staff-Directory/Alternate-Index Template
As usual I’ll include the complete templates in the companion files - let’s just look at the core code here:

{exp:query sql="SELECT member_id FROM exp_members WHERE group_id = '8'"}
:member:custom_profile_data member_id="{member_id}"}
!--The switch variable handles applying the required different css to every other entry --}            
<div class="{switch="staffBorder rtMargin|staffBorder"}">
a href="{path='staff-directory/alternate-profile'}{member_id}/"><img src="{avatar_url}" width="{avatar_width}" height="{avatar_height}" alt="{screen_name}'s avatar" /></a>
h4><a href="{path='staff-directory/alternate-profile'}{member_id}/">{screen_name}</a></h4><br />
p>{phone}<br />
{email}<br /></p>

OK - so there are a couple of things new to this series going on here. 

Query Module
The first is the use of the Query Module.  The query module is handy for retrieving data from EE’s database when the built-in tags don’t do what you need.  You will need to know how to write SQL statements - which could be a whole series of tutorials in itself.  Here is where you will need the ID of the new member group you created earlier - place the group ID in the where clause of the SQL statement, in place of the 8 in the example.  This will limit the query to just find the member id’s for members in the new group - so just staffers.

Custom Profile Data Tag
The reason I needed the Query Module here was due to a limitation of the next tag - the Custom Profile Data tag.

The Custom Profile Data tag will accept a member_id as a parameter, but it’s not a looping tag.  I can’t even give it multiple member_id’s in a piped list (at least not according to the documentation).  So - In order to make a loop I nested the Custom Profile Data tag in the Query tag.  The Query tag provides the looping, and feeds the Custom Profile Data tag the member_id. 

Note that the switch variable is still available within the Query tag - handy here as the classes need to alternate to get our layout correct.

Now - on the single entry page showing the content for a specific member, I’ll also need to feed a member_id to the Custom Profile Data tag.  To do that I appended member_id to the end of the link.  This will put the member id in the URL, where on the single entry template I’ll be able to grab it using a segment variable.

Staff-Directory/Alternate-Profile Template
In this template the Custom Profile Data tag is used 3 times - once for the page title, once for the sidebar contact info, and once for the main content.  I’ll just cover the main content area tag pair below - so you can see how the segment variable comes into play:

<h2>Staff Profile</h2>
div class="content_page_right">
{exp:member:custom_profile_data member_id="{segment_3}"}
<div class="post">
img class="ministry_photo" src="{photo_url}" width="{photo_width}" height="{photo_height}" alt="{screen_name}'s photo" />    

Again - I forced the member_id into the link on the index template, so when one of those links is followed the member_id is put into the 3rd segment location in the URL.  That allows me, on this template, to now grab that value using a segment variable and feed it to the Custom Profile Data tag as a parameter.

Which is Better?
So having now seen how this version went together you might be asking which I think is better.  There isn’t honestly a clear answer - it’s going to depend on the larger picture of the specific site you are building.  This approach would put the ability and responsibility of profile maintenance on the shoulders of the staff members themselves (which may or may not be a good idea).  If these staffers are also posting blog entries or participating in the Forums then this content would also be easily usable in those contexts, so centralizing it would be nice.

But I do also lose a nice URL for the profile pages, having a member id rather than name.  I also lose the ability to easily tie together staff members with audio messages using weblog relationships—so I think for my project I still prefer the weblog-based approach.  However it was a nice challenge to also build it out this way for comparison and showing how to work with the query module for the times when the native EE tags don’t provide the content you need.



Category Navigation

<< Previous Entry   

Next Entry >>


Previous Comments

Picture of Kevin

by Kevin

Date: Sunday, January 18th, 2009
Comment: #1

According to your outline, I can’t figure out what is the next logical step?  More relationship fields? Contact embed additions? I believe in one of your earlier posts you wanted to fix something, but can’t remember what!

Looking forward to your next installment!

Mike Boyink

by Mike Boyink (Author)

Date: Sunday, January 18th, 2009
Comment: #2

Relationship field to connect audio messages to the Staff Directory, a Contact Form, and a Site Map are pretty much all thats left to do.

Picture of Kevin

by Kevin

Date: Tuesday, January 20th, 2009
Comment: #3

I found both paid and free ways EE can create a sitemap that is compatible with Google’s sitemap submission specifications. 

Is this sitemap going to be the type that notifies on updated pages (xml), or connected somehow to the navigation embeds, or will this be a simple, static sitemap?

Just wondering ... :)

Mike Boyink

by Mike Boyink (Author)

Date: Tuesday, January 20th, 2009
Comment: #4

Not a Google sitemap, just a human sitemap.

Picture of Mary Ellen

by Mary Ellen

Date: Tuesday, March 3rd, 2009
Comment: #5


Building the member module this way do you see a problem with allowing the cp url to be publicly available? Is that not why they change the system folder so no one can see it?

I need members to be able to register and access the cp to update their profiles should I be worried about linking to the cp login?

Mike Boyink

by Mike Boyink (Author)

Date: Tuesday, March 3rd, 2009
Comment: #6

I don’t worry about it - you’ll lock it down to just what they need to see.

You can also masc access to the CP if need be.

Picture of Doug

by Doug

Date: Monday, April 6th, 2009
Comment: #7

Is there a way to sort by name?  Right now it sorts by member ID.  I may have to use the weblog method to get the sorting and grouping I want (ie the ability to view all members in personnel, financial services, etc).

Mike Boyink

by Mike Boyink (Author)

Date: Monday, April 6th, 2009
Comment: #8

Sure…it’s all based on a query so you just need to look at an orderby clause to sort on name.

Picture of brandon

by brandon

Date: Monday, May 4th, 2009
Comment: #9

Hey Mike,
I would think being able to link articles to an author profile wouldn’t be trivial.

In this comment thread you’re linking to your author profile which I understand as you’re using the member module. I have two questions:

1) Are you using the query module or did you customize the admin template and simply link to it?

2) IF someone were to use the staff weblog approach how then would they relate authors to entries other than a custom relationship field?

Mike Boyink

by Mike Boyink (Author)

Date: Monday, May 4th, 2009
Comment: #10

Hi Brandon -

1. Here on Train-ee I’ve implemented the User Module from Solspace—so it’s handling the presentation of the profile page (in addition to the register/login areas etc).

2. I guess I don’t understand why you wouldn’t want to use a relationship field?  It’s native functionality and the perfect fit for the job.

Picture of brandon

by brandon

Date: Monday, May 4th, 2009
Comment: #11

1) I’ll have to take a look at the Solspace module- thanks for that information, I didn’t know about it. Seems there is a ‘mass’ of information to wade through to find the good stuff. I appreciate your site!

2) Well I was simply wanting to link the authors name of article entries to their profile, as well have a ‘staff directory’ which is cross linked to articles. I tried both setting up a weblog for the team, and the member directory module approach and have settled on the member directory approach because its integrated without the need of another select box when it comes to editing or adding new articles. I guess both are good but the member module seems to take out an additional step for wanting to ease administration.

I prefer the weblog approach though since it has friendly urls. If there were a way to relate automatically from an authors weblog to an articles weblog, that would be a perfect scenario. I’m a little dissapointed at this part of the member management module, but its still very nice and I won’t complain ;)

Here’s the site I’ve been working on: www.lifecatalystconsulting.com

Mike Boyink

by Mike Boyink (Author)

Date: Monday, May 4th, 2009
Comment: #12

Hey Brandon—

To go the weblog approach you’d have to add a field to choose the author one way or the other.

If these people are actually writing these articles (as opposed to sending them to an admin for posting them to the site) then I’d use the built in Member Module as that’s exactly what it’s designed to do.

The User module really takes all the pain out of dealing with styling it, etc - well worth the price.

Picture of brandon

by brandon

Date: Monday, May 4th, 2009
Comment: #13

Cool that makes sense, I guess it really comes down to what the desired process for administrating the site is, makes great sense. I appreciate your help and input.

Picture of John Knotts

by John Knotts

Date: Wednesday, June 10th, 2009
Comment: #14

This post was the perfect solution for what I was trying to do!  Thanks so much!

Picture of Casey

by Casey

Date: Wednesday, June 17th, 2009
Comment: #15

Thanks for this. I was actually building a church site which needed this exact functionality. At first, I was a little peeved at how the members module had left so much to be desired (in terms of frontend display), but this article came at perfect timing. FWIW, The reason I chose to go with this method instead of just creating a “Staff Weblog” is because the staff of this particular church website need to be able to not only maintain their profiles but manage other weblogs for their specific groups. This allows me to better organize personnel with content control in one shot.

Mike Boyink

by Mike Boyink (Author)

Date: Thursday, July 2nd, 2009
Comment: #16

Hey Jan—

I haven’t seen that happen. It sounds like a good tech support request.

Picture of parsoncraig

by parsoncraig

Date: Friday, October 16th, 2009
Comment: #17

Don’t you have to have at least two groups: one for the staff and one for the Super Admins?  If so, how would the query change? 

{exp:query sql=“SELECT member_id FROM exp_members WHERE group_id = ‘8’” OR “1”}

Mike Boyink

by Mike Boyink (Author)

Date: Friday, October 16th, 2009
Comment: #18

Well, no - I don’t *have* to have two groups.  This is for a completely imaginary church you know..;)

It could be that the superadmin account isn’t held by a staffer.

Regardless - if you need to pull more than one group then yes the SQL statement would be different.  You’ll have to experiment but I’d expect the where clause to be something like

WHERE (group_id "8") OR (group_id="1"


Might need the table name along with the field name.

Add Your Comment

Commenting is not available in this channel entry.

Unless otherwise stated all content is © Michael Boyink of Train-ee.com & Boyink Interactive. Please don't steal - I've got kids to feed...