21 November 2007

Android!



For those who don't know (somehow), Google has acquired and released their platform for "iPhone killer" phones. It's called android. Seems like this is a good chance to practice building phone apps, especially since it doesn't involve learning Objective C.

I think it could be a fun way to spend the day-after-Thanksgiving. Also, please enjoy my requisite self-referential pic of the new phone, like I did for the iPhone.

17 October 2007

IMAP, how I missed you!

Dear GMail,

I'm leaving you because you didn't fulfill me the way a real mail service can. It was great that you were free, but free POP3 doesn't fill that spot in my heart the way a paid IMAP can. Back in college, I promised to be forever faithful to IMAP, but you were sexy, and I needed a mail agent so badly, it was easy to fall for you.

This morning, I knew I made the right choice. I flipped through my mail on my phone on the way to work, and deleted some things, and when I got to my computer at my desk, the mail was deleted. My drafts and outbox are on the server too, so I can start an email on my phone and finish it later.

I know, you expect me to use your interface. I'm supposed to use my browser when we hook up. Even with beer goggles, I'm sorry to say, you weren't hot, so I was using native mail apps whenever we talked. I can't even tell you how frustrating it could be when my three mailboxes that you touched your POP3 would get their own separate copies of mail. I think my other friends were upset about our relationship, too, because their messages would get lost in one of the inboxes that I couldn't keep up with.

I know, you wish I could see through the protocol to who you really are... but I can't. I'm so sorry, and by the way, please forward my mail to my new IMAP account. That way I don't have to tell anyone we broke up.
-Me

25 September 2007

Handy tip for layouts in Freemarker

If you're writing a Java webapp and using Freemarker as your templating engine, hooray! Skip to the next section. Maybe this tip will come in handy.

If you're not using Freemarker, you should really consider it. JSP's are ridiculous - why are you compiling all your markup into Java code? Do you like it when you make a small typo in your JSP page, and get an error from the JSP engine referencing the Java code it created to render your page?? Gross, let's go read through the generated code to infer what the typo was! Do you like how the JSP pre-compilation step is annoying to set up, but if you don't, you have the dreaded first request to worry about? JSP's might be a little faster than interpreting markup on each request, but with smart caching, and the ease of adding more web server boxes, that's a dumb reason. And wow, let's give people the ability to write arbitrary controller code in the view, and then trust them to do things the right way instead.

Oh, and if you like Velocity, that's cool I guess. Freemarker is nice because it's a real stickler for correctness - a null value isn't just rendered as a blank string, because it's not (insert scary life-support app example). The model is the model, you can render it, and that's all. Just what you should be doing.

The layout tip


If you've played with (or gotten paid to work in) Ruby on Rails, you're familiar with the "layout" concept. It's just a simple template for a page, and instead of using "includes" where the template has to know what's going to be inserted, it just "yields" to the page content. It's the same philosophy as Struts Tiles - the dependencies between your markup files should go from the bottom up - the content needs a place to be inserted, and the template doesn't care what it is.

This layout method gives you a similarly easy and readable result in Freemarker.

First, let's create a page, with some wishful thinking for how we think the layouts should work:


<@layout.basic>

<a href="/customer/accounts">Browse accounts</a>

</@layout.basic>


That's saying, I'd like to use a layout named "basic" and in the place that layout puts the page content, I'd like to have my link to Browse Accounts show up there. The page is as short as can be, and readable.

Now, let's make it work. It seems I'm calling a macro "basic" and I expect it to be in the "layout" namespace. I haven't used an import macro on my page, so the code for the layouts will be auto_imported into my pages, using the "auto_import" setting in Freemarker's Configuration object. I set it to "/layouts/layouts.ftl as layout" so that the template /layouts/layouts.ftl gets imported to all my pages with the layout namespace. (It has to be that way because Freemarker can only associate one template with each namespace.) If you're using Spring to configure Freemarker, you'd create a props element containing an "auto_import" prop and pass it to the freemarkerSettings property of the FreeMarkerConfigurer bean.

Now I create the layouts.ftl template. This could contain all my layouts, but it would look strange for several of them to live in one file, so instead my layouts.ftl looks like this:


<#include "admin.ftl" />
<#include "basic.ftl" />


