$200 Price Drop on Apple iPhone

iPhoneI’m probably the last person who cares to actually find out about this, but last night Apple dropped the price on the 8GB iPhone from $599 to $399! And they added new touch iPods that are basically the iPhone without the phone (but with the web features and apps) that start at $299.

I still need a MacBook Pro first and I’m still debating whether or not to wait for the next rev on those before buying one. They’re in the middle of their product cycle, so it’ll be at least another three months before new versions come out. The smart thing to do is to wait.

How does Apple make their products so appealing that it is physically difficult to not buy them? Every day Apple makes the case for why design is so important.

Icons, Icons, Icons

I’ve recently come across a wealth of icons from various sources. At first I thought “I’ll keep all these to myself so I can impress my designer friends,” but then I thought “what else am I going to blog about?” So I decided to share them. Besides, sharing is cool too — just ask the creators of all these amazing icons:

Several of the icon sets were designed as desktop packages, but because the icons are individual PNG files (in most cases), they’re perfect for web design too.

I feel like I’ve been living under a rock. If the above list doesn’t satisfy your craving for icons, then you have to check this out:

Icon Themes on Wikimedia Commons

Edit: Also check out Icon Finder

Please check out the licenses and follow the rules when using these icons. The licenses are legally binding and it’s the right thing to do. The designers have put in enormous amounts of time and, in most cases, just want credit for their work. I think that’s the least they deserve.

Digging Digg

Lately I’ve been coming across a lot of really cool stuff on the web via a variety of sources. The most recent of which has been Digg. I had heard about Digg for years but a system to rank popular news stories just didn’t interest me that much. I finally took a look at the site and I was an immediate convert. The design category is fantastic.

class.pagination.php

Download this file

I’ve been meaning to simplify my work / life by creating some classes that I can use to streamline a lot of the projects that I work on. I found myself with some time this week and finally took a small step in that direction by creating a pagination class.

Up until now I’ve used a function that I wrote way back when for paging. It was clunky, kludgy, and limited. I looked around at what was available online and what I found was, for the most part, clunky, kludgy, and limited.

Starting from my existing code, I laid out some goals for how I wanted my new pagination object to work:

  • It had to be very simple to integrate. I wanted to be able to drop it into a file and have it just work.
  • The output had to be semantic, valid (X)HTML that would be easy to style with CSS.
  • I wanted options for how the links would display.
  • It needed to have options to output clean URLs (for when I’m using mod rewrite) or normal URLs with ugly query strings.
  • It needed the option of using sessions to store SQL queries since, much of the time, this would be necessary when using clean URLs.
  • It had to be drop-dead simple to configure options, such as how many pages to display per page, enabling mod rewrite functionality, enabling the use of session data, etc.

The idea for using sessions and clean URLs came from Ben Jamieson / Thyme Online. I’m also going to credit him with the idea for highly compartmentalizing the code used in the class (he has a highly compartmentalized pagination class of his own with sessions and clean URLs…) even though I remember what his code looked like when I first met him and I think this may be a case of the student becoming the master!

If you’re wondering why I wrote my own class instead of just using his, well, there were a couple of reasons:

  • I wanted the practice (I re-read the chapter on OOP in my PHP book before starting).
  • I’m an idiot: I was concerned about security and I didn’t realize the session data was only storing a session ID in the client side cookie and not the actual SQL queries. I initially wrote this class to include Alexander Valyalkin’s most excellent md5_ encryption and decryption functions.
  • There were some things I wanted to do differently.
  • And because I already had my own paging code that I wanted to adapt.

If you already have something in place to handle pagination, a lot of this code will probably look familiar — there aren’t that many ways to skin this particular cat — but hopefully this code is clean enough and reusable enough that some people will find it useful.

A Simple Example

<?php
   include_once('class.pagination.php');
   $sql = "SELECT * FROM table_name";
   $paging = new pagination();
   $result = mysql_query($paging->paginate($sql));
   while ($record = mysql_fetch_assoc())
   {
      // Output records here
   }
   print($paging->getLinks());
   print("<p>".$paging->getCount()."</p>");
?>

