Spirit of 1999

Tuesday, December 6th, 2005

Wow. I haven’t seen an online store this bad in years. I know there are still a lot of crappy marketing sites out there, but most sites trying to immediately close sales long ago figured out that fancy tricks stop customers from buying. Not these folks.

It took me four or five tries to figure out where to click to see the page for the product I was interested in. On the third try I actually ended up on a page for a similar but slightly different and more expensive DVD burner than the one I was looking for. Initially I thought this was bait and switch, but one should never attribute to malice what can be explained by simple stupidity. I did eventually find the page for the product I wanted. Of course, this page promptly refused to sell me the drive because I didn’t have cookies turned on.

Birds on Rails, Part 3

Saturday, December 3rd, 2005

Now I want to create a new page that lists all the species in the birds table. That is, it looks like this:

Brooklyn Bird Report Master Bird List

  • Fulvous Whistling-Duck Dendrocygna bicolor
  • Greater White-fronted Goose Anser albifrons
  • Snow Goose Chen caerulescens
  • Ross’s Goose Chen rossii
  • Brant Branta bernicla

This will live in the file /masterbirdlist.rhtml

How to do it? I begin by creating a regular HTML file named masterbirdlist.rhtml and putting it in the app/views/bbr directory, but that doesn’t work. It just tells me “Unknown action No action responded to masterbirdlist.rhtml.” OK. Looking back at the notes from Day 1, I see how to handle that. I add this method to the bbr_controller.rb file:

def masterbirdlist
  render_text "Hello"
end

Now I get “Hello” for the masterbirdlist. Of course that’s not what I want. I want to load the masterbirdlist.rhtml file. How do I do that? About this point I begin wondering what the manual says. Googling for it, it appears that there isn’t one. That compares very unfavorably with PHP and Java, both of which at least have documentation, not to mention reams of third party books available. (Later I found this site, but it doesn’t appear to be a true comprehensive manual; just a random collection of HowTos.) However, there does seem to be some API documentation which mentions render_file() methods. Maybe that’s what I need? No wait. I remember this now. I bet I have to generate a controller for the masterbirdlist:

~/Web sites/bbr$ script/generate controller masterbirdlist
      exists  app/controllers/
      exists  app/helpers/
      exists  app/views/masterbirdlist
      exists  test/functional/
   identical  app/controllers/masterbirdlist_controller.rb
   identical  test/functional/masterbirdlist_controller_test.rb
   identical  app/helpers/masterbirdlist_helper.rb

That seems to work. I thought this was just for mapping to database tables, but apparently it’s for all pages. This gives me the “Unknown action No action responded to index” at /masterbirdlist. But I’ll create a view for this in app/views/masterbirdlist/index.rhtml. Bingo! That works.

Now let’s add the code to generate the list of species:

<ul>

 <% @birds.each do |bird| %>
  <li><%= bird.common_name %></li>
 <% end %>
</ul>

This produces

NoMethodError in
Masterbirdlist#index

Showing app/views/masterbirdlist/index.rhtml where line #14 raised:

You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occured while evaluating nil.each

So now I have to create the birds variable. Thus I add this code to the masterbirdlist_controller.rb:

def index
  @birds = Bird.find_all
end

Now I get this error:

NameError in
Masterbirdlist#index

uninitialized constant Bird

I suspect this is because I haven’t mapped that table in Rails yet. i.e. I haven’t generated a model for the birds. Let’s do that:

$ script/generate model Bird
      exists  app/models/
      exists  test/unit/
      exists  test/fixtures/
      create  app/models/bird.rb
      create  test/unit/bird_test.rb
      create  test/fixtures/birds.yml

And now the page works. OK. I ‘m starting to get the hang of this. Adding the genus to the list is easy:

<% @birds.each do |bird| %>
  <li><%= bird.common_name %>  <i><%= bird.genus %></i></li>
 <% end %>

Now let’s add the species:

 <% @birds.each do |bird| %>
  <li><%= bird.common_name %>  <i><%= bird.genus bird.species %></i></li>
 <% end %>

Oops. That didn’t work:

ArgumentError in
Masterbirdlist#index

Showing app/views/masterbirdlist/index.rhtml where line #15 raised:

wrong number of arguments (1 for 0)

Hmm. Do I just need to put that in two separate tags or do I need to learn how to concatenate strings or terminate statements in Ruby? Concatenating seems to work; and it uses the plus sign, same as in Java:

 <% @birds.each do |bird| %>
  <li><%= bird.common_name %>  <i><%= bird.genus + bird.species %></i></li>
 <% end %>

However, it turns out I forgot a space, so I might as well just go ahead and use two tags anyway:

 <% @birds.each do |bird| %>
  <li><%= bird.common_name %>  <i><%= bird.genus %> <= bird.species %></i></li>
 <% end %>

I think that’s as far as I’m going to go tonight, but just maybe I am speeding up a little past what I could do with PHP (though I still don’t fully grok how the site is getting organized, and the URLs mapped.)

To Blog or Not To Blog

Thursday, December 1st, 2005

