Results tagged “design”

Relationship Management

There's a pretty decent article over
at A List Apart on relationship management by Keith LaFerriere from a couple weeks ago (catching up on some of my reading). I enjoyed the "Hat Head" versus "Bed Head" comparison, particularly since I'd definitely qualify myself as a "Bed Head" in my attempt to live a creative lifestyle. Though, as a developer, my idea of a creative lifestyle is probably a little different from the conception of a typical designer (less coffee and black turtlenecks and more Dr. Pepper and not-shaving).

Anyway, he makes several very important points that I think everyone in development and design need to adhere to more.

  • Don't take things personally. Yes, you are being creative and it is important to you, but if you're making money doing it, you need to have a professional attitude and be willing to compromise.
  • Be an example, particularly if you're the team leader. It's really amazing how much the behavior of a person is determined by the people around him. If you get ticked off every time someone does something you don't like, people around you will probably start having at least a kernel of similar behavior. This goes doubly so for managers and leaders. Your behavior sets the tone the rest of the group will judge itself by. Be good.
  • Watch your language. By this I'm referring to trying to be what I would call "open-minded language." If you indicate by the adjectives you use that you're not listening or don't intend to, you will convince no one of anything. Avoid strong adjectives and try to talk as if all the options are still open even if you're already on a specific path. You can make it clear that a bad idea isn't going to fly without insulting your audience.

Anyway, I just wanted to post that link and give an infinitesimal boost to what I consider to be a good overall article on getting along with coworkers and getting the job done as a team.

Cheers.

The last update I had for the church web site
was in August
. I'm now proud to announce that the new design that Jay Risner put together for us is now online. I want to use this blog to briefly talk about the design, but mostly to map out where I hope to take the site next.

Design and Administration

The design mostly speaks for itself, though there's one hidden piece which is kind of handy. One of the difficult things about Drupal from a design standpoint is the fact that the CMS backend isn't in a backend. That is, with many other CMSes out there, such as WordPress, Joomla, and Magnolia you work in a separate interface to do the work of creating new stories and articles. The web designer doesn't have to cope with these at all because no casual visitor will ever see them. With Drupal, however, the admin interface is integrated with the front-end of the web site. Drupal merely adds another set of administrative menus and screens into the front-end. Thus, you have a long set of menus that your design has to cope with.

In the case of the new New Hope Church design, you can't just let this menu go into the sidebar because the sidebar was designed to be simple. The solute we came up with was to create an extra sidebar that sits in the brown background to the left side. I got the idea for this from the Trac
web site which places a menu on the left side of the main column and ads on the right. Since Jay's original design was so well-structured, it was really just a matter of creating an extra float to sit off to the left to work it in.

Looking Ahead

Looking ahead to what I would like to do with the site next I see a number of different sub-projects that need to be handled. The most obvious is a few incremental improvements to the new design. I cobbled together the current front-page and I don't really care for it. I need to get all the pieces of the front-page looking and fitting together better. I would like to move the login to a bar just under the banner. I would like to get all the columns laid out and pretty. I would like the directions to include a map. I would like the Flash banner to look better when Flash isn't available. Etc.

Speaking of maps, I would like to incorporate more maps into the site. There are a number of nifty things we can do with maps if we just take the time to implement them. For example, our church considers the central gathering to be only a small part of what we do. We could make that much more obvious if we added a map of the LIFE groups and other smaller meetings that take place throughout the week. Being in a college town, we send out quite a few members and it would be nifty to see a map of where our "alumni" have gone.

I would like to make it a community organization tool. I would like to see members come to the web site to find out when and where things are happening. It would be nifty if there was a way for groups to record recent happenings for their members to read about. It could even include things like a current list of prayer requests and other information. This would allow alumni and those who missed something to keep up with their groups similar to the way I keep up with friends I don't hear from often via Facebook
. It could help facilitate discussions such as helping to arrange who's going to bring meals to a family or who's bringing which dish to a supper meeting. This could help avoid the mess of email lists each group maintains themselves.

A frequent request is for a member directory to be placed online. This could be done if access to the directory was regulated appropriately. It would be great to be able to have this information online for people to change as soon as the move or to let former members keep their information available for anyone who wishes to stay in touch.

And finally, back to the mundane, the site is really disorganized right now. I need to establish some order for the site if any of this is to work in a way that will be useful. Since I'm hoping to allow the structure to be somewhat organic, the structure must be somewhat fluid so that it can grow and flex to fit differing needs. On the other hand, certain pieces of information need to be highly structured (such as information about leadership, beliefs, and other fact sheets) and I need to provide for this as well.

Anyway, there's a lot to do on the site. I just hope that I have time (or help!) to get it done with a baby due any day now.