The above example is the simplest usage. The class is included, the object is initialized, the SQL code is passed and returned with the LIMIT clause appended (note: it will replace any existing limit clause) and the links are output.

Sample Output

For large sets of data, ten or more pages, first and last links are added to let users quickly jump to the beginning or end of the data set. Otherwise, just the pages and previous/next links are displayed. You can change that by passing an optional variable to the getLinks() function or, if you’re going to output multiple sets of paging links on a page, you can override the default format via the setDisplayOptions() function (see description of this function below for more details).

Available Functions

paginate($sql) – This function initializes several variables and returns a modified SQL statement with a LIMIT clause appended to it.

setDisplayOptions($x) – This function changes how pagination links are output for a given page. It takes a numeric value between 1 and 4:

  1. Only show the first and last links for large data sets (ten or more pages). Only show previous link when not on the first page. Only show next link when not on the last page. This is the default setting.
  2. Always show first and last links. Always show previous and next links.
  3. Never show first and last links but always show previous and next links (the Flickr option).
  4. Never show first and last links. Only show previous link when not on the first page. Only show next link when not on the last page.

You can achieve the exact same functionality by passing this variable in the getLinks() function. Both of the following examples output the same thing:

<?php
   // Example one
   $paging->setDisplayOptions(3);
   print($paging->getLinks());

   // Example two
   print($paging->getLinks(3));
?>

setPageSize($x) – Override the default number of items to display per page. The default is 25.

setModRewrite(TRUE) – The default value is FALSE. Override this if you plan to use mod_rewrite to create clean URLs. If you don’t know what this is, leave it alone.

setUseSessions(TRUE) – The default value is FALSE. Override this if you have complex SQL statements that you don’t want to pass via query strings. You’ll probably need to enable this if you’re using clean URLs.

setSessionName($name) – This just exists to prevent any possible conflicts with existing code. The default session name is ‘searchdata‘. If, by any chance, you already use a session variable with that name, you can override the name used by the pagination class.

This function can also be used if you plan to store multiple SQL queries by assigning a unique session name for each query.

getSQL() – What goes up, must come down — or better put: what is input, must be output. You pass a SQL statement to the pagination object; this function returns that SQL statement to you with the LIMIT clause appended to it.

getCount() – This returns the “Displaying from x to y of z” string. It gets its own function so that it is easy to omit if don’t want to display it.

getLinks($x) – This is the meat and potatoes. This function returns the list of links for output. It accepts the same numeric option that setDisplayOptions($x) uses.

Miscellaneous Notes

Regardless of whether you use clean URLs or not, the the current page is determined by the $_GET['page'] variable. The page variable always needs to be the last part of the query string or path. Examples:

  • domain.com/articles/title/5/
  • domain.com/article.php?name=title&page=5
  • domain.com/search.php?keywords=xyz&sort=desc&page=2

The first example above is using mod_rewrite.


To use sessions, you first have to initialize the session data with:

<?php
session_start();
?>

If you are using cookie-based sessions, you must call session_start() before anything is output to the browser. For more information on how to use session_start(), see the php.net website.


You can view the source code of this page and the associated stylesheet to see how the links are output and how I’ve styled them.

If you have suggestions regarding this class, please leave a comment. Also, this isn’t heavily tested, so if you find a bug (I’m sure there will be some) please let me know about it.

Download this file

One Month Birthday

Ashton Gregory Clussman

Today is Ashton’s one month birthday. He’s changed so much in a month. He’s grown. He’s gained weight. He’s lost hair. And he is curious about the world. Looking back over the last month, it breaks down pretty much like this:

  • Week 1: This breathing thing is new. And the food goes in where?
  • Week 2: Wait, the food comes out??
  • Week 3: How?
  • Week 4: Okay, I’m starting to get the hang of me. What’s with the hairy guy?
  • Week 5: Hey, he’s kind of funny.

He stares at everything now. He tries to reach out and grab things. He is awake all day, which means he actually sleeps part of each night. Karina is jealous because Ashton wants to play with daddy — he smiles when I talk to him — but I’m just the “play” parent right now. She’s the Bringer of Life. He looks to her for sustenance and comfort. He won’t sleep for me. We don’t nap together. When Ashton is with his daddy, he expects this monkey to dance.

