ORDER BY BiggestProblem DESC

Oct
21
2008

I caught a little snippet on NPR this weekend that fits in well with what I've been hearing a lot of on the radio, TV, newspapers and the like. They were interviewing someone who was making drastic changes to their life and spending due to a loss of one of the family incomes.

I had a lot of reactions that made me wonder how they afforded their previous lifestyle if the loss of a part-time job led to things like moving into the cellar to avoid heating the rest of the house. Lots of these stories on TV and radio and in magazines make me wonder how many of these are stories that happen every day, bad economy or not, but we now have crowds of journalists digging to find them because it makes for a good story now.

Digressions aside, one of their cost-cutting measures stuck out at me: dramatically altering what they wear to get down to only one load of laundry a week. What I heard sounded like there was a lot of effort for this and hit me funny because we got a new washer and dryer a couple of weeks ago and an image of those yellow EnergyGuide cards from both popped into my head.

The washing machine's card estimated that our ANNUAL energy cost for both electricity and gas (for our hot water) was . . . $11. That's right. Less than a buck a month to wash all of our clothes.

I'm not going to pretend that I understand their situation, but, if we needed to find an extra $1000 or even $2000 a month to scrape by in tough times, it's pretty clear that OUR laundry isn't a gold mine of wasted cash, just waiting to be tapped into.

Whenever I see huge effort going into places where it isn't going to pay off proportional to that effort, I start thinking in SQL. To me, given the amount of data I work with on a daily basis, it's entirely natural to take all of the expenses and ORDER BY the biggest expense when it's time to start cutting.

And, if a quick look at the top of that list doesn't reveal much, a quick ORDER BY "least important" works as well to reveal the easiest cuts.

This approach is something that's impressed me with how the Bill and Melinda Gates Foundation went about choosing the areas to attack first. Everything I've seen about that process says that they were pre-occupied with choosing problems that affect the lives of the highest number of people. They did an ORDER BY "number of people who die from ???" on the giant spreadsheet of problems in this world.

When I go out of my way to consider a problem or situation through this lens, I often end up with a much more obvious place to start my solution. I think this pattern is really powerful. Imagine going through your typical cubicle farm and following this simple process:

  1. Ask everyone the following questions:
    1. What is the most tedious computer-related task you do daily/weekly/monthly?
    2. How much time do you spend on it?
    3. If that task wasn't yours to do any more, what project that isn't being done now would you be able to do instead?
  2. Compile those results, along with salary-type information and start doing ORDER BY's to see what the most tedious, time-wasting tasks are actually costing.
  3. Start tackling the top of the list with a portion of your IT budget.
  4. Act on that list of projects that aren't being done by enabling people to get moving.

Imagine how many thousands of hours, tens of thousands of dollars are being wasted on things like manually comparing 2 reports, line by line for discrepancies because there isn't a reconciliation report that SHOWS the differences.

Imagine how many good ideas for projects, ideas for improving your business, for making a better product or offering a better service are stagnating in your cubicle farm. And, imagine that, after eliminating or reducing these tedious tasks, instead of laying people off, you reinvest that previously wasted time into those ideas and project.

I have to wonder how this little exercise might affect an organization's position in a tough market.

Ideas for Content Management in ASP.NET MVC

Oct
05
2008

I've been working on quite a few projects where I'm either already directly developing within the ASP.NET MVC Framework or where the framework is prominently featured in my design/architecture documents.

Because the framework is so new, there are still a few kinks and the patterns for how to do some common things haven't yet sorted themselves out. One of those areas is how to handle content in web applications.