Cafe au Lait dates back to 1995. I know I’m not the first blogger. Ric Ford’s Macintouch precedes me, and probably others do as well. However, I was there quite early on, I think before the word “blog” was coined. Truth is I’ve never even really thought of Cafe au Lait, Cafe con Leche, and The Cafes as blogs, even after I added RSS feeds. Most obviously they’re organized by date rather than by post. And despite occasional off-topic posts, I mostly keep them focused on Java and XML respectively.

However, Mokka mit Schlag is very much a blog. It looks like a blog. It feels like a blog. It reads like a blog. Most importantly for me, it writes like a blog instead of a static set of web pages. Most importantly for you, the reader, it is no longer limited to one topic. Here I feel free to expound on any subject that wanders into my field of vision. I have carefully categorized posts so my birder friends can read about birds and my programmer friends can read about programming and my family can read my travel stories, without having to pay attention to the parts that don’t interest them; but I still get to write about anything I like; and that’s a good thing.

Birds on Rails, Part 2

Wednesday, November 30th, 2005

Rails seems to be installed and working (Finally. That took almost a full day.) so let’s see if we can build some real pages. The first thing I need is something simple. I want to iterate through the sites table in the database and print each name in the site into an HTML unordered list. The SQL command is as follows:

SELECT name FROM sites

(It will be a little more complex in the future, but let’s start simple and add to it.)

Rails embeds Ruby code in HTML using <% %> and <%= %> markers. Here’s another downside. This is not well-formed XML. PHP correctly uses processing instructions for this. Rails should have copied from PHP instead of JSP/ASP.

So I went ahead and added this chunk of code to the index method that’s creating the main page by calling render :text.

 <% @sites.each do |site| %>
  <li><%= site.name %></li>
 <% end %>

Hmm, that completely didn’t work. Apparently I first need to create a view. That is, I need to create a file called index.rhtml in the app/views/bbr directory. Then I need to delete the index method in the bbr_controller.rb file. Then I put my Ruby code into the index.rhtml file instead. Then in bbr_controller.rb I put this code:

def index
  @sites = Site.find_all
end

This maps the sites variable to the sites table so I can reference it in the view rhtml file. And voila. The index page now pulls the list of site names out of the database and inserts them into the web page as desired.

More CSS Layout Madness

Tuesday, November 29th, 2005

I remain convinced that the whole CSS layout mess was poorly thought out, poorly designed, and poorly explained. Yes, it’s hobbled by poor implementations too; but can you really blame the poor implementers when the spec writers could never explain exactly what they meant? Proof of this is just how incredibly difficult it is to reproduce simple, basic, liquid two column layouts any third grader can throw together in five minutes with tables.

The latest problem I’ve noticed comes on this site when the post is not long enough to match the sidebar. For example, take a look at Links Matter. The Google ads end up below the text instead of to the right as they should. Or the Mac category page where both the Feed list and the ads disappear below the text. That is the “column” shifts left as soon as possible.

There’s probably a break or clear or keep property I can set somewhere to make this come out right, as long as the font or window isn’t too big or too small, of course. But why should I have to? Why couldn’t CSS layouts be based on liquid nested tables like the ones proven to work by years of experience? Why invent something new? Note I am not suggesting that HTML tables be used for layout; only that CSS define its own table layout independently of any HTML tables in the document being styled? Not only would this be simpler to code against and implement. It would handle some tricky cases in three column layouts with large and small fonts that CSS still can’t manage. (See Cafe au Lait for one example.) Even Java has finally learned what’s been obvious to web designers for years: tables are the natural way to layout a page. However the W3C still hasn’t figured this out.

Oh well. It’s probably too late to fix this now. But please, if you ever find yourself inventing a new layout scheme, be it a stylesheet language, a GUI layout manager, or something else; please, please try to organize it around two-dimensional nested tables rather than something that only appears to be simpler.

Meanwhile I think I fixed it by floating the sidebar to the right at the same time the content was floated to the left. That is, I changed

#sidebar
{
	padding: 20px 10px 10px 0px;
	}

to

#sidebar
{
	padding: 20px 10px 10px 0px;
    float: right;
	}

This works, at least in Firefox. However In Safari, it pushed the sidebar always completely below the content. Back to the drawing board I guess.

Safari Breakage (+ a shoutout to IE)

Monday, November 28th, 2005

Hmm, seems some recent CSS change broke the sidebars in Safari 2 on Tiger. Safari’s CSS support is quite good; so it’s more than likely my bug (though Firefox does render this site as I expect). I’ll try and figure out what’s going on and fix it. In the meantime, if anyone is using Internet Explorer to view this site, please let me know how it looks. Thanks.

OK. I see the problem. It’s this rule for the search form text field:

#sidebar #searchform #s {
	width: 55%;
	padding: 2px;
	}

I can change that to

#sidebar #searchform #s {
	width: 15%;
	padding: 2px;
	}

Then Safari works. However, the search box gets too small in Firefox. I suspect the two browsers are measuring that 15/55% against different elements. One’s probably measuring against the page and one against the parent, or some such. So let’s try font-relative units instead. 8 em should work nicely:

#sidebar #searchform #s {
	width: 8em;
	padding: 2px;
	}

That looks about right and seems to work well in both browsers.