Pardon the mess

26 Aug 2007 In: Miscellaneous

I am going to roll out a new look and feel for my blog, since this one isn’t mine. I am going to do this the lazy way, live on the server, rather than setting up an identical local environment for testing. Hopefully it won’t take me too long.

Ruby East Bound

25 Aug 2007 In: Technobabble

I just registered to attend Ruby East 2007 in Pennsylvania at the end of September. Is anyone else going?

Organizing Rails Views

7 Aug 2007 In: Technobabble

This may seem like, and probably is, so elementary that it isn’t worth writing about. I poked around on Google for a bit and couldn’t find the answer though, so it might be worth sharing. Basically I have a Ruby on Rails application with a controller whose corresponding views directory is getting hard to look at. For all my bazillions of partials I prefix them with something so they sort together _pet_detail_comments.rhtml, _pet_detail_properties.rhtml. You get the idea.

As I approach 30 views in one directory though, it starts to get hard to look at. I am an organization freak, so I want to group partials by context and put them in subdirectories:

/app/views/petstore/detail/
/app/views/petstore/checkout/
/app/views/petstore/article/
/app/views/petstore/forum/

When you render the partial you have to use the full path of: controller/subdirectory/partial_or_view. At first I wasn’t using the controller in the path, and you need it for this to work, apparently. So rendering a partial looks like this:

  1. page.replace_html "pet_comments", :partial => "petstore/detail/comments", :locals => {:pet => @pet}

Rubyists always talk about clean, easy to read code. I have always thought that this sort of thing is just as important. Happy organizing.

Breakin’ The Law: Nested Links

26 Jul 2007 In: Technobabble
DISCLAIMER:I didn’t even bother testing this blog posting in IE, though in practice I have made it work in all browsers. If you are using IE, you can go here to fix the problem.

According to the HTML spec, nested links are illegal. Good, fine, OK. Personally I am having a hard time understanding why anyone would want to nest links. I mean, why would anyone want to do this:

  1. <a href="http://www.blizzo.com">Blizzo loves
  2.     <a href="http://www.ajaxian.com">Ajaxian</a>
  3. </a>

The problem is, however, that I can see a need for nested onClick events. Consider the following happy little onclickable characters, the box and the link. Go ahead, click them, you know you want to…

The Box The Link
Oh So Clickable

As my old drafting teacher used to say, “Peace, Love, Happiness Be”. This is all just great. The problem comes when the the sexual tension that has been building between these two for the last three seasons finally reaches critical mass and they become one. We don’t just get a dip in the ratings, we have a problem:

What if when you click the link, I don’t want the div to change color, because in his contract he states he refuses to do color changes with anyone else on the set at the same time. Prima donna <div>’s. A little JavaScript can solve this problem, like so:

  1. <script>
  2.     var freeze_js = false;
  3. </script>
  4. <div class="clicky_div" onclick="if(freeze_js == false){toggle_color(this)};freeze_js = false;">
  5.     <a href="javascript:void(null)" onClick=":freeze_js = true;alert('Oooh, do it again!')">Oh So Clickable</a>
  6. </div>

The freeze_js variable prevents the onClick action of the <div> when the link is clicked, but it still changes color when you click on the div outside the link. You, in the back row, come up here and try it out for the class.

So now that we have everyone playing nicely together, we may even get contracts for another 13 episodes. My question becomes… is this icky? Would you expect everything to fire off when you click, or just the one thing you click on? As web UI’s become more complex, how should we handle this problem? Huh, huh, huh?

What’s Your Walk Score?

25 Jul 2007 In: Reviews

When technology meets geography, I get very excited. Toss in the concept of sustainability/green concerns and I get even happier. In that vein, I stumbled across Walk Score today. You put in your address the site maps various types of businesses near your home and calculates an overall score. If you choose to live near more businesses, your score gets higher.

Improvements:
One problem with walkscore is the distance between your location and the resource appears to be determined mathematically by examining the latitude and logitude of the two locations. This is fine, if your’s superman. Unless I can jump over rivers, scramble over buildings and cross private property, the math doesn’t work out. I assume the problem is that there is no data out there for determining how far it is to walk somewhere, only to drive. Maybe that alone should give us cause for concern.

www.walkscore.com screenshot

My Scores:

  • Home (Denver): 54/100
  • Home (NJ): 15/100
  • Work: 14/100

Multiple Ajax Form Submissions in Rails

17 Jul 2007 In: Technobabble

It has been a while since I have written, but I ran across this age old problem in Rails today and wanted to share my simple solution. Users that double click on submit forms, or multi click when things don’t happen fast enough for them, wreak havoc on web applications. In order to prevent the data from being submitted more than once, there are a variety of approaches, here is mine.