And that’s cool with me.

What Day Is It?

I know it’s Sunday only because the clock on my computer is telling me it’s Sunday. Things have gone pretty much as we expected them to. We took “Child Preparedness” classes and spent the last month or so watching A Baby Story and Bringing Home Baby on TLC. And we weren’t completely clueless to begin with.

Baby does the following and only the following: sleeps, pees, poops, feeds, cries. That’s it. You’re on his schedule and not the other way around. I think most people know this beforehand but it is hard to understand the impact it will have on you. Sleep is a luxury. Eating is a necessity, but the quality of the food is a luxury. You eat what you can, when you can.

We’re stuck in the hospital for at least another day. Maybe two. The room is tiny and with my cot folded out there is barely room to move around in it. Sitting on a cot doesn’t provide much back support. We’re both feeling the pain in our lower backs. It’s overcast so there isn’t much light coming through the window. With little interaction with the outside world, the odd hours we’re keeping, and the lack of sunlight, it’s really hard to keep track of the time…or even the day.

When Ashton smiles the whole world lights up, but at two days old, he mostly just stares at me or sleeps. When he sleeps one of us sleeps too. He’s having a lot of problems with gas, so he cries and screams through most of the night. It’s hard to take a turn sleeping when he is screaming. Not because of the noise but he’s suffering and you don’t want him to suffer.

We’ve posted some more pictures to Flickr and we’ll continue to post pictures there as we take them. (The updated iPhoto plugin lets us go from camera to Flickr in two quick steps–which is nice.)

I’ll try to post again later.

Introducing Ashton Gregory Clussman

Hey Everybody,

It’s been a long day. Karina’s contractions started last night. Around 3:30 AM this morning they reached a point where we could get admitted to the hospital. Things were going well for a little while but then the labor stalled. And stalled. And stalled. The doctor tried to jumpstart things with Potocin but it just wasn’t happening. A little after two the decision was made to do a C-Section.

Little Ashton was born at 3:11 PM CST.

He weighs 7lbs 11oz, is 19.5″ long, and has a 14″ diameter head. With that head the C-section was a foregone conclusion but none of us knew that at the time.

We’ve had a chance to take some photos and you can see those here.

We’re going to try to get a little bit of sleep now.

Today is the Day

We were admitted to Seton Hospital about 30 minutes ago. Karina has been having contractions non-stop for days now but they finally met the 5-1-1 rule: five minutes apart, one minute in duration, and consistent for at least an hour. Today, Baby Clussman will be parolled.

Baby Watch

I’m going to start pointing everybody to this space for updates, especially the non-update updates, which is what this is: baby still isn’t here. Karina has continued to have contractions all day but they’re still not consistent. The birthing ball seems to be working wonders–she gets a contraction five seconds after she sits on it. We’re also going for walks and trying other ideas to help jumpstart active labor.

Womb = Attica

There is some irony that Karina is finally ready for Baby to come out and now he’s the one who isn’t cooperating. I’m convinced that, up until now, she’s kept her legs tightly crossed and was busy summoning all of her willpower to keep him locked away until she was ready for him. Baby was a prisoner in her womb. I’m sure of it!

Monday she started getting contractions at around 9 AM. They were stronger than the ones she had all last week, more consistent, and the pain from them went from her back through to the rest of her body. The contractions lasted all day and into the night. It was okay though because she was finally ready.

We went to the doctor’s office at 1 PM but there were no doctors. They were all off delivering babies. There were no nurse practitioners. They were all off delivering babies. In fact, there was nobody to do an exam. The nurses hooked Karina up to a fetal monitor and recorded the contractions and baby’s heartrate then sent us home. We were to report back a few hours later. Then again today.

After all those trips back and forth, the verdict is in: the prisoner will not be parolled. Karina hasn’t progressed at all since our appointment last Thursday.

Neither of us have slept much the last two days. We’re both tired and a little frustrated, but we know we’re going to be a lot more tired once baby arrives. Hopefully we’ll get some sleep tonight. The excitement and worry both wore off a bit with the news that today was not going to be the day.

