Brandon Bohling

Remove Day Part of Date in URL

Since everyone is talking about shipping these days tonight I took the plunge and released my modified blog on a new server. I have been dreading this day because a) the redesign is incomplete and b) there are so many steps in cleanly moving a domain between providers. Of course, immediately after “flipping the switch” I realized that my old website used URLs like /2011/09/25/Ellie/, but my new configuration was setup to use /2011/09/Ellie/ (notice I no longer have a day in the URL). Crap.

No sweat, right? I knew .htaccess could handle such an easy task. The problem was (being an .htaccess novice) I did not know the exact syntax to use. Worse, all the samples I could find simply showed how to strip out the entire date, not just the day. Thankfully, I finally came across this post where Alan Levine describes exactly what I needed to do in this paragraph:

The first part instructs the web server to return a permanent redirect (301) to find anything that has the three numbered structure (e.g. yyyy/mm/dd/) and find all the stuff that comes after that (.*) – every set of patters in (…) corresponds to variables we can use in the result– $1 $2 $3 are the year, month, day respectively, and $4 is the string of the url we want to preserve.

Simply adding the line below in the .htaccess fixed the issue:

RedirectMatch 301 /([0-9]+)/([0-9]+)/([0-9]+)/(.*)$ http://brandonbohling.com/$1/$2/$4

Like I said, “No sweat”.

An Event Apart

AEA San Diego

I just spent the last few days in sunny San Diego. Instead of enjoying the outdoor activities though, I was in a large room with hundreds of other people learning about the latest in standards-based web design. The conference, An Event Apart (AEA), had twelve top-notch speakers including Jeffrey Zeldman and Eric Meyer who started the conference. In my 18 years of being a professional web guy I have been to many conferences, but without a doubt AEA was my favorite…even better than WWDC. The mix of designers and developers was refreshing and given the limited number of attendees (~400) it was easy to talk with many. There were no “tracks”, simply one room, so no making tough choices on which sessions to attend. And the content. Not a single session was a snore fest. All the speakers presented beautifully engaging slides, sharing knowledge and best practices through stories, something I rarely experience in my day job.

OSX Disk Images

I wanted to create an encrypted disk image for my 2012 Tax Return documents, but unfortunately Disk Utility, which comes with OSX, does not allow image sizes (that are encrypted and journal HFS+) less than 10.5 MB. This seemed strange, so I looked for the command line equivalent. With the help of this article I came up with this:

hdiutil create -encryption -size 5m -volname 2012Taxes 2012Taxes.dmg -srcfolder ~/Desktop/foo/ -fs HFS+J
  • 5M = disk image size (5 MB)
  • 2012Taxes = disk image name when mounted
  • 2012Taxes.dmg = disk image name
  • -srcfolder is optional. It adds the files to any folder you provide
  • HFS+J = format will be journaled HFS+

Note: you will be prompted for a password after you execute the command

For whatever reason I still could not create an encrypted disk image smaller than 5 MB, but the fact I could create one smaller than the Disk Utility seems odd.

Underscore Your JavaScript This Moment

Up until last year it had been many years since I had been a full-time developer. After a year back in the code, I still do not feel as competent as I felt in my prime. So maybe what I am about to share is common knowledge among the developer community, but just in case…

If you are developing solutions using JavaScript I highly recommend you check out two helpful libraries: Underscore and Moment.

Shamelessly copied from the underscore website:

Underscore provides 80-odd functions that support both the usual functional suspects: map, select, invoke — as well as more specialized helpers: function binding, javascript templating, deep equality testing, and so on. It delegates to built-in functions, if present, so modern browsers will use the native implementations of forEach, map, reduce, filter, every, some and indexOf.

and moment:

A 5.5kb javascript date library for parsing, validating, manipulating, and formatting dates.

So two libraries to make a developer’s life easier…perfect. Let’s look at a few examples to show off their awesomeness. Keep in mind, I purposely selected more basic features just to introduce the libraries. If there is enough interest I can cover more advanced usage scenarios in the future.

Moment

For the example we will use the following sample JSON response:

