I have finished building a simple content management system (see: Yay Tests!). It is the best work I've yet done in my four and one half years at Headspring.
The project was really fun because I got to do some wild stuff in breaking with RESTful routing out of necessity (see: of both CMS routing and forcing browsers to close) and some of the more conventional model-view-controller things which still seem like magic to me (see: easy AJAX?). Beyond MVC, I am proud out the underlying architecture too (see: Fight for the Center).
So what didn't go so well? What are some pitfalls that I will avoid next time (and document here so that you may avoid them too)?
One:
I struggled to get the FCKeditor working. (see: couldn't skate by with a marginally functional FCKeditor)
Two:
I placed an overemphasis on alphabetization. (see: When to Alphabetize)
Three:
I staged a version of the web application on one of Headspring's servers and in doing so I struggled to get ASP.NET MVC running in an IIS6 environment. There are two things to remember to do. First, the MVC .dll has to be added to one's bin folder. Secondly, one needs to set up "wildcard mapping" which may be done by going into the site's properties in IIS:
From the "Home Directory" tab click on "Configuration..." to get this dialog box:
Next, click the "Insert..." button for this dialog box:
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll needs to be added here and the checkbox for "Verify that file exists" should be unchecked.
Four:
A flash movie plays at the home page of the web application which is public-facing. It was noticed that when persons tried to view the home page at an iPhone that the flash movie just appeared as a broken link. This problem, and other potential woes caused by an inability to use Flash, had to be addressed and it was suggested to me that I display an image in lieu of the flash content if Flash was unavailable. I thus struggled to find a way with JavaScript to determine if the flash plug-in was installed to empower some conditional logic that would sniff for Flash. I had trouble finding a script that worked universally across all browsers. Eventually, I found this solution:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>BTA Systems</title>
<link href="/Content/Site.css" rel="stylesheet" type="text/css" />
<script src="/Scripts/AC_RunActiveContent.js" language="javascript"></script>
<script type="text/javascript" src="/Scripts/jquery-1.4.2.js"></script>
</head>
<body>
<SCRIPT LANGUAGE=JavaScript1.1>
<!--
var MM_contentVersion = 6;
var plugin = (navigator.mimeTypes && navigator.mimeTypes["application/x-shockwave-flash"]) ? navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin : 0;
if ( plugin ) {
var words = navigator.plugins["Shockwave Flash"].description.split(" ");
for (var i = 0; i < words.length; ++i)
{
if (isNaN(parseInt(words[i])))
continue;
var MM_PluginVersion = words[i];
}
var MM_FlashCanPlay = MM_PluginVersion >= MM_contentVersion;
}
else if (navigator.userAgent && navigator.userAgent.indexOf("MSIE")>=0
&& (navigator.appVersion.indexOf("Win") != -1)) {
document.write('<SCR' + 'IPT LANGUAGE=VBScript\> \n'); //FS hide this from IE4.5 Mac by splitting the tag
document.write('on error resume next \n');
document.write('MM_FlashCanPlay = ( IsObject(CreateObject("ShockwaveFlash.ShockwaveFlash." & MM_contentVersion)))\n');
document.write('</SCR' + 'IPT\> \n');
}
if ( MM_FlashCanPlay ) {
var flash = true;
} else{
var flash = false;
}
//-->
</SCRIPT>
<script type="text/javascript">
$(document).ready(function() {
if (flash) {
$('#flash').removeClass('noshow');
} else {
$('#image').removeClass('noshow');
}
});
</script>
<div id="flash" class="div040 noshow">
<script language="javascript">
if (AC_FL_RunContent == 0) {
alert("This page requires AC_RunActiveContent.js.");
} else {
AC_FL_RunContent(
'codebase', 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0',
'width', '959',
'height', '285',
'src', 'BTA',
'quality', 'high',
'pluginspage', 'http://www.macromedia.com/go/getflashplayer',
'align', 'middle',
'play', 'true',
'loop', 'true',
'scale', 'noscale',
'wmode', 'opaque',
'devicefont', 'false',
'id', 'BTA',
'bgcolor', '#007FB3',
'name', 'BTA',
'menu', 'true',
'allowFullScreen', 'false',
'allowScriptAccess', 'sameDomain',
'movie', 'BTA',
'salign', ''
); //end AC code
}
</script>
</div>
<div id="image" class="div040 noshow">
</div>
</body>
</html>
Five:
This NHibernate-related code:
public void updateSettings(Settings settings)
{
var sessionFactory = CreateSessionFactory();
using (var session = sessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
session.SaveOrUpdate(settings);
session.Flush();
transaction.Commit();
session.Close();
}
}
}
...ended up replaced by this NHibernate-related code:
public void updateSettings(Settings settings)
{
var sessionFactory = CreateSessionFactory();
using (var session = sessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
session.SaveOrUpdate(settings);
session.Flush();
transaction.Commit();
session.Close();
transaction.Dispose();
sessionFactory.Close();
sessionFactory.Dispose();
}
}
}
Do you see the difference between the two? Duh. :) Launch Marketing, who was liaison with the end client, received this message before the replacement.
Six:
The UI displayed a series of tabs for the topmost categories of content. If one tab was "up" it had to be denoted in the HTML. I wrote a class that checked to see if the current context demanded adjusting a particular piece of HTML and I called the class 53 times within three of my Views. Unfortunately, instead of passing the menu system, hydrated from the database, into the implementations of the class, I had the class reach out for data. This made the application run noticeably slow. Why would I make this mistake? I was just trying to pass one less thing to a method. I am participating in a book club which is going through "Clean Code" by Robert C. Martin. Page 40 contains: "The ideal number of arguments for a function is zero (niladic). Next comes one (monadic), followed closely by two (dyadic). Three arguments (triadic) should be avoided where possible. More than three (polyadic) requires very special justification - and then shouldn't be used anyway."
Seven:
The content, siteconfig, and logs folders within a dasBlog install must be given permissions to allow for writing. In the absence of the permissions, there is no way to update the blog.
I hope this cheat sheet will spare you the headache I had.
No comments:
Post a Comment