Clearly this is where you add additional layouts as you need them.

Finally, let's look at the contents of basic.ftl:


<#macro basic>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
</head>
<body>
<div id="header">
<p>
Cows make moo sounds
</p>
</div>
<hr/>
<div id="content">
<#nested>
</div>
</body>
</html>
</#macro>


This creates a macro named "basic" and uses the nested macro to include whatever appeared in the body of our caller's <@layout.basic> tag.

Neato!

30 August 2007

Work smarter, not harder... and faster!

Maybe it's obvious. When you try to do things really fast, it can actually be slower.

I always thought "A stitch in time saves nine" meant that you should stitch as fast as possible. I think I just assumed that, which I need to be careful of, because when you ASSUME, you make an ASS out of U and ME.

It's certainly true with programming. When it comes down to it, if you look at a finished application, it's conceivable you could just type the code for it in an afternoon, especially if you have good tools that let you express your intent quickly. Of course, you don't know exactly what the code will look like until you start to create it, but let's ignore that for a sec.

So... taking my time and thinking for a second to save time. I was too frantic for the last couple years, and wrote a lot of Log object instantiations.

public static final Log log = LogFactory.getLog(NiceObject.class);

I wrote that a lot, and got a Das Keyboard so I could type it even faster. I knew that Eclipse could do this for me, but there's that nagging startup cost, where the first time I set it up, it would take longer, and I might go looking around for more of the same (or blog about it), making it much longer than typing it out.

Well, lo and behold, I am happy I took the 30 seconds to:

24 August 2007

Correction!

Well, I learned that what I said yesterday isn't quite true. It IS true that the geocoder.us site does a bad job geocoding on this street. You can see their map here:
http://geocoder.us/demo.cgi?address=4050+BEN+LOMOND+DR+PALO+ALTO%2C+CA+94306

BUT, if you zoom in, you see the shape of the street is right, they just have the pin in the wrong place. The maps come from the TIGER/Line data as well as the geocoding. The problem is that the Perl module, Geo::Coder::US, doesn't use one of the data files in the TIGER set - the RT2 "type 2" data. This file is Complete Chain Shape Coordinates which means it has midpoints for some street segments. I found the two midpoints for the street I showed yesterday, and put some pushpins at those spots - and behold, the curvy street problem would go away!

Now, too bad I can't find any libraries (in any language!) that do the same thing as the Perl library, but use the RT2 data...

23 August 2007

Why TIGER/Line can be a bad source of geolocations

I came up with this neat map in Google Earth, showing the difference between Google's coordinates for some addresses in Palo Alto, CA, and a line connecting those to the TIGER/Line-backed geocoder.us coordinate, colored blue-to-red based on how far off it is. The TIGER/Line data only has endpoints for a range of addresses, and the geocoder.us Perl module tries to do a linear interpolation to get addresses in the range. Obviously this doesn't work well for non-linear streets like this one...

17 August 2007

FeedBurner, finally!

I have sort of known in the back of my head that I ought to have my feed managed better. It would be nice to see who is subscribed, both because I don't really want to blog to hear myself talk, and also because you get an incentive to write more interesting and useful stuff if there's an audience.

So I hooked up feedburner, and was pleasantly surprised by how useful it is. Not only do I get my basic readership metrics, it also manages the trick of getting existing subscribers under the metrics (by telling blogger to redirect requests for the feed URL) and lets me fold in daily bookmark digests and photos.

Hopefully my 2 readers (?) will also enjoy my random API and documentation bookmarks (?) and at the same time, my attempts to do film photography (?).

Now I am wondering how to advertise my Twitter and Skype and Facebook and so on. I guess it's good to make them widgets on the right side of the blog, and just assume that one URL will give away my complete identity. Maybe hCard is good for this? I do feel like my "Card", whether it's vCard or whatever, should have my contact info including many URL's, and should be easy to broadcast my card to *everyone*, not just online friends. Then the offline people like grandma get my new phone number, and online people get the skype ID, and all is well.

That would be another reason to try out one of the email->snail mail gateways - I can subscribe my grandmother to my vCard feed and she'll get it via postal mail... slick. Except then she'll call me wondering why I sent her a letter, just because I added a web 2.0 service to my card... maybe I should think about that some more.