The Ruby (Rails)

In addition to form submission, occasionally we want to throttle down Ajax invoking links to single clicks at a time as well. To accomplish this, we need to look at our use of link_to_remote and form_remote_tag (though this would work for all methods that support link_to_remote options).

  1. # form_remote_tag
  2. <% form_remote_tag (:url => {:action => "save_stuff"},
  3.     :condition => "ajax_in_use == false",
  4.     :before => "ajax_in_use = start_ajax(ajax_in_use)",
  5.     :complete => "ajax_in_use = end_ajax(ajax_in_use)",
  6.     :html => {:id => "html_id_for_form"}) do -%>
  7.  
  8.     # form goes here...
  9. <% end -%>
  10.  
  11.  
  12. #link_to_remote
  13. <%= link_to_remote "click me for ajax",
  14.     :url => {:action => "ajax_method_in_controller",:object_id => this_object.id, :additional_url_parameter => true},
  15.     :condition => "ajax_in_use == false",
  16.     :before => "ajax_in_use = start_ajax(ajax_in_use)",
  17.     :complete => "ajax_in_use = end_ajax(ajax_in_use)"
  18. %>

The things to pay attention to here are :condition, :before and :after. The condition determines whether the call to the back end may be sent, which is controlled through a JavaScript boolean. The :before hook sets the JavaScript variable to show that it is use, and the :after hook releases it. Why not just set the variable to true or false? Using a function allows me to layer in additional behavior to make a more pleasant user experience.

The JavaScript

Now that we have our hooks in place, we need to define the JavaScript functions and variables that are being used. These are all included in an external JavaScript file that is included in the layout.

  1. // initialize ajax state
  2. var ajax_in_use = false;
  3.  
  4. // turn ajax calls off
  5. function start_ajax(ajax_in_use) {
  6.     document.body.style.cursor = 'wait';
  7.     return true;
  8. }
  9.  
  10. // allow ajax calls
  11. function end_ajax(ajax_in_use) {
  12.     document.body.style.cursor = 'default';
  13.     return false;
  14. }

As a small nicety, I change the cursor to ‘wait’ while the Ajax calls execute, helping clue the user in that something is happening. The functions also allow a nice way to do something more complicated in the future. There, thats all there is to it. It isn’t fancy or clever, but it seems to work well so far.

Micropayments for Premium Software

12 Jun 2007 In: Observations, Opinions

I was thinking about the fact that, yet again, there is a new version of Adobe Photoshop out, version CS3. For their standard package, a new user has to swallow a $649 price tag to get in the door. If you are lucky enough to have an older version, you can get into the upgrade for $199. CS2 was released almost exactly one year prior to CS3.

This got me thinking about software prices in general, but I will stick with Photoshop for this example. My guess is that Photoshop has one of the highest percentages of piracy in it’s install base. Adobe gets nothing from those people. A certain portion of those pirates are going to steal it regardless of the price tag, because that’s what they do. I can’t help but wonder, however, how many people say “$650! Screw that!” and hop onto a file sharing network, cutlass gripped mercilessly between their clenched teeth.

Of that latter group, I would guess that some percentage would be willing to buy it if the price tag weren’t so high. So how could Adobe lower that price bar and net the cash from these pirates? Since the upgrade is $199, and the release cycle appears to be 12 months, you are essentially paying $16.60 for the new hotness. Why not offer a service at $20 a month to use the software, possibly with some larger lump payment to get going ($50). Now someone only has to come up with $70 to get into their product instead of $649.

Now the real benefits kick in. Instead of waiting a year for new features, they can roll them out in real time as they are developed, creating a more agile product for their customers. They could also experiment, tossing in features here and there on a trial basis, without some delicate, long impacting consequences.

If adoption of this practice took off, they could even lower the price to grab ever increasing percentages of those fence dwelling pirates, until the inconvenience of finding and implementing the pirated software overshadows the barrier to just plain purchasing it.

Until then, bon voyage!

CSS Indentation

11 Jun 2007 In: Technobabble

I realized today that there is something that I have been doing with Cascading Style Sheets (CSS) for some time that, while it seemed obvious to me, has turned out to be helpful for others. For most web developers, CSS is a straight, static file with definition after definition. Good little programmers will at least provide comments to separate sections or specify the purpose of obscure classes, but thats about it. About the time I switched to pure CSS layouts, and JavaScript free drop down menus (a la suckerfish), I noticed my CSS was getting unmanageable. Go back and look at a style sheet you hacked together last year and see how clear it is to you now.

