Thursday, November 29, 2007

I was fortunate enough to pop up to a special event on Silverlight at Microsoft in Redmond, WA today. Mithun Dhar, Laurence Moroney, Arturo Toledo, Adam Kinney, Ernie Booth and Jesse Liberty gave us some sweet tips on building apps and organizing a good workflow between developers and designers.

Arturo is an awesome graphical designer. Oddly, or perhaps not, I liked his presentation the best. He made the Expression products fly and gave me (a developer) good tips on working efficiently with my design team. Jesse was a close second with his fundamentals presentation - he really clicks well with developers.

The crowd was mixed with about 60% developers and 40% graphic artists. I saw the ScottGu blog post this morning announcing that Silverlight 1.1 is now named Silverlight 2.0 - between that and the hints dropped at today's meeting, it feels like Silverlight is getting ready to explode. I think I'll still remember this day very well in three to five years.

Thursday, November 29, 2007 2:53:08 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
 Wednesday, November 28, 2007

http://www.justsayhi.com/bb/html_quiz

I forgot some easy ones like <div> and I thought I typed <fieldset> because I also got <legend>, but a respectable score; maybe? ScottV got a couple more than me.

fun
Wednesday, November 28, 2007 12:23:08 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 

I got a favorable message, so I reckon its not all that bad.

http://www.lhotka.net/weblog/MagenicWantsYouThisTimeWithAQuiz.aspx

After all, Rocky got an 84. I think I rocked most of the ASP.Net questions, but the smart client stuff and multi-threading is a little foreign to me.

What did you get?

Wednesday, November 28, 2007 12:07:19 AM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
 Saturday, November 24, 2007

Under ordinary circumstances, all three of my blog readers know that I don't like playing blue. Yet sometimes, it is the only possible response.

This is to the 1998 Honda Civic Headlight Replacement Technical Writer:

You Suck.

I'm no mechanic, but I have replaced my car battery, and I'm generally aware of what goes on under the hood. Plus, I'm a good reader. I can follow directions. In my older cars, the bulb was encased in the complete housing. A few screws and a plug-and-play later was all it took. Not so today. All you get at the store is the actual bulb. Much smaller and easier to ship.

The following images show the 1.5 page description of how to replace a light bulb in a 1998 Honda Civic.

The instructions for headlight replacement begin on the right side of the following page. The author notes some good points to understand before tackling the job.

civic-headlight-p185

Then, it gets into the meat of the job with a full page shown in the following image.

civic-headlight-p186

As you can plainly see, at no point does the author state the following truth:

If you are reading this manual, then your best course of action is to return it to the glove box and drive to your nearest Oil Can Henry's location. Request a bulb replacement and happily pay the fee knowing that (a) you didn't have to do it (2) you didn't break anything; aka, less swearing and (iii) the delta between the cost of the bulb at the NAPA auto part store and what you paid at the shop are negligible.

And for that malfeasance, this technical writer sucks. It is my opinion that anyone replacing the driver's side headlight in a competent manner would not need to resort to the manual. For if they did, it would be a clear indication of the pain to come.

For starters, a light source for working under the hood is a good idea. I used one of these pod lights. Press the light to turn it on and off. They're small and nimble.

 Light Source

So here's what we're dealing with. The drivers side headlight sits squarely in front of the power steering reservoir. The following image shows my finger on the reservoir. Its connected by one hose on each side and is seated on a small cradle. You can already begin to see the terribly small spaces we're about to engage.

Power steering reservoir

Just from the previous photo alone, you can see how the designers failed with this bulb location on the 1998 Honda Civic. Per the instructions, I am to lift the power steering reservoir out of the cradle and push it aside so I can gain access to the bulb housing. Those two hoses that attach to the reservoir aren't too keen on movement. I finally ended up disconnecting one of the hoses and stuffing it with a rag to stop the flow of power steering fluid to my garage floor. There was quite a bit of cussing to just reach this state.

Now that I had the reservoir propped up and out of the way and the power steering spill slowed to a slow dribble, I could being the real work. The following photo shows an overhead view of the bulb housing and my light source nestled into a good crevice.

Driver side headlight

Next, I need to pinch the tabs of the bulb housing to release it. This is very important, so you would think that the book would do a good job of describing where they are and what they look like. Not so. The tabs are nearly invisible, even with great lighting. They're about the size of a small pea on each side as indicated in the following photo. Before learning this, I cracked the plastic housing on the bulb housing with the pliers. Go me!

