“Project” project

| |

There have been some big projects happening in the office over the last few months, which we’ll tell about when they’re public (there should be several emerging over the next few weeks). A smaller one, and I hope she’ll forgive me for describing her site that way, has emerged into the public light: we’ve been doing some WordPress tweaking for Project Happily Ever After.

PHEA, as we call it in the office (any title that long needs a TLA, even if it’s a FLA) is run by a former colleague of mine from Runner’s World, Alisa Bowman, and it’s WordPress at the core. Beyond that core, however, PHEA uses several plugins, a custom page configuration, and a very custom theme. Wrangling all those players became our job, with the primary goal of shifting the theme from a three-column layout which left the content column too narrow for embedded video to a two-column layout. The result is easier to read and places the reading focus where it belongs: on Alisa’s columns, not on the sidebar material.

We’d love to claim credit for this, but actually Alisa is that rare and delightful client who knew exactly what she wanted; she just didn’t know how to make it happen. We demonstrated potential changes on a staging installation on one of our servers, and when they were approved, used Subversion to push theme changes out to the live site.

We have a lot of respect for WordPress as a lightweight publishing system which is easy for non-technical users to pick up, but PHEA demonstrates that for users with a clear idea of their site’s function and the patience to try a few different options, it can also be a powerful tool for creating a rich site which is worlds apart from a cookie-cutter blog.

Moving a Rails/Mongrel site to Phusion Passenger on Ubuntu

| |

As I’ve noted before, several of our Rails projects are hosted using Phusion Passenger. We’ve been helping HitFix explore this option in recent weeks because it solves several minor deployment and restart frustrations they’ve been grappling with, and in the process I wrote up this walk-through for the installation.

This process is actually really easy and the instructions on the Passenger site and those provided during the installation process are excellent. The glitch we ran in to is that recent versions of Ubuntu and/or Apache 2.2.x use a slightly different method of loading modules and module configuration. (I haven’t run in to this method often enough to have learned whether it’s new in Apache or in Ubuntu.)

Instead of using one monolithic configuration file, sometimes offloading host configuration to included files, these Apaches instead globally include all modules found in the mods_enabled subdirectory of the Apache directory. Each module has two files, a .load file and a .conf file. The .load file contains only the LoadModule configuration directive; the .conf file contains any configuration directives.

Now, the actual files live in the mods_available subdirectory of Apache, and activating a module just means adding a symlink to the relevant files in mods_enabled, then restarting Apache. Deactivating it just means removing the symlink and restarting again.

With that in mind, here’s the Passenger process:

  • Install Passenger on the server. This should be as simple as:

sudo gem install passenger
sudo passenger-install-apache2-module

  • On one system, this second command actually told me that the Apache 2 Development Headers were missing. (Passenger needs these to compile the Apache module.) I needed to run sudo apt-get install apache2-prefork-dev to get these headers. This didn’t work on the first attempt, but running sudo apt-get update once or twice finally got me a successful install of that package. Running the passenger-install-apache2-module script then worked successfully. Note that you will need a compiler on the system in order to generate the Apache module. You would think you could take this for granted, but apparently not.

At this point, the module is built. This is where we have to adapt Phusion’s original installation instructions. Essentially, the next step is to make sure the module is loaded by Apache. Here’s how I did this:

  • Create a file at /etc/apache2/mods-available/passenger.load with the following content:

LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-2.0.6/ext/apache2/mod_passenger.so

  • Create a file at /etc/apache2/mods-available/passenger.conf with the following content (I think the IfModule container may be optional, but I played safe):

<IfModule passenger_module>
PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.0.6
PassengerRuby /usr/bin/ruby1.8
</IfModule>

  • Create symbolic links to both those files from /etc/apache2/mods-enabled/, i.e.

sudo ln -s /etc/apache2/mods-available/passenger.load /etc/apache2/mods-enabled/
sudo ln -s /etc/apache2/mods-available/passenger.conf /etc/apache2/mods-enabled/

We can restart Apache at this point without disturbing the existing site. Note that we can change which ruby is used (e.g. for Ruby Enterprise Edition) by altering the path at the PassengerRuby directive and restarting Apache.