SXSWi 2007: Hey Everybody

This weekend I’m misssing my favorite event: SXSWi. I start looking forward to the next one the day the current one ends and I usually have more fun during those four or five days than I do when Karina and I go on vacation.

But I’m missing it for a very good reason: Karina is due any day now and it turns out there are a (very) few things that are more important than south-by.

To all of our friends who are in town: we both want to say ‘hi’. Even though we probably won’t see any of you, we will think of all of you with envy for the next four days. Enjoy south-by and send us the cliff notes! (If you have my cell or email, drop me a line — I am hoping to make it downtown for an hour or two tomorrow if we’re not in the hospital.)

Steinbeck’s intro from “Travels with Charley”

James sent this to me this afternoon and I liked it so much I wanted to pass it along.

“When I was very young and the urge to be someplace else was on me, I was assured by mature people that maturity would cure this itch. When years described me as mature, the remedy prescribed was middle age. In middle age I was assured hat greater age would calm my fever and now that I am fifty-eight perhaps senility will do the job. Nothing has worked. Four hoarse blasts of a ship’s whistle still raise the hair on my neck and set my feet tapping. The sound of a jet, an engine warming up, even the clopping of shod hooves on pavement brings on the ancient shudder, the dry mouth and vacant eye, the hot palms and the churn of stomach high up under the rib cage. In other words, I don’t improve; in further words, once a bum always a bum. I fear disease is incurable. I set this matter down not to instruct others but to inform myself.

When the virus of restlessness begins to take possession of a wayward man, and the road away from Here seems broad and straight and sweet, the victim must first find in himself a good and sufficient reason for going. This to the practical bum is not difficult. He has a built-in garden of reasons to choose from. Next he must plan his trip in time and space, choose a direction and a destination. And last he must implement the journey. How to go, what to take, how long to stay. This part of the process is invariable and immortal. I set it down only so that newcomers to bumdom, like teen-agers in new hatched sin, will not think that they invented it.

Once a journey is designed, equipped, and put in process, a new factor enters and takes over. A trip, a safari, an exploration, is an entity, different from all journeys. It has personality, temperament, individuality, uniqueness. A journey is a person in itself; not two are alike. And all plans, safeguards, policing, and coercion are fruitless. We find after years of struggle that we do not take a trip; a trip takes us. Tour masters, schedules, reservations, brass-bound and inevitable, dash themselves to wreckage on the personality of the trip. Only when this is recognized can the blow-in-the-glass bum relax and go along with it. Only when do the frustrations fall away. In this
a journey is like marriage. The certain way to be wrong is to think you control it. I feel better now, having said this, although only those who have experienced it will understand.”

I’m not scared…yet

I’m not a big believer in religion but sometimes I do feel tested. We’re now eight weeks away from our estimated due date. Last week my laptop–the one I do all my work on–died. It died once before and I’m not sure if I’m going to try to get it fixed this time around. The rub is that I can’t afford to replace it and I can’t afford to be without it.

My car has been on its last leg for a long time now. We’ve only been using it when we absolutely had to, which we absolutely had to on Friday night when my wife was driving home from work in the freezing rain and her car broke down. Turns out the transmission is shot on hers, which is not great news two weeks after we fixed the A/C, power steering, and a CV joint.

We ended up putting a large sum on the credit card to repair my Hyundai Accent (somehow that car always gets a reprieve). The list of things done to it was a page long. I had been avoiding those repairs in the hopes that we could trade it in for a new car at some point, but I had to bite the bullet. We live 25 miles from Austin and we have to have at least one working car.

Saturday was spent going back and forth with the repair shop. I spent several hours there but I managed to get both cars to them, get both diagnosed, and worked out what work was going to be done to them. Getting the one with the broken transmission home today was the real challenge (that’s not going to be fixed anytime soon). At five miles an hour it takes a very long time to drive the ten miles from the repair shop to my house. I did it though and I have no idea what to do with the car now that I have it home. Maybe CraigsList.

Things have been tight for a while, but this is the first time they’ve been scary.

To the six people who read this: sorry I haven’t posted in a long time. There never seems to be enough time these days.