All of these projects are web applications that *do* stuff. Most of these apps are filled with pages to edit things, retrieve data, manage queues, etc. In other words, the custom business logic that's unique to my clients' and my businesses. However, every single one also needs a batch of "pages" that *are* just basic content, with a few variables (like who's logged in) sprinkled through them.

The pattern that appears to be recommended by the ASP.NET team (via what is in the project template for the "home" and "about us" pages) basically requires a new view and a new action in a controller for each page, which, for those playing along at home, also requires rebuilding the app and redeploying.

Experience has taught me that solutions like that inevitably lead to pain. Once deployed, people always want to add pages, change them and otherwise mess with things more often than anyone wants to go through the build/deploy cycle. That leaves me looking for something that has the content more separated from the aspx setup than the default pattern seems to suggest.

It's at this point in the conversations I've had about this topic that a variety of ASP.NET content management systems are brought up. The problem with all of them that I've checked out from this angle boils down to what you consider the "center" of the app.

If your app is mostly content, with some custom functionality, these CMS solutions can work well. That's because all of them push you to do your custom functionality as a plugin to their framework. Beyond that, most of them don't handle or do well with things like variables being embedded in random paragraphs, extreme personalization, switching out paragraphs based on roles, etc.

OK, so that leads to using a CMS *library*. I looked at a few of those too. Several didn't do variables at all, another few were basically just wiki article storage, another few made everything "news" or "blog posts" and shoehorned it into that. The choices left me a little cold.

After looking at all of these possibilities, I wanted to take a stab at exploring a solution in a "hands-on" way as that approach tends to let me really get inside the problem. Often after working through a proof of concept, even if I end up going with one of the pre-packaged solutions, I can do a much better job of picking the right one and understanding the pro's and con's of each.

So, I took a bit of time to run through this problem and work it out in POC code.

The first place I looked was at the alternate view engines for MVC. Several of them look interesting, but I'm planning on sticking with the default WebForms engine for all of the non-content functionality. That actually means not using the alternative view engine that actually implements the technology that I ended up using in my POC.

There are reasons for sticking to the WebForms view engine for at least the short term. One of them is that the default path inside the MVC ecosystem is going to get the most attention to work through patterns that work. Another is to leverage familiarity in the area where the hardest work has to be done in these apps (the custom business logic and rules). Several of the projects involve other devs, so going to MVC is already going to be an adaptation for them (though one I think is worth it).

OK. On to what I did in my POC. I knew that I wanted to leverage a templating system in some way. One that came up over and over when doing research was Jakarta Velocity, a Java solution from the Apache Foundation (a group that usually thinks things through pretty carefully).

NVelocity brings that engine to .NET, but hasn't been updated since 2003. Fortunately, the folks over at the Castle Project picked NVelocity up and have been maintaining it improving it as well. As I mentioned earlier, NVelocity is also one of the alternate view engines. Though I have reasons for not using it in that way, it is an additional vote of confidence for it.

NVelocity templates are written in the Velocity Templating Language, which gives all of the elements I need for the problems I'm looking at right now.

The first problem I did run into when using NVelocity inside of my POC MVC app was that the basic Castle implementation wants the NVelocity templates on the disk as files. That defeats most of my purpose here as I want the templated content to come out of the database and be editable there as well.

Fortunately, this CodeProject code adds the ability to use NVelocity with a template that comes from
a string instead of having to have them in individual files on disk by creating a memory-based engine implementation.

I basically aimed to have pages made up of snippets for this POC. A PageController action of Details() takes a string I called "Slug" which is the URL-based name of the requested page. That base page is loaded and is parsed for tokens that point to template snippets. Those snippets are then integrated into the composite template before feeding it to the NVelocity engine.

I chose a token for handling includes (double braces on each side of the named key). My initial proof of concept only did one level of inclusion: a page and snippets of content, but this method could handle whatever level of recursion that's necessary.

So, a page named "home" could have a token:

{{user-details}}

which would be replaced by the snippet of template code that has the unique key "user-details" from the content repository. The recursion would be handled by tracing through the tree of those included tokens for a given page until the nested tree is built.

The controller needs to build up objects that fulfill all of the variables in the templates. A production implementation of this would need to provide a way to report on the dependencies that a given composite template requires to avoid empty slots.

However, since NVelocity handles doing things like passing objects more complex than basic strings, this can be much easier than it might be otherwise. So, you can do something like pass (User)CurrentUser to the template, which can have properties pulled into the template from there. By passing that one object, you can have a template like:

The account for $CurrentUser.FirstName $CurrentUser.LastName is currently $CurrentUser.AccountStatus with a balance of $CurrentUser.AccountBalance

That ability also handles one of the peripheral problems I hadn't included as part of the scope of this POC, but became an obvious fit along the way: internationalization. If you provided an object with all of the label text, button text, menu names, etc. as UTF-8 text in the properties, you could fill all of those bits in as:

$Labels.Home | $Labels.AboutUs | $Labels.MyAccount

Overall, I like the flexibility and don't see anything really standing out as a roadblock to this solving the CMS needs I have in this range of projects. There will definitely have to be some work on the back-end administration of this content to catch missing objects and judicious use of caching of both objects and composite templates to keep it from slowing things down, but I think those are definitely solvable.

NVelocity handles the kind of dictionary objects I'd like to hand off to CMS pages, conditional rules, basic looping, etc. At the same time, it lets you manage most of this stuff outside of code (provided that you provide some decent structure to the objects available to the PageController for all of the pages (things like CurrentUser, SiteSettings, ThemeInformation, etc.).

That ThemeInformation object actually hits on one other requirement of one of the projects in particular where I need user-defined theming for things like fonts and colors, thus lining up the birds nicely for a stone to be thrown.

The template language is pretty much just basic HTML with simple variables and loops, making it pretty easy for people outside of the dev team to work with as well, without a WYSIWYG editor (which would make the back end a much bigger pain to develop). It also can be re-used for template-based emails from these same systems pretty much wholesale.

At this point, I'd really like input on the approach and opportunities to improve it. Solving this problem well is something that will make all of my MVC projects much easier and be really re-usable.

Sit on Your Butt and Watch Movies Day

Oct
01
2008

Creative Commons Licensephoto credit: Usonian

A few years back (I can't really remember exactly when), my lovely wife looked at the calendar, and, seeing my birthday a week ahead, asked me what I wanted to do for the day. That wasn't the first year she'd asked that question. However, it was the first where I came up with anything other than a shrug an "I don't know".

When she asked that time, I stopped and gave it some thought. A few moments later, an answer tumbled out of my mouth, "What I really want to do is spend the day sitting on my butt and watching movies, with the laptop in front of me".

Once said, I realized that it was really exactly what I did want to spend my birthday doing. Holidays all celebrate something. Birthdays are celebrations of specific individuals and the things they enjoy. For lots of people, that celebration involves large groups of people, noise, loud music and a great deal more activity than I have ever really enjoyed.

I do, however, really enjoy chilling out and watching movies in my home theater, while messing around online and writing code for my own purposes. Thus was born the first Sit On Your Butt and Watch Movies Day.

The first one turned out to be an amazingly great day, humble though the activities may be. I chose movies entirely based on what *I* felt like watching, had a couple of tasty meals, and thoroughly enjoyed myself.

After that, when people asked me how I spent my birthday or how I was going to spend an upcoming one, I would relay my new tradition. What surprised me is just how many people seemed to stop for a second, think about it and say, "You know, that's a really good idea.".

Clearly, this day has an appeal for lots of people and every year, more and more people join in. However, I have been asked for what the "rules" are. Given how I didn't exactly start this as some sort of grand vision, I have pretty much just made on-the-spot rulings on people's questions.

My birthday is coming up this coming Sunday, and I figure I might as well share a more "structured" version of the holiday for those who want to join in on the laid back fun. Since the main day is on the weekend this year, things are wide open if you'd like to join in.

Suggestions on this list are welcome and those that strike my fancy will be included in next year's revised definition.

Your Guide to Sit On Your Butt and Watch Movies Day

  1. Sit On Your Butt and Watch Movies Day is a laid back holiday. Where any rule would cause you stress or discomfort, the rule should be deleted.
  2. Sit On Your Butt and Watch Movies Day is celebrated on October 5th (J Wynia's birthday), your birthday or the birthday of someone nearby.
  3. If those days are inconvenient, choose the nearest weekend day.
  4. There is no limit to the number of celebrations in a calendar year.
  5. Whenever possible, the day should be without work, either employment or house-related.
  6. The number of movies to be watched must be at least 2, ideally 5-8 and limited only by your definition of "day".
  7. The primary celebrant shall be the holder of the remote control and, should an all-in-one universal remote not be available, the holder of all of the remotes for the duration of the celebration.
  8. The movies to be watched must be either personal favorites or movies you haven't seen before. Any movie which might inspire a "meh" should be left in the DVD stack until later. There are to be no compromises or sacrificial choices for the sake of others in the room.
  9. Any movie which causes the celebrant to think to him/herself, "Why am I still watching this?" should be ejected immediately and the next movie on deck begun. Letters to the producer/director/lead actors about how they ruined your own personal holiday are entirely optional, but should wait until the next day.
  10. Because the movies can't be paused while you visit the bathroom or get snacks at a theater, Sit On Your Butt and Watch Movies Day is best celebrated in a home theater.
  11. There should be a comfortable seating arrangement, temperature adjustment and lighting levels. Suggested configurations tend toward dimmed lights, slightly cool temperatures and an overstuffed recliner or sofa. Seating choices which allow the feet and heart to be on the same level are optimal.
  12. There shall be no talking during the movies. Or, if the celebrant is one who is prone to talking during movies, there shall be little silence. Whatever. Either way, recitation of catch phrases and favorite lines along with the actors are welcome, but should only begin when the celebrant starts it.
  13. The snacks must be many and diverse, covering all of the snack groups: salty, sweet and savory.
  14. The meals should be delivered or otherwise easily obtained during short intermissions.
  15. The celebrant's beverage of choice must flow freely. While the official beverage of Sit On Your Butt and Watch Movies Day is Coke Zero, that should in no way influence the beverage choice.
  16. In case the snacks and meals may prove to exceed the digestion capacity of the celebrant, antacids and/or Pepto Bismol must be readily accessible.
  17. To provide the best movie roster, the movies should be planned in advance, saving particularly desired movies just for the day.
  18. Showering or communicating anything more sophisticated than grunting is entirely optional.
  19. Finally, should the nearest celebration be too far away to be bearable, emergency celebrations can be declared at any time. It's *somebody's* birthday.

This year's stack of DVD's looks like this, with a couple of slots still open:

  • Iron Man
  • Run Fatboy Run
  • Leatherheads
  • The Forbidden Kingdom

 

J Wynia

For better or worse, I'm the guy who runs things here. I'm a web consultant, software developer, writer and geek from Minneapolis, MN. This site is a fairly wide cross-section of the things I'm interested in and enjoy writing about. If you'd like a more "real-time" slice of my thoughts, you should follow me on Twitter here.

Oh, and if you happen to be looking for hosting for your Subversion repositories or just web hosting in general, take a look at Dreamhost. It's what I use for Subversion and your signup helps me out.

Feeds and Links


www.flickr.com
This is a Flickr badge showing public photos from J Wynia. Make your own badge here.

Search


Pages

Archives

Computers Blog Directory
© 2003-2010 J Wynia. All original content is licensed under the terms of the Creative Commons Attribution license unless otherwise noted. Content from other sources is licensed under its original terms.