To move a site to Passenger, you want to back up the file found at /etc/apache2/sites-available/yoursite, then edit it to make these changes:

  • Change the DocumentRoot to the public directory of the app, e.g. DocumentRoot /u/apps/yoursite/current/public
  • Comment out (with a #) all the lines related to the proxy, starting with the Proxy balancer definition and extending through all the ProxyPass, ProxyPassReverse and ProxyPreserveHost directives.
  • Restart Apache (/etc/init.d/apache2 restart). If something goes wrong, restore the backup you made of the configuration file and restart Apache again to restore the previous configuration.

The final trick is to update the restart task in Capistrano to handle restarting Passenger and not Mongrel. This is actually pretty easy, particularly if you’ve already overloaded the restart task in your config/deploy.rb file. Just replace the line reading run "mongrel_rails cluster::restart -C #{mongrel_config}" with one reading run "touch #{current_path}/tmp/restart.txt" and we’re good to go. The start and stop tasks probably also needs tweaking to remove the mongrel commands–probably pasting the same command in for “start” will do the trick unless we feel like putting Apache commands in.

BaselineNDA is a “pretty amazing application”

| |

Jason Mark Anderman of whichdraft.com:

I gave a presentation last week for the Association of Corporate Counsel’s Law Department Management Committee (there’s a mouthful!) entitled:

Web 2.0 for Contracts: Where to Go, What’s Free, What Costs Money

Anderman provides a list of sites he recommended in his presentation, including BaselineNDA, the application we built for Baseline Solutions Corporation. Here’s what Anderman had to say about BaselineNDA–with our emphasis added.

BaselineNDA (Pretty amazing application, with some limitations, it can read and mark up a confidentiality agreement for you)

Thanks, Jason! We think it’s pretty amazing, too, and we’re not even lawyers.

Styling anchor tags appropriately

| |

There’s a hitch in CSS styling of HTML a tags (“anchor” tags). The problem is that a tags are used for two different purposes: to establish a target, or “anchor,” for a link (e.g. <a name="anchorname">Link to this</a>), or to mark a section of text as a hyperlink (e.g. <a href="#anchorname">links to that</a>).

The first use of anchors is rare, nowadays. Every page has a default anchor, named “#“, which is set at the top of the page, and authors rarely set additional ones. They’re most frequently seen on Wikipedia pages, of all places, where subsections of the larger page are all anchored.

The problem comes in styling. What happens is that the text which is wrapped as an anchor gets styled as though it’s a hyperlink, even though without an href= attribute, it won’t work as one. This discourages a lot of webmasters from using anchors. One typical stunt is to not wrap anything at all, to create the anchor as <a name="anchorname" /> or <a name="anchorname></a> (the latter style is how Wikipedia does it). This isn’t available, however, to people using some kind of WYSIWYG editor in a CMS.

The real solution is to properly style a tags, and by “properly” I mean “not the way the default browser styles do it.” That means clearing styles from the a tag, and applying link appearance only to the :link, :hover, :active and :visited pseudo-elements.

Here’s how we did this for a recent project:

  • Style default a tags to look just like all other text:
a {
  text-decoration: inherit;
  font-style: inherit;
  color: inherit;
}
  • Now define the a:link pseudo-element to look the way you want your hyperlinks to appear. This pseudo-element is often ignored, but it’s the key to not applying link styles to your anchors. (We apply the same style to the :visited pseudo-element.)
a:link, a:visited {
 border:none;
 text-decoration:underline;
 font-style:normal;
 color:black;
}
  • Style the other pseudo-elements, because otherwise they won’t show differently from usual text (i.e. if :hover isn’t styled, links will appear to “disappear” when users mouse over them).
a:hover {
 text-decoration: none;
 color: #a3211f;
}

There’s no real trick here: all that’s involved is respecting the full definition of the a tag, and all the states allowed by its pseudo-elements.

HitFix is in Beta

| |

The site we spent the later part of December working on is now in public beta. HitFix is not the kind of site Noah and I imagined ourselves working on when we got started; it’s a site about entertainment and popular culture with commentary by industry insiders. But they needed more bodies who knew Rails as they pushed to launch, and their designer knew us from his previous job, so we got a call.

We can’t take credit for any individual aspects of the HitFix site; what we did was work as a team with HitFix’s internal Rails developer, Elliott Blatt, to make the site Beta-ready. This meant taking Photoshop demos and making fully-functional pages from them, working at all levels of the Rails stack. (We’ve been joking that our work on this site was in defiance of Brooks’s Law.)

Elliott has been a thrill to work with, having more experience with Rails than either of us, and we were surprised to find him learning from us almost as much as we were learning from him. What we’ve learned from this site is significant as well; it’s impossible to detail all the small conventions we’ve learned from Elliott, but one big example was learning HAML and its CSS sister, SASS.

It has also been an experiment in decentralized development, as some of the HitFix team is in California, Elliott is in Cambridge, and we’re in Amherst.

We’re still in active development with HitFix, but as I mentioned before, the beta is up, so if you’d like to take a look, you may find it interesting.

Name our drink

| |

The official Common Media caffeinated beverage of the winter is a large coffee from The Black Sheep across the street. The coffee is divided between two large mugs, to each of which is added a packet of hot chocolate mix and enough hot water to top off the mug. If the coffee is appropriately milked, it’s a pretty decent mocha.

So what do we call this? “The CMI” is inelegant. “Poor man’s mocha” isn’t bad, but a little bland, and it really saves time more than money (though it does save money). Maybe “The Subprime Mocha”?

Code for FlyFi

| |

We’re a few days late on this one, but no, FlyFi has nothing to do with wireless internet access on commercial airlines. It’s the new name for Emergent Music, LLC’s music discovery service (formerly known as Goombah), which uses collaborative filtering technology to analyze your iTunes library (we’re not kidding) and recommend new tunes.

Common Media was involved in the FlyFi launch through our friends at Corey McPherson Nash, who masterminded the new design. CMN provided us with layered Photoshop files to represent pages in the new design; we used those to render XHTML/CSS files for the Emergent Music, LLC team, who replaced dummy content in our files with links back to data from their application. This is how I worked with the sharp designers at Sinauer Associates, my former employers, and we’re doing similar work for other companies even now. (More on those jobs when they’re public.)

FlyFi takes the Pandora model (starting from a single song and building a stream of related songs) and goes a step beyond by using entire libraries to build their recommendation streams, which they call “Grooves”.

Like us, Emergent Music, LLC has chosen not to hang out in the insular tech-centric communities around Boston or Silicon Valley: they’re based in Brunswick, Maine. (They’re not even the first Web 2.0 company to come out of Maine: LibraryThing is based in Portland. No, not the other Portland, the first one.)

Baseline in American Lawyer

| |

Actually, it’s Legal OnRamp that’s profiled in the December American Lawyer, but BaselineNDA gets a mention as one of the value-added services available through “the ramp.” And there’s more Baseline in the pipeline.

Phusion Passenger, permissions, and Rails’ session store

| |

For various reasons, we’re moving three Rails apps hosted on one VPS to use Phusion Passenger rather than the Apache/Mongrel Cluster stack (via Coda Hale) we’ve been using since we got started.

The Passenger installation process really is as easy as it’s been described, particularly if you’re as comfortable with Apache configuration as we are, but by moving responsibility for serving your apps from Mongrel to Apache, file and process ownership becomes an issue in a way it wasn’t when Mongrel and Apache talked to each other and otherwise minded their own stores. Ben Hughes hinted at this in his walk-through of the Passenger installation, and we were not immune.

Our problem turned out to be session files. The first application we moved to Passenger (and it’s worth noting that apps running on Passenger and apps running Mongrel cluster can coexist under the same Apache) was Redmine, which uses file-based session store by default. If ownership of those session files creates a problem, and it did for us, switching to ActiveRecord session storage resolves the problem.

For those wondering about the point of Passenger, it’s memory use. A single Mongrel instance and an app running under Passenger have comparable RAM requirements, but because Passenger is an Apache module, it can spawn new instances as requests arrive; the Mongrel cluster solution requires multiple mongrel instances to be running all the time. This means Mongrel apps essentially require the RAM for peak capacity all the time. Passenger gives that RAM back at non-peak times, which allows more apps to share the same system, allowing us to get more mileage from our VPSes. (It’s worth noting that the Phusion guys claim a 33% memory savings per instance if Ruby Enterprise Edition is also used, so that will probably be our next step when all the apps are Passenger-ized.)

Update, 12/10: Another gotcha we found was file permissions. Again because of the permissions issues, Rails wasn’t writing to the shared/logs/production.log file. We didn’t notice this immediately, because the applications ran, they just didn’t log anything. The solution here was to change the ownership and permissions on the files. Specifically, we changed group ownership to “nobody” (the group Apache runs under) and the mode of the log file to 664.

We have an office!

| |

Door from hall by pjmorse, on FlickrAs of yesterday, Common Media, Inc. has an actual office, the kind which isn’t either of our spare bedrooms, the kind we both have a key to, and the kind where the company pays for the internet connection. (Or will, once our telco shows up to turn it on. How do telcos still have customers when they make it so hard to become a customer of theirs?)

We’re now in the center of Amherst, at 34 Main Street #7. We’re still in folding chairs and spare tables for furniture, and we’re working on stuff to hang on the walls (and probably over that window in the door). But the DSL is coming, and now we have a place to work where there’s a reduced risk of cat-on-keyboard. You can see more photos of the office on Flickr.

If we were lawyers, we’d be painting our firm name on that window, but for now we’ll settle for a plate down by the street door. We expect CMI will celebrate its second birthday in this office. I’m guessing there’s room for five of us in there, so we’ll be there until we get bigger than that, or smaller than we are now.