var jsonSample = {
  "Vacation": {
    "StartDate": "/Date(1366182000000)/",
        "EndDate": "/Date(1368169200000)/",
        "Trips": [{
        "Name": "Fun in the Sun",
            "Origin": {
            "Location": "Iowa City, IA",
                "Date": "/Date(1367046000000)/",
                "DateFormatted": "Saturday, April 27th 2013"
        },
            "Destination": {
            "Location": "Phoenix, AZ",
                "Date": "/Date(1367218800000)/",
                "DateFormatted": "Monday, April 29th 2013"
        }
    }, {
        "Name": "Family Time",
            "Origin": {
            "Location": "Portland, OR",
                "Date": "/Date(1366182000000/",
                "DateFormatted": "Wednesday, April 17th 2013"
        },
            "Destination": {
            "Location": "Iowa City, IA",
                "Date": "/Date(1366527600000)/",
                "DateFormatted": "Sunday, April 21st 2013"
        }
    }, {
        "Name": "Return Home",
            "Origin": {
            "Location": "Phoenix, AZ",
                "Date": "/Date(1367910000000)/",
                "DateFormatted": "Tuesday, May 7th 2013"
        },
            "Destination": {
            "Location": "Portland, OR",
                "Date": "/Date(1368169200000)/",
                "DateFormatted": "Friday, May 10th 2013"
        }
    }]
  }
};

Nothing too elaborate, but hopefully should be familiar if you have worked with JSON before. If you are new to JSON, check out this video.

First, let’s address the unfriendly dates that we are sometimes served. Moment makes it a snap:

var dt = moment('/Date(1366182000000)/');
var humanReadableDate dt.format('dddd, MMMM Do YYYY, h:mm:ss a');

Creating a moment object is simple as the first line shows. A moment can be created from any string that can be parsed by Date.parse. Then, like many modern languages, formatting is as straightforward as following a certain syntax.

If you are comfortable with how this works, then you can actually perform this as a 1-liner:

var humanReadableDate = moment('/Date(1366182000000)/').format('dddd, MMMM Do YYYY, h:mm:ss a');

To some I am sure this simple example does not impress, but look at the docs for yourself. I doubt you will come across a scenario where Moment will not make your life easier when dealing with date and time.

To see this in action yourself: http://jsfiddle.net/bbohling/8vDQS/.

Underscore

Underscore is not always necessary to complete a task, but it has almost always reduced my code by at least 30%. In addition, it makes the code much more maintainable in my opinion. Let’s take a look at a few examples of what we can do with underscore.

Sort: Organize Your Lists

In our jsonSample above the data is not sorted by date which could be an issue. With underscore, this is easily addressed:

var sortedTrips = _.sortBy(jsonSample().Vacation.Trips, function (trip) {
   return moment(trip.Origin.Date);
});

First we pass in our list jsonSample().Vacation.Trips and then our iterator. In this case, it means that our trips will be sorted in ascending order by each trip’s origin date (we use moment to ensure a standard date is used).

Note: jsonSample has parenetheses because in the jsFiddle I created for this tutorial I am using Knockout, which is another fantastic JavaScript library I highly recommend.

Some: Is there any truth in your list?

Let’s say we want to know if a user is going somewhere specific. We can create a function that takes a destination and will return true/false based on if the trip is located in the jsonSample. This can be implemented using underscore’s some function which again takes a list and iterator.

tripTo = function (destination) {
   return _.some(jsonSample().Vacation.Trips, function (trip) {
      return trip.Destination.Location == destination;
   });
};  

Here we have a function called tripTo that has a destination parameter, which will be used in the some function. Similar to sortedTrips above we will pass our Trip list and our iterator that checks to see if the trip (destination) location is the same as the destination that was provided. As soon as one of the destination locations equals the destination argument, the function will stop traversing the trip list and tripTo will return true. Of course, if the destination argument does not match any of the trip locations tripTo will return false.

See the example in action.

Each: Traversing Your Lists

In this final example, let’s add a property to jsonSample. Instead of always converting the date whenever a view needs to display it, let’s convert it up front. Underscore makes this a snap with the each function.

newJson = function (json) {
   _.each(jsonSample().Vacation.Trips, function (trip) {
      trip.Origin.DateFormatted = standardDate(trip.Origin.Date);
      trip.Destination.DateFormatted = standardDate(trip.Destination.Date);
   });
   return json;
};

I’m guessing those comfortable in JavaScript can easily guess what’s going on here. Thanks to the flexibility of JavaScript in our iterator we are simply adding a DateFormatted property to trip.Origin and trip.Destination. You can see what the updated jsonSample looks like when it has been sent through our newJson function by checking out the jsFiddle.

Wrap-up

Again, these examples are basic, but hopefully intriguing enough to check out underscore and moment. It shouldn’t take you long before these two libraries are making your life as a developer much easier.

Configuring Homebrew in a Multi-User Setup

My MacBook Pro is setup with two user accounts: one for personal and one for work. This is certainly not my setup of choice, but if I want to use my own MBP (which is retina) at work then I have to abide by this rule.

Anyway, this setup caused an issue when I went to do something that required Homebrew. After a little research and testing Leif Hanack had the best answer. All it requires is a group that both users are members and then change group permissions on /usr/local. While I have not done so myself, this methodology should work on other items (i.e., iTunes library) I wish both accounts to have access.