Cheers.

Outgrowing Mason

It's a good thing Terri's coming home tomorrow. I don't think my body can take many more of these late nights. (I.e., my wife is out of town for a conference, so I pulled late nights this week, since I don't when she's home. :)

Background: The latest idea for Contentment, which is the real working idea originally came by basically adding some customizations built with HTML::Mason. Mason is a nifty mini-CMS/embedded-Perl templating system. It's hard to classify because it has a really wide mix of features. It serves files, it provides a layered virtual file system, it provides a templating engine, it provides some fancy features for wrapping content with other content via "autohandlers" and filtering, etc. To paraphrase Strong Bad, "It beats the pants off that ol' washed up the PHP I used to use."

So, I extended it. Initially, I added an indexer and a template system. Well, I had to use some odd tricks to get that to work, but I think Mason still did it pretty well. I added a system for handling contextual and session information. I brought SPOPS into the picture to help out with the database end of things (and then I hacked that because the so-called last S=Security is S=Stupid Security, at least for my needs.) I've added a fancy transformation system, which I've revamped to make it even better. I've added a fancy filtering system to be applied after transformations (which should go through the same refactoring that transformations did). The latest addition is the VFS system. I've written a new project, File::System to handle the new needs I have for URL mapping and the soon to come URL to database record mapping I have in mind.

What does this all add up to? I'm seriously abusing Mason at this point. I've taken my good ol' friend Mason and ripped his guts out, strung them around the room, and replaced parts with my own PVC. Okay, that's disgusting. Man, I go weird at 4am...I should sleep.

Basically, I'm going to have to evaluate things more, but I think that I've already spotted the next set of updates. Mason is going to say, "Sayonara." Or at least, partially. It's still going to be a valuable part of the system, but it won't be the front end anymore, I think.