Bulb Housing and Tabs

After the bulb housing is removed, the rubber seal and wire latch can be removed to produce the following item of grief - a blown out halogen bulb. I bought a new one at NAPA for $8.00

Expired Halogen Bulb

When you're wrestling with the wire that provides a constant pressure on the bulb housing and keeps it in place, be careful not to snap off the little plastic tab that hooks onto the wire; that's bad. Grrrrrr.....

Headlight Stabilization Wire

Finally, I drove (the other car) to the NAPA auto parts store (again) and purchased a small amount of power steering fluid. When I arrived, the very nice man behind the counter saw the section I was looking and advised me on a good brand of leak sealant. I explained that I actually wanted power steering fluid. Sizing me up accurately, the man tilted his head and asked why I wanted power steering fluid. Evidently, I didn't pass muster. I explained that I had spilled some quantity onto my garage floor when I was replacing a headlight. At that point I must have passed some threshold of the "i-know-what-i'm-doing" home mechanic or the "complete-idiot" home mechanic. He was nice enough to stop the inquiry there and saved me a little face. So for $3.75 I left the store with a some power steering fluid and a small funnel to refill the reservoir.

So, in summary, this experience was an absolute unnecessary pain in the ass. I realized the folly of my plan about one-third into the debacle and kept thinking of reasons that I should just fold up now and waltz in to the nearest Oil Can Henry's to stop the suffering. Yet, I persisted and now I have two functional headlights in my car, and one extra piece of wire in my garage.

fun
Saturday, November 24, 2007 10:10:42 AM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [5]  | 
 Wednesday, November 14, 2007

I'm installing DotNetNuke v4.7 and I scroll to the bottom of the standard page that I've seen many times before, when lo and behold, I come across this for all to see!

dnn-install

Everyone who installs a brand new version of DotNetNuke gets to see a tiny photo of me on the cover with Shaun Walker. Sweet!

Wednesday, November 14, 2007 4:08:11 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [1]  | 
 Sunday, November 11, 2007

I had remarked to The Wife that she had spent over N on clothes during the past month. She retorted that it couldn't be correct.

Thanks to http://www.wesabe.com, this was an easy thing to confirm. Wesabe organizes purchases that you upload to your Wesabe account from your bank. It creates some great charts and graphs for managing your money with precious little effort. All free of course.

I returned to The Wife and explained how all of the values are tagged correctly, and the value is actually N+1. There are purchases from Motherhood, Gap, Macy's and Old Navy.

And here's the quote:

"Oh, that's why! Not all of those are clothes. Macy's isn't clothes... it's make-up."

Zing!

Sunday, November 11, 2007 9:33:11 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
 Saturday, November 10, 2007

In my experiences as a software developer, its fairly normal to hear comments like the following:

  • That's too many hours
  • They don't have the budget
  • I'm not paid enough

I had the good fortune of attending a Portland XP Users Group presentation a few weeks ago by James Shore. He got off on a slight tangent and gave us (well, at least me) a simple equation to chew on:

roi

He explained that at its core, Return On Investment is represented by the previous equation. It can help explain quite a bit about the world. This was in response to someone asking about the high cost of the software development methodology under discussion that night.

If you're presented with a scenario where the value is constant, then the only way to play the game is to minimize costs. Think of a job that never changes. If it always provides the same value to a business, management will seek ways to reduce cost in order to improve the ROI equation.

On the other hand, a scenario where value has the capability for growth is much more interesting. If you wanted to make $500,000 a year then you would be challenged to deliver some multiple of that cost as a value to the business.

Here's my favorite take-away: At some point along the graph, as value increases then cost becomes insignificant. This is the place to be.

The initial cost of software can make some people squeamish. I'm certainly not one to be afraid of zeros; I'm much more interested in the value.

  • What is this solution doing for the business?
  • Is there a practice in place for tracking ROI over time?
  • How soon can it begin providing value?
  • Can it provide even more value?
  • It is possible to reduce cost and drive the equation even higher?

This is why I love my job at Pop Art. Driving value higher and then swooping back to cut costs with new technology that makes me more productive. Value will often come in several forms including cash value, brand value and community value. In any case, it all starts with that equation.

Saturday, November 10, 2007 6:11:25 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
 Friday, November 09, 2007

I was working with a web service client that talked to SharePoint this week. I wrote a quick Silverlight app that extracted a list of tasks out of a SharePoint list. I love how simple this is to tap into:

