So one of my duties for the past couple months, and one of the most extensive programming projects I’ve done, has been using HTML, CSS, Javascript, PHP, SQL layered on top of the MediaWiki content management system for a project known as “Government OI Exchange System,” or “GOES,” which lends itself to various terrible puns. The overall concept of the project was to develop a prototype system that would make government “official information,” or “OI,” messages more human-friendly to read and interact with. MediaWiki, the content management system that powers Wikipedia, was chosen because we wanted people to be able to discuss OI dispatches, as well as collaborate on them. Unfortunately, due to the nature of the system, I can’t make a publicly available version very easily, so I did the next best thing and did a virtual tour. We’ll start with the core of the GOES Wiki, a message viewing system that, for lack of creativity, is called NMail.
Click to see the main NMail display page.
The first thing to notice about the display is my name (REID.MICHAEL.JAMES) in the upper left corner. When users log into the GOES Wiki, they must present a PKI certificate in order to proceed. (In practice, this certificate is actually a physical ID card with a magnetic strip that is read by a specialized USB device.) NMail then uses the PKI certificate in order to personalize the data that is displayed in the main panel. All of the data in the main panel is pulled from a Microsoft SQL Server database that contains over 150,000 messages; despite the database being on a modestly powered home computer, due to well-placed indexes and good query writing–excuse the blatant horn-tooting–the page loads in less than a second. For example, the page in the image was generated by this query:
DECLARE @perPage INT DECLARE @pageNumber INT DECLARE @idNumber INT SET @perPage = 20 SET @pageNumber = 1 SELECT @idNumber = OrgUser_ID FROM dbo.Users WHERE OrgUsers_WebName = ‘REID.MICHAEL.JAMES.1234567890′ SELECT * FROM ( SELECT msg_TIME_RECEIVED, msg_PREC, msg_Subj, MSG_ID_MSGS, msg_DTG, msg_From, msg_Body, msg_SecLbl, f_Read, f_Favorite, f_Status, ROW_NUMBER() OVER (ORDER BY msg_TIME_RECEIVED DESC) AS rowNum FROM ( SELECT dbo.Msgs.msg_TIME_RECEIVED AS msg_TIME_RECEIVED, dbo.Msgs.msg_PREC AS msg_PREC, dbo.Msgs.msg_Subj AS msg_Subj, dbo.Msgs.MSG_ID AS MSG_ID_MSGS, dbo.Msgs.msg_DTG AS msg_DTG, dbo.Msgs.msg_From AS msg_From, CAST (dbo.Msgs.msg_Body AS TEXT) AS msg_Body, dbo.UserToMsgRefs.f_Read AS f_Read, dbo.UserToMsgRefs.f_Favorite AS f_Favorite, dbo.UserToMsgRefs.f_Status AS f_Status, dbo.UserToMsgRefs.f_Deleted AS f_Deleted, dbo.SecLbls.SeclLbl AS msg_SecLbl, ROW_NUMBER() OVER ( PARTITION BY dbo.Msgs.MSG_ID ORDER BY dbo.Msgs.MSG_ID) AS seq FROM dbo.Orgs LEFT JOIN dbo.MsgToOrgRefs ON dbo.Orgs.ORG_ID = dbo.MsgToOrgRefs.ORG_ID LEFT JOIN dbo.Msgs ON dbo.MsgToOrgRefs.MSG_ID = dbo.Msgs.MSG_ID LEFT JOIN dbo.UserToMsgRefs ON (dbo.Msgs.MSG_ID = dbo.UserToMsgRefs.MSG_ID AND dbo.UserToMsgRefs.OrgUser_ID = @idNumber) LEFT JOIN dbo.SecLbls ON (dbo.Msgs.msg_SecLbl = dbo.SecLbls.SecLbl_ID) LEFT JOIN dbo.MsgToGMFRefs ON (dbo.Msgs.MSG_ID = dbo.MsgToGMFRefs.MSG_ID) WHERE ((dbo.Orgs.ORG_ID = 9898 OR dbo.Orgs.ORG_ID = 9899 OR dbo.Orgs.ORG_ID = 11000 OR dbo.Orgs.ORG_ID = 14015 OR dbo.Orgs.ORG_ID = 14066 OR dbo.Orgs.ORG_ID = 14490 OR dbo.Orgs.ORG_ID = 14661)) AND dbo.Msgs.MSG_ID IS NOT NULL AND (dbo.UserToMsgRefs.f_Deleted = 0 OR dbo.UserToMsgRefs.f_Deleted IS NULL)) AS T WHERE (seq = 1) ) AS dtOuter WHERE (rowNum BETWEEN (((@pageNumber – 1) * @perPage) + 1) AND (@perPage * @PageNumber))
It makes slightly more sense with proper formatting… slightly.
As you might be able to tell from the query, which messages a user can view is based upon to which organizations they belong, information that is held in the database. In addition, a user has individual ‘relationships’ with a message–a message being read or unread, or messages being favorited, for instance–which are also stored in the database. (The large number of options and unwieldiness of queries like the above are why the next task on the project is to create a SOAP service for potential end-users of the system, so they won’t have to interact with the database directly.)
As far as the user interface GOES (see what I mean about bad puns?), the main cool feature is that everything is loaded using AJAX. AJAX is the “loading in place” mechanic that sites like Facebook, Twitter, and Gmail use to feel more organic to the end-user. So, comparing the display in the first image with this display of new messages only, the only thing that was reloaded was the message listing in white.
Similar to being able to show only new messages, users can do things like change the sorting category, filter their messages by organizations and search for messages about zebras, and change the page (a fairly important task for a mail client).
So what happens when one actually clicks on a message? We’ll find out in the next installment of this exciting series!