Anyway, I'm never satisfied. I don't know who said it, but in the "Camel Book" by Larry Wall, Tom Christiansen, and (originally) Randall Schwatz (though, he's since been gypped, I understand), the three virtues of programming are Laziness, Impatience, and Hubris. I think a fourth one to add to the list is Discontent.

Yes, very punny. Good night.

Form processing

Once I start on a problem I have a difficult time letting go until I have a solution. I mentioned forms processing in my last entry and I have been crunching on it ever since.

I have found that the major problem with the original design had more to do with a poor OO methodology than a bad design. I just need to get the pieces separated into the correct objects. Therefore, I've build a new OO API for forms processing.

Okay, I've separated the system out into the following pieces:

  • Context - a transient object that collects all the information pertinent to the current request
  • Session - a persistent object that collects all the information connected with a particular user's session
  • Setting - a persistent object containing application-wide settings
  • User - a persistent object containing information about a user that exists across sessions
  • Form - an object stored in Settings that describes the structure of a form
  • Submission - a transient object that exists initially when a Form is written to a response and again if the user POSTs that form back in a request
  • Action - a functor object that performs some action using data from a processed Form Submission
  • Widget - an object that both renders some set of controls in a response used to form a POSTed request and a functor that performs some processing of Submission data on behalf of a Form before the form's Action is executed
  • Map - an object used to determine how the response should be constructed when interacting with a Form
  • Panel - a box in the response containing whatever object the Map says it should contain, the topmost Panel, __DEFAULT__, can be used to affect the entire response

The use-case is basically like this: The response has a Panel placed in it (possibly the __DEFAULT__). This Panel specifies a Map, which determines what sub-response to place within the Panel. Typically, this is some sort of Form, to being with. The Form is drawn to the response and stored in the Settings (keyed by a application-unique name). The Form determines the Action that is run on the receipt of an activated Submission. A Submission is initially created to associate a UUID with the submission and to remember the Map used so that an activated Submission received later will operate according to the original Map behavior. Finally, the user gets a copy of this form in her browser and fills in the details of the form. Once filled, the form is submitted back, which creates an activated Submission object. The Submission object then causes the Form to process all the incoming information via it's Widgets. Assuming successful processing by all Widgets, the Form then runs the Action. Based upon the Action result, the Map is then used to determine how to render the response. This generally involves an immediate 302 Redirect to the next page in the Map and then the Map is used within that page to determine how to render the content there.

Phew! The details of this whole process are almost entirely handled internally to Contentment (or will be when I release the next trunk revision). The only the thing the programmer will have to do is to create a Form with Widgets, create an Action to handle the Submission, and a Map to determine what to do next, based upon the output of the Action. This creates a nice HTTP-centric MVC architecture where the Action/Map form the controller, the Submission forms the model, and the Form/Widgets form the view.

As those who have read ~Sterling TNG will know, I've recently begun revamping my ~Sterling web site. I am still working on it in short bouts when I can and have gotten the first revision of my form handling stuff put together and tested using the first revision of my database security plugin.

The two major things I've struggled with over the last few years in desiging my framework is URL handling and form handling. The essential problem is that HTTP is a cruddy protocol for designing web applications and interactive systems. HTTP has only barely hacked together support to allow state to exist between clicks. As such, you have this situation where you have to track work flows page by page by page. Instead of the more typical GUI design of event by event by event. A single page might include hundreds of events, which cannot be processed by the server until the user clicks a "Submit" button or something similar.

Anyway, I've come up with what I consider to be a solution a little different from most that I've encountered. One thing I want is the ability to have truly hidden fields. Many forms need to have extra information associated with the form. Such things can include the type of operation being performed, limitations on the input the user can give, or just extra data that needs to be associated with a form that has already been set by the user or that the user doesn't get to have a say in. This is especially needed in the case of multi-page "wizards" where each page collects a little bit more data from the user. After several pages, the wizard is completed and all the data can be processed.

What I've done is assigned every form in a page an ID that is unique to each user's session. Then, session data stored on the server can be used to store the hidden information without relying on the user to submit the form properly (i.e., hidden fields in the form itself might be maliciously modified). Then each field name has this ID associated with it so that the user could have multiple instances of the same form. Each page might have multiple forms, so I've included the ability to have multiple forms on a page where each is activated separately or through a kind of event system, one form may activate another, etc. Forms that aren't activiated aren't processed, but their information might be kept in case they need to be activated later or the user hits the "Back" button.

To me, this seems really nice. I have a nice way of storing form data associated with the user and it's all fairly seamless to the programmer as well through the use of a lightweight widget API embedded in Mason files.

However, this does have a few problems: session expiration, form data expiration/naming, and storage abuses. This system requires that each form add a few entries to the user's session. Watching a user's session is a little interesting because everytime a user opens a page with a form on it, the session expands to add the metadata for that form to their session. Thus, if a person hits reload on the login page 10 times, their session expands each time. This could lead to some consequences where a form with a lot of session data could eventually consume huge amounts of hard disk space. This is a bit unlikely because most the information is small amounts of text, but you never know.

Session expiration is a problem most sites have to watch out for. For example, when I click on the Preview button of Drupal after I finish typing, I will have preceded that click by selecting the text of this post and copying it to the clipboard. Why? Because sometimes Drupal unexpected terminates a session, which will cause all my typing to be lost because Drupal will say "ACCESS DENIED" and Firefox will forget to store the values I have already typed. Nasty.

I do not want this to be a problem. So, I have to find a way to recover a user's session. Probably this will involve setting a cookie on their machine that never expires to help track the session ID they had originally. Then, when their session expires and the get taken to the login screen, the successful login will result in an automatic copying of their old session to the new one. Then, we must take the data that they submitted when the session expired and process it as if nothing had happened. My forms processor should be able to cope with this pretty seamlessly, I just need to hook it into the security API, which hasn't yet been done. It will also require some modifications to the security API which as the security API contract is incomplete.

Finally, a problem fairly unique to my setup is form data naming/expiration. This is a little more nebulous. In some cases, forms may need to be time sensitive and need the information in them to expire. I also haven't really figured out how a completely processed form should be cleaned up or if it should. What if a user logs in to the system, and then I just clean out all record of that form and then the user hits the back button a couple times to get back to the login screen and logs in again using the original form? Error! The form no longer exists. At the same time, it's bad news to store the user's password in their session longer than absolutely necessary, which would be stored indefinitely if I didn't clean up the form metadata in their session. Therefore, I'm considering setting up some way of reinitializing a form to a fresh state if they try to go back to one that's already been cleared. (Of course, this isn't yet an issue because the implementation doesn't yet clear forms out because of this problem.)

A second aspect of this problem is naming. At this time, each form widget is named with a 5-letter identifier prepended to the name to identify which form the control belongs to. This will undoubtedly break automatic form fillers, which might not be a bad thing at times. However, these tools are useful, so I don't want to completely invalidate them. Instead, I'm probably going to create some sort of aliasing system where each form element will have it's name prepended by the same integer every time and then there will be a hidden field to alias that integer to the real form ID. In the cases where a page contains only a single form, or where forms aren't nested, the integer wouldn't be necessary, but might just be added in anyway to make the coding a little easier and make page output faster. (Sometimes, I don't know if theirs going to be a nested form until after I've started printing output to the client, so we'd probably be better of just making the assumption anyway).

I hope XForms takes off because it would make all of this much easier as it gives a much more natural client-side API for handling a lot of these details (especially, nested forms, form wizards, et. al.).

1

Tags

Find recent content on the main index or look in the archives to find all content.