One of my Community Server projects is very User Points-centric. More of my clients are asking for integrated points-based functionality in their communities, and I am starting to see how a rich points API would add a lot of value to Community Server. I know there’s been more work done on Points in CS2008.5 by the smart guys on the CS Core Team, and I’m looking forward to building cool features on it. But there’s one small item still missing in Community Server CS2008.5 that would make a lot of peoples’ lives a bit brighter: a SortBy=”Points” QueryOverrides property option for the UserList control.
I needed to generate a UserList sorted by points this week. It was one of those things you think is Community Server Cake until you discover it’s an afternoon. I didn’t tell my client it would be cake as I often mistakenly do, so I was in the clear.
After discovering there was indeed no SortBy.Points option, I figured I had two roads I could take with this. 1) Generate a DBVTUser Chameleon control set with my CodeSmith templates (DBVTUserData, DBVTUserList, etc.) with the DBVTUserList’s DataSource being a point-sorted UserSet from a single SQL Data Provider call, or 2) take the opportunity to explore “the Community Server Way.” And when I say “opportunity,” I really mean it. Option #1 would have been quicker, but walking through the CS source in #2 is always more enlightening.
The Chameleon HTML would have been similar whether I chose path #1 or #2, but getting there was the fun.
I won’t bore you with the details of the journey, but scenic points along the way included custom UserQuery, UserQueryType, and UserSorter objects, as well as a Points-enhanced users.Filter() method.
This is what we’re after in the UserList DataSource, an attractive, ample-breasted UserSet of Active Users and filtered by a new Points-aware QueryType object. We couldn’t interject a simple DBVTSortBy.Points here because CommunityServer.UserQuery is the baseQuery of the UserList’s UserQuery. A CS.UserQuery.SortBy = this.DBVTSortBy wouldn’t cut object casting muster. That’s okay. UserQueryType can do the job.
We need to pass our UserSet to our local equivalent of CommunityServer.UserSorter, but we need to filter it along the way mostly to add paging goodness.
The fact that the User object contains a Points property makes it easy to modify a custom CommunityServer.UserSorter class to compare users by their Points property.
I like simple, and this solution, though it works great, ain’t it. Perhaps someone smarter than me can bring to light some detour I followed or a course I hadn’t considered for simplicity sake. I don’t know though. Some things in Community Server are just fricken’ hard.