http://sharepoint.yourcompany.com/_vti_bin/lists.asmx

The previous URL will show the path to one of the web services provided out-of-the-box by SharePoint. This particular web service provides several methods for dealing with SharePoint lists. I just needed to call the GetListItems() method and pass in the list name and view name as parameters in order to get my data.

This worked fine on my local machine, but when I migrated the solution to a staging server, the SharePoint web service refused to send me the data. After a bit of finagling, I realized the web service was happy to talk to my laptop, but it politely declined the remote web server's request as I lacked the proper credentials. I even was running the web solution with impersonation enabled because I wanted to pass along my Windows credentials during the call from the web server to the remote SharePoint server. I forgot that this is just simply not possible.

For security reasons, the web server does not hold on to my credentials "just in case" I might want to use them later. In this scenario, I do need them - but no dice. This particular list in SharePoint is locked down tight.

I didn't have the proper credentials when my web service client fired off a request to SharePoint. When I was running on my local machine, using Casinni, my credentials were readily available. On a remote web server, the credentials vanish. This is called a "Double Hop" problem - the hops are from the browser, to the web server, to another remote web server. The second hop tanked. It was a silly mistake on my part, but hopefully by writing this down now will help me remember sooner next time.

The code below shows how I solve this problem by manufacturing a credential on-the-fly and then fire off a request to SharePoint. There are multiple ways of solving this problem; I just happened to chose this one.

         MySharePoint.Lists list = new ProjectBoard.MySharePoint.Lists();
 
         list.Credentials = new System.Net.NetworkCredential(
            ConfigurationManager.AppSettings["Credential.Username"],
            ConfigurationManager.AppSettings["Credential.Password"],
            ConfigurationManager.AppSettings["Credential.Domain"]);
 
         XmlNode listItemsNode = list.GetListItems(
            ConfigurationManager.AppSettings["LoremIpsum.Guid"], 
            ConfigurationManager.AppSettings["LoremIpsum.View.Guid"], 
            null, null, "100", null, null);
 
         XmlNode dataNode = listItemsNode.ChildNodes[1];
 
         foreach (XmlNode rowNode in dataNode.ChildNodes)
         {
           // extract values here
         }

Now that I've got this little prototype functional, I can encrypt the credentials in the web.config file by using DPAPI, an encryption tool that makes it easy to protect sensitive information. Since I'm creating new credentials here, I can avoid the Double Hop problem and get on with my prototype.

Friday, November 09, 2007 10:03:14 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
 Monday, November 05, 2007