We indent code for clarity, why not CSS? “But CSS isn’t structural!” you say, “there is no clear way to determine what should nest what”. That is true, but that doesn’t deter me. Layout stuff is easy, since it closely parallels your HTML, which is quite structured.

Consider the following HTML:

  1. <div id="container">
  2.     <div id="left_panel">
  3.         <span class="left_panel_header">I'm so, like, left</span>
  4.         <h4>Some Stuff:</h4>
  5.         <ul>
  6.             <li>One</li>
  7.             <li>Two</li>
  8.             <li>Three</li>
  9.     </div>
  10. </div>

Your CSS could look like this:

  1. #container {
  2.     background-color: #336699;
  3.     color: #ffffff;
  4. }
  5. #left_panel ul li {
  6.     text-indent: 20px;
  7.     font-weight: bold;
  8. }
  9. h4 {
  10.     color: #00FF00;
  11.     text-align: right;
  12. }
  13. #left_panel ul {
  14.     margin: 0;
  15.     padding: 0;
  16. }
  17. #left_panel {
  18.     float: left;
  19.     border: 1px solid #AACC00;
  20. }
  21. html, body {
  22.     font-family: Georgia;
  23. }

Now, there certainly isn’t anything wrong with the above CSS, it’s quite functional. However, over time it will become hard to read, and subsequent modifications will take more and more time. This is how I would create it:

  1. /* "header" definitions */
  2. html, body {
  3.     font-family: Georgia;
  4. }
  5. /* Page container */
  6. #container {
  7.     background-color: #336699;
  8.     color: #ffffff;
  9. }
  10.     /* Left Panel */
  11.     #left_panel {
  12.         float: left;
  13.         border: 1px solid #AACC00;
  14.     }
  15.  
  16.         /* left panel menu */
  17.         #left_panel ul {
  18.             margin: 0;
  19.             padding: 0;
  20.         }
  21.  
  22.             #left_panel ul li {
  23.                 text-indent: 20px;
  24.                 font-weight: bold;
  25.             }
  26.  
  27. /* Global style definitions */
  28. h4 {
  29.     color: #00FF00;
  30.     text-align: right;
  31. }

As you can see, this is much easier to read. As soon as you start analyzing the CSS that defines what is in that left panel, everything sort of makes sense. Likewise, our override for H4 has nothing to do with the left panel, so it is aggregated into a lower section of the CSS. Had we defined #left_panel h4 {}, I would have put in the indented portion for the left panel. And of course, our comments will make sure that 6 months from now, when I am asked to update the CSS for the page, I can do it with little trouble. Comment well, and comment often. Comments and whitespace are free!

For the past few years I have taken this for granted, but now that I think back, every web developer that has seen my style has adopted it for themselves, which means it at least merits sharing. Hopefully this will help a few of you, especially the ones that write hundreds of lines of CSS.

To Mock Or Not To Mock

5 Jun 2007 In: Technobabble

Testing. For most developers, it lurks like a cancer in the back of our brains. You know you should be writing tests, and you should be writing them now, but… well, let me just get this thing working first. At RailsConf I attended several talks, and a tutorial, on testing. While I didn’t get much in the way of concrete knowledge to get started writing tests, I did drink the testing Kool-Aid and I am on my way to becoming a Test Driven Development/Behavior Driven Development advocate.

All of that said, I don’t have enough experience writing tests to be an expert, but this conversation I had today seemed worthy of sharing. When do you use a mock. I uttered a phrase that received a lot of head nods towards the tail of the conversation:

“Mocks are bug aggregators”

If you decide to use mocks in your testing, you are essentially saying “I have no way of testing this for real” or “This is too hard/time consuming/boring right now”. That isn’t to say that mocks dont have their uses, like mocking data that comes to or from a remote system, but they don’t actually test true functionality. If they did, we wouldn’t call them mocks.

What a mock does is create a choke point for aggregating bugs. If you don’t have time to write tests for part of your system, you can mock it, and then when bugs arise that slip past your tests, you have a good idea where to start looking. Of course, good little programmer girls and boys will write tests instead of mocks, but sometimes reality usurps idealism.

Homesick

5 Jun 2007 In: Family, Miscellaneous

In some sort of cosmic intersection of experience and psychology, both Amy and I are very homesick today. While my work at Vonage is going very well, we miss the closeness of our friends and family in Colorado. For cathartic purposes, here is a small list of the things I am missing during this slice of consciousness:

About this blog

This blog is a dumping grounds for my experiences as a web developer, a parent, an artist, a writer and a human being. Maybe someday there will be something here that is worth your time, some sort of useful information or words that piece your very soul. Probably not though.