User Panels - A Proposal

User Panels shoots pretty high: it aims to provide a consistent, easy platform for the handling of user-centric information display. It's not about new storage mechanisms or anything like that - just about marshaling all that user content together in a sane, easy-to-use way. I'm hoping that this blog post can be a semi-official shout-out to the drupal community - an RFC, I guess.

user_panels comes out of a basic observation about Drupal: virtually every Drupal site has a different conceptualization of who users are, what their role is within the site, how they should be interacting with one another, etc. This observation helps explain why it's been so difficult to settle the question of how 'users' ought to be handled - most folks, myself absolutely included, are coming from the perspective of a particular use case. Even with deliberate effort, it's been pretty tough to get into a genericized head-space with respect to users. There are, I think, a couple reasons for this.

IMPORTANT NOTE: much of this probably sounds like a proposal for core. It's not. While I'd personally like to see a solution along these lines integrated into core, this solution requires Panels, which would mean getting the Panels engine into core - and that's a whole other bag of chips. This idea CAN be implemented entirely in contrib, and that's what my focus is on here.

The 'User-Centric' Challenge

The first problem is tied to data storage: almost all of the profile solutions that have arisen store user data in nodes. Specifically, there's bio and nodeprofile for D5, which have merged (and an enormous kudos to everyone involved in that effort!) into content profile for D6. Now, many debates have been had about the appropriateness of nodes as a data storage mechanism, and let me be clear that, while it's an important debate, it's not the topic at hand. There's also core's profile.module...but that's it's own whole can of worms that needn't be opened right now.

With the node-based solutions, the problem is at render-time: if you're storing a whole bunch of data about users in their corresponding node, then you've got to pick a render-time strategy for teasing out the particular subsets of data you want and arranging them on the page. Which either means doing it in the theme layer, or handing it off to another module first. Pushing the responsibility directly to the theme layer is just wrongheaded, in my opinion - it means that for any site implementing user-centric data pages, there's a task to be done which sits uncomfortably between a typical drupal dev and themer's toolset. Handing it off to another module first is the better option, because that module can make data-organizational level decisions, then present a consistent package to the theme layer. As far as I'm aware, Advanced Profile Kit is the only module that's really directly focused on that kind of logic for users. (Note that Michelle and I have been talking about this general idea for a while, and the long-term plan is to deprecate APK in favor of user_panels, which she and I would co-maintain)

But Users != Profiles, which begs the question: where does MySite fit in to the above discussion? It doesn't, really. MySite doesn't use nodes as a data storage mechanism, and it's not about building user profiles. It's more analogous to something like an iGoogle homepage - which in turn entails that it provide its own rendering logic for a DND interface. But it's still very much within the 'user-centric' scope. This disjointedness of these connections points to what I believe to be the second major problem with drupal's user handling: there are different conceptual axes along which any given user-centric page can be organized, and we're not always clear on which one we're talking about. Specifically, I see there being three axes: the user profile (bio/nodeprofile/content_profile, APK), the user homepage (mysite), and the user account page, which the core user module currently provides. Three, because of basic structural differences at the access level:

  • The account page is strictly user-facing; menu callback-level access is private.
  • The homepage is typically user-facing, with the potential for exceptions; menu callback-level access is semi-private.
  • The profile is public-facing, with the potential for restricting access to sub-components; menu callback-level access is public.

Note: There are some common exceptions to these access settings, but I'm not aware of any that can't be handled easily.

I don't know if this division has been explicitly articulated anywhere else, but its basic tenets strike me as being implicit in almost all of the discussions about Drupal's user handling. It's the conceptual underpinning over which many such discussions break down, because folks tend to (quite understandably) build a conceptual model of users based on the use case they've worked/are working from. Breakdown tends to occur over this problem: a piece of content that clearly belongs on the private account section/axis for Site A equally clearly belongs in the public profile section/axis for Site B. I think that core's existing system of providing user categories probably gets the gold star for best recognizing this reality, as it opens up the potential for implementing the user as a dynamic platform, viewable/interactable through many different lenses. Unfortunately, the core system crashes and burns on implementation.

A Platform: User Panels

There are a number of problems that a user platform has to solve if it's going to to better than core, more than just the ones I've described above. But they're a decent starting point, so I'll tackle the two major issues - node data retrieval & display, and handling of different user 'axes' - to begin with. A quick excerpt from earlier in the article:

...if you're storing a whole bunch of data about users in their corresponding node, then you've got to pick a render-time strategy for teasing out the particular subsets of data you want and arranging them on the page...Handing it off to another module first is the better option, because that module can make data-organizational level decisions, then present a consistent package to the theme layer.

That.Is.Panels. Minus the fact that Panels is not even remotely restricted to node data, it's a passable description of what Panels does: it grabs a specific bit of data and arranges it with respect to all the other pieces of data, all the while interacting with and presenting a consistent package to the theme layer. Problem 1, check.

The second issue is a little more complex, as it has to do with the way that Panels' context system works. But it's also the essence of user_panels-as-platform. I don't want to digress into the depths of the Panels engine, though, so I'll start with the final vision. PLEASE note that this description simplifies on a number of levels concepts for clarity & brevity:

  • Modules such as like nodeprofile, bio, content_profile, mysite, etc., would provide the content they create and store as pane types to be used by the Panels engine. (Things provided by core can be packaged into the user_panels module itself).
  • Through an administrative GUI, site admins can choose which (if any) of the different axes - private, semi-private, and public - get to use which of the various pane types provided by those modules.
  • Site admins can choose [system] paths at which each of these axes should reside, as well as whether or not to enable the semi-private or public axes at all.
  • Site admins can also set up how each of the displays for the axes should look, and set the override mode for each axis: either 'blueprints' or panels_page-style.

I'm hoping that the only particularly difficult thing to grok in that bullet list is the 'override mode'. The mechanics are pretty abstract and arcane, but in application, it's really pretty simple: imagine that we're overriding node/% with panels, and we're not doing any funky stuff with different displays for different node types. In this case, panels_page does overrides by using a single display for ALL those callbacks. That means there'll be exactly one row in the {panels_display} table, with one configuration, and EVERY single page request of the form node/% will call up the data from that row. Even if you've got 10 million nodes, they're all rendered through that one display.

In Blueprints mode, however, having 10 million nodes would mean that you also have 10 million displays. The difference is significant because it means that for each of those nodes, the node's owner is able to control how his/her node looks without affecting how any other nodes look. All the site admin does is create a 'blueprint' that provides all new nodes with a pre-configured display, that the owner can then change at will. In other words, everyone gets to control the appearance of their own node - or for our case, their profile, or homepage, etc. This is the paradigm under which og_panels operates.

Hopefully I'll have time to write up a little more about this paradigmatic difference, and potentially some efforts towards abstracting the process of writing a blueprints-based system (panels_page-style overrides are fairly straightforward by comparison), but that's all a separate blog post. For our purposes here, the bottom line is: Site admins can decide whether all user_panels are identical (created by the site admin), or if the users should be able to modify them.

Most of what needs to be done to make this a reality isn't actually that hard. We'd need to stitch together an admin interface, and pull in pieces of code that have already been written and tested in og_blueprints and panels_page. Abstracting the blueprints paradigm would be nice, too, but it isn't strictly necessary and can be done later.The only part of this whole idea that I think would be difficult is the very first bullet point in the list - writing the Panels integration for each of those modules. That's the part that'll depend on interest in this idea by the rest of the community.