By some cruel trick of nature, I've been surrounded by web content management systems for the past several years. I've written several (who hasn't?) and stood up instances of DotNetNuke, Windows SharePoint 2007, and now Interwoven TeamSite.

I'm told Interwoven has been around for 14 years and they're currently on version 6.7.1 of their TeamSite product. This offering includes features for enterprise content management (ECM) and the assorted adjacent technologies that simply must accompany ECM in a large scale deployment. Since the beginning, their product has included version control and workflow features. I'll describe a few core parts of Interwoven TeamSite here.

Source Control Repository

First off, developers will get a quick leg up if they simply know that TeamSite includes a source control repository. It works like any other. You can get the latest source, edit something, check it back in, compare versions, label a snapshot of the repository as well as branching. There. You're farther ahead than I was when I got my first explanation, about two years ago.

Standards based developers can relish in the fact that they have carte blanche control over the HTML and CSS sent down the wire to the browser. I'm talking about the production site here, not the administration pages used to interact with TeamSite. Nearly everything you'll do with TeamSite is done through a browser, providing that browser is IE or Firefox. Sorry Safari, this car is just a two seater. Again, browser support for the production site you're building is up to you - just talking about the TeamSite administration pages here. You'll continue editing specific files in your favorite tool, such as Visual Studio, Photoshop or TextMate. So once you get the subtle nuances of this source control system in you're brain, the challenge is to build a compelling web site using the same tools you have now; no silver bullets here.

Its also worth noting that this is only a source control repository; not a web development platform. You'll still need IIS, Apache, or some other web server technology to host your site. Interwoven TeamSite is mature enough that it supports Windows, Unix and Linux environments and several popular databases such as SQL Server and Oracle; just what you'd expect from an enterprise content management system.

FormsPublisher

Interwoven's TeamSite product includes a feature called FormsPublisher. This is useful for scenarios where an information worker needs to contribute to the web site, but lack HTML and CSS skills. This type of user can complete a form, let the system validate it, and then press a button to have the system generate the equivalent HTML page. The form can include validation, business logic, database queries or anything else you can dream up. While an HTML expert would prefer their favorite text editor and complete control to the HTML page. An information worker without HTML skills can now edit an existing page, based on an customized form. Now the challenge shifts to having the information worker select the appropriate form to build the page.

A developer configures a set of files and folders to support this process. At a high level, there are three parts in motion. The Data Capture Template (DCT) is an XML file that describes how TeamSite should present the form to the information worker. A Data Content Record (DCR) is an XML file that contains an instance of a form completed by an information worker. You launch TeamSite, click File, New Form Entry and select the form you want to complete. Next, the given form appears in the browser. The fields of the form are defined by the DCT. After you click the Save button, the field values are serialized into a DCR file. These files are organized in a collection of folders on the TeamSite server; one folder per form. Each folder has a conventional set of child folders to hold the DCR files as well as the presentation template file(s), These are the files with the .tpl file extension.

A presentation template converts a DCR into something else. Most of the time, at least for me, that something else will be an HTML page. Imagine a single DCR file that contains both public and private information for a company; perhaps the DCR contains public information about a single product as well as private information for their tech support staff. The DCR file can be send around via workflow for approval and the finally be ran through both sets of presentation templates which results in two different HTML files - one file is deployed to the public and the other file is kept on the Intranet. Both files are assured of having the appropriate content via the approval process and the presentation templates apply the correct branding and layout. This model supports a good workflow model as well as good separation of design from content. Its just one example of using the FormsPublisher in the enterprise.

Since DCR files are just XML, it's relatively painless to import legacy data into TeamSite. These imported XML files map to a given DCT, then they're translated into HTML pages via a presentation template. For example, if you have the last 15 years of press releases on the legacy system, you can import the existing information with some batch processes and stand up a new TeamSite server pretty quick.

Workflow

A workflow describes an automated business process. It can instruct an author to perform an edit or add a new file to the site and manage the process of approvals, taking a snapshot of the system for archival purposes and finally deployment. When a task such as "Edit Content" or "Review Content" becomes active, an e-mail can notify the appropriate party. When the work is completed, the assigned person just pushes it through the hole. Reviewers can click "Accept" or "Reject" after previewing the changes, they don't need to know the next appropriate step in the process - its automated. The system tracks the state and flow of information of the activities throughout the lifecycle according to the established business rules approved by the given company rather than based on how the given employee feels that particular day.

TeamSite has always included a workflow mechanism, but I can only imagine how difficult it was to develop them in the past. This latest version includes a Windows client application that supports drag-and-drop editing of workflow designs. You can work locally with workflows saved to your desktop in an offline mode, but you will eventually need to save the workflow up to the TeamSite server via commands in the tool. Workflows are serialized into XML files in the background, but its rare to look at the raw information. The workflow designer application helps you do the things you would expect such as setting up a series of tasks linked by arrows; some might be conditional based on human interaction or automated entirely by Perl scripts, Java classes or some other business logic.

Its interesting that Interwoven prides itself on a large number of supported platforms for the server product, but the Workflow designer client requires the Windows operating system. As I understand it, some (or all) of the workflow client application was recently purchased from another company. My hunch is the client application is written in C++ based on the look and feel as well as the OS requirement. Its a little clunky but it gets the job done; I sure wouldn't want to hand code all of the XML it generates.

Conclusion

Overall, I'm happy with my experiences thus far with TeamSite. The documentation is rich, it has a thriving online developer community, and the paradigm isn't too hard to grasp. At one point, I started getting bogged down with the massive about of XML configuration files and customization points. After sleeping on it (and a stiff cup-o-coffee) I realized that any other enterprise level application has a similar amount of customization. Since TeamSite embraces a litany of platforms, it makes sense that they don't (or haven't) invested a lot in slick little Windows GUI programs for configuration needs. Why build a server GUI tools when Windows is only one of your supported OS platforms? On the other hand, they could build a few more web based administration forms to get around some of these XML file updates. Once I started tallying up how many configuration pages I go through for Windows SharePoint, I stopped feeling like I was building my own box and installing Linux and started thinking about the broader ideas and why I was configuring the system instead of how - perhaps it just semantics, but I felt better.

Monday, November 05, 2007 10:29:32 AM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  |