Iteration 2 : The Code
The Code Viewer
My journey into Object Oriented Programming (OOP) and ColdFusion is well under way. We have completed Iteration One which was a shot-gun approach to web application development. This iteration is about refactoring and getting the application to work in a cleaner, more efficient way. There will be touches of OOP, but this is more about making the application better now that we have a good sense of usability issues and what we actually want it to do.
As always, this code viewer allows you to look at my progress on this project on a day-by-day basis. See how I am updating individual files. See where new methodologies are getting applied. See how OOP can help you.
Note: The code viewer works better in FireFox (big suprise), but is functional in both FireFox and IE.
For every code update, I will update the live application. The live application will always have the most recently updated code. Click here to launch the latest version of the application.
Iteration 2 : Code Updates
I do NOT support this approach. I am only posting it as an update because it works in a misleading fashion and should be changed. I only realized this after I had done it. I want to talk about my reasoning so that later I can fix it and you can learn from my mistakes.
By referrential redirection, I mean sending a user, as a post-form-processing action, to a referring url rather than to a hard-coded "success" page. I would say that this approach is not need 80% of the time, but for this project it is. In this application, one can edit or delete a video from either the search.cfm ColdFusion template or the favorites.cfm ColdFusion template. And, until now, the "success" action of the edit_video.cfm ColdFusion template was just to send the user back to the search page. This ruins the user experience regardless of where you come from. If you came from the search page, you lose your search criteria. If you came from the favorites page, you are taken to a completely different section. In this case, hard-coding the success action is a lose-lose situation.
To help over come this, I created a page equivalent URL (as discussed in previous updates) for every page in the application. I was planning to create a queue of page visits that would act a referrential chain. After talking to Peter Bell and another guy (whose name I cannot recall) at the NYCFUG meeting, I realized that I didn't need a chain of references; all I needed was the last "different" url.
In this update, I use that page equivalent url and the idea of the last "different" url to keep track of the referring page. If you look in the Application.cfc ColdFusion component, you will see that I have added an APPLICATION-scoped variable, ReferrerUrl, in the OnApplicationStart() event method. Remember this application is designed to be single-user (but that is the least of the problems). All this variable has to do is keep track of the last different url which will be the current page's referrer.
Then, if you look at the end of the OnRequestStart() event method, you will see that I update the APPLICATION.ReferrerUrl. The update is based on how the page was accessed: As a first run page; as a Nth run page; as a new page in the same section. I don't want to go into it too much, as it is hugely commented in the code, but the gist of it is that the referrer url is updated based on the CGI.http_referer and the current Url.
For the moment, we will say that this takes care of tracking the referring url. But, keeping track of it is only one part of the problem; now, we have to apply it. To do so, I updated the Meta Form object to have a post processing directive. This is related to the post processing Url, but in a more abstract way. I was not comfortable with the post processing url as it had the potential to create very strange looking FORM keys. The post processing directive works in the same way (as a hidden form field or a dynamic form field name), but instead of passing around a URL, it passing around an "action request". The ones that came to mind were:
- SELF. This would request that the form page CFLocation take the user back to itself with a blank form.
- REFERRER. This would request that the form page CFLocation return the user to the referring url (as dictated by the value of the APPLIACTION.ReferrerUrl value).
- TOC. This would request that the form page CFLocation take the user back to the table of contents of a given section (or all related actions such as edit, delete, sort, etc.).
- LIST. This would request that the form page CFLocation take the user back to the List page of a given section (ex. going form the edit_tag.cfm page to the tags.cfm page).
Now, these are requests, not commands. The given form page would evaluate these requests and do what it felt was necessary. If a form page did not have the code to check the post processing directive, these requests would have no affect.
I then updated the edit_video.cfm ColdFusion template to have a hidden form field, metaform_postprocessdirective, and set its value to "REFERRER". If you look at the post processing section of the edit_video.cfm ColdFusion template, you will see that the code checks to see if there is any post processing directive. If there is (which will be constant due to the hidden form field), the CFLocation uses the value of the APPLICATION.ReferrerUrl variable (if it is available). Now, the success action of the edit_video.cfm ColdFusion template will redirect the user to where they came from. This should better the user experience.
I added this methodology to the delete_video.cfm ColdFusion template as well since this page could be reached from multiple places in the application.
Then, I wanted to take that one step further and apply it to the edit_tag.cfm ColdFusion template. If you remember from earlier updates, I was passing the "edit_tag.cfm" url as part of the name of a submit button. This was getting put into the post processing url of the Meta Form object. As I said before, this made me feel uncomfortable. To calm my sense, I replaced this with the use of the post processing directive. Now, instead of the "Save and add Another" button having the name "metaform_postprocessurl_edit_tag.cfm" is has the name "metaform_postprocessdirective_SELF".
If you look at the post processing section of the template, you will see that it checks the Meta Form's post processing directive and if "SELF" was requested, the CFLocation refreshed the form. If not, the CFLocation takes the user back to the tag list page, tags.cfm.
At first glance, this has indeed taken care of the referrential relocation problem. The user is always sent back to the page from whence they came. The user is having a better application experience.
The Problems With This Approach
Indeed, at first glance, this probably does look fine. But, after more evaluation, you will find that it is riddled with problems. For starters, let's take a look at how we keep track of the referring Url. We do this with a single-session variable that checks the current request's url. Well, what happens if the user opens up the application in more than one window? This is a standard practice for web application use and MUST be accounted for. This, effectively, creates parallel branches of the same application session. This does not mix nicely with our solution. Every page request is going to be evaluated as if it was made in sequence (with each request checking a central referrer url value). This is going to quickly corrupt the referring url value and therefore all CFLocations that depend on it.
What quickly becomes apparent is that the CFLocation / referrer combination needs to be done on a CLIENT-WINDOW-basis and NOT on a user-session basis. And, since the ColdFusion server is completely removed from the user's browser, this means that we cannot do things quite as stealthily. Some sort of value MUST be passed around from page to page (not just stagnating on the server). I do NOT know how to handle this yet.
The other problem, which is not even worth going into at this time, is the idea that actions will set up a chain reaction that will directly affect the idea of a single referring url. Imagine that you could edit a video from the search page. Then, on the edit page, you could get to the delete page. Then imagine you chose to delete that video. The success action of the delete page would attempt to send you back to the edit page. However, since the video no longer exists, the edit page wouldn't be what you expected. Would it show a blank edit form? Or, would it send the user back one step further to the search page? Again, I do not have the solution. All I know is that the current solution is not proper.
There are no comments posted for this web log entry.
Iteration Two Updates
Nov 30, 06 Code Update
Nov 21, 06 Code Update
Nov 20, 06 Code Update
Nov 15, 06 Code Update
Nov 14, 06 Code Update
Nov 10, 06 Code Update
Nov 9, 06 Code Update
Nov 6, 06 Code Update
Nov 5, 06 Code Update
Nov 2, 06 Code Update
Oct 31, 06 Code Update
Oct 30, 06 Code Update
Oct 27, 06 Code Update
Oct 25, 06 Code Update
Oct 23, 06 Code Update