Leopard, autotest, growl, and Bob the Builder
May 23rd, 2008
There's a bunch of articles that helpfully diagnose and solve the GRRRRowl + autotest + Leopard snafu.
In order to save me, and my cohorts, some time I've bundled it all up in a README + script + icons.
Being a new father, currently at my in-laws, I've reached for the nearest toy, and made bob the builder icons. I think they might even challenge hookercookerman's set (sadly, not on the web as afar as I can see - step up hookercookerman and post them).



Grab it
here (tarball, installation instructions inside)
P.S.
I made the screenshots with Photo booth's 'backdrop' feature, and a real toy. Finally, I can do composites (I just knew not learning photoshop would pay off).
Leopard, SSH-agent, and a macports gotcha
May 19th, 2008
So you're using ssh keys for all your servers and github and whatnot, and you've been using SSHKeychain in OS X 10.4, to manage that, and not type your password in all the time (SSHKeychain is a gui for ssh-agent).
Now that you're on Leopard, this all Just Works. No need for SSHKeychain (although SSHKeychain does other things too), and everything is nicely integrated with Mac OS keychain services. There's a nice write up over here at Ormset i Noreg. Buried in the comments, Luke Redpath notes that macports users might not be seeing this coolness, as OpenSSL is a dependency of some common ports (like git), and so the macport's ssh is not compiled with the leopard funkiness.
To fix this (assuming a standard macports install):
sudo mv /opt/local/bin/ssh /opt/local/bin/ssh-macports sudo mv /opt/local/bin/scp /opt/local/bin/scp-macports
Now, when you next push to github, or deploy to a server, you'll get something like this:
Hooray!
git hosting with Leopard
May 19th, 2008
So you wanna host your own git repos? Got Leopard? Got Git? Read On...
Assumptions: You have git installed.
Create a git server on leopard with gitosis
Download and install gitosis
mkdir src git clone git://eagain.net/gitosis.git cd gitosis sudo python setup.py install
Create a git user and group on the server
Create a unix user and group for git, using dscl: leopard's directory service cli
1. Find an unused uid and gid
sudo dscl . list /Users uid sudo dscl . list groups gid
(check that, say, 401, is unused in both)
2. Create the git group
sudo dscl . create groups/git sudo dscl . create groups/git gid 401
3. Create the git user
sudo dscl . create users/git sudo dscl . create users/git uid 401 sudo dscl . create users/git NFSHomeDirectory /Users/git sudo dscl . create users/git gid 401 sudo dscl . create users/git UserShell /bin/bash sudo dscl . create users/git Password '*'
4. Create the git home directory (make this location match the end of line 3 above)
sudo mkdir /Users/git sudo chown git /Users/git sudo chgrp git /Users/git
Create an ssh key, and copy it to the server
1. If you don't already have one, create an ssh key, on your local machine if it is not the server
ssh-keygen -t rsa
2. Copy the public key to /tmp on the server
(if your local machine is the server)
cp ~/.ssh/id_rsa.pub /tmp/my_key.pub
(if the server is different from your local machine)
scp ~/.ssh/id_rsa.pub your.server.com:/tmp/my_key.pub
Setup gitosis in git user's home directory
1. Initialise gitosis [on the git server]
sudo -H -u git gitosis-init < /tmp/my_key.pub(you should see something like this:)
Initialized empty Git repository in ./ Reinitialized existing Git repository in ./
2. Make sure git's paths are set to your current ones (where you can see gitosis and git)
sudo su git (enter your password) echo "export PATH=$PATH" > ~/.bashrc exit
Clone the gitosis repo to your local machine
git clone git@your.server.com:gitosis-admin.git
If you see something like this, then you're all set
remote: Counting objects: 5, done. remote: Compressing objects: 100% (4/4), done. remote: Total 5 (delta 0), reused 5 (delta 0) Receiving objects: 100% (5/5), done.
What next?
Get familiar with gitosis. scie.nti.st has a great writeup for *nix systems, which I used as a reference point. The end of that blog has some general intro to gitosis.
Troubles? Make sure that you can ssh to the server as git (make sure that Leopard's ssh settings allow any user to login, or edit /etc/sshd_config). Otherwise post your troubles here in the comments.
IE8 lagging in standards support (comparatively speaking)
May 11th, 2008
I don’t know how I missed this (well, I do, I've been ridiculously busy), but about a month ago Microsoft issued a statement about planned CSS standards support in the upcoming IE8. The good news is that CSS 2.1 support will be almost complete—good, but not great, considering that this standard is rather old now, as it’s been a “candidate recommendation since 2004”.
The bad news is the level of support for CSS3 elements. Look through that list & try to keep afloat in the sea of red “no”s that signify their CSS3 support—or lack thereof. Of course, CSS3 is still very much a work in progress and is unlikely to be a candidate recommendation for another decade, judging from the pace of “Last Calls” for various components of the CSS3 spec. Nevertheless, the developers behind Safari & Firefox have been implementing a lot of the spec. There’s some fantastic stuff in it (multi-column support! colours with opacity!), that I for one would like to use immediately—and which we do, on our own site & some others we’re currently developing. But for the foreseeable future, if you’re using IE, you won’t see these things.
Given the clusterfuck of discontent that was IE7, and that Safari & Firefox have cleaned their clocks with current & emerging standards support, one might think that Microsoft would take the opportunity to really push IE8 to be a 1st-class browser. But no, they’ve just decided to tread so softly, so slowly, that the net result will be that IE8 will be that much farther in the distance. I mean, IE8b has just passed the Acid2 test. Hooray. Safari & Opera have worked on complete compliance with Acid3—and have succeeded.
This sucks. There are fantastic things taking place in CSS, in particular CSS3—which you can experience right now in Firefox & especially Safari. And I’d like all my site’s viewers to be able to see these effects in action.
Congratulations to Ian!
May 7th, 2008
As of last night, Ian became a father! At around 11pm, his son was born. Let me be the first in a public forum to congratulate him :)
Hopefully, he’ll soon post pictures—and a name!
ardes plugins available github and lighthouse
April 30th, 2008
Many of our plugins are now available on github: github.com/ianwhite
And OSS projects such as these can now be hosted free on lighthouse: ianwhite.lighthouseapp.com
The ones that you see on lighthouse have all had a good dusting off to make sure they're compliant with the very latest edge, and BC to 2.0.2. response_for is now branched to support edge and 2.0.2, but the other plugins haven't yet required this.
If you don't see one you use there, it means that I haven't deemed it being used by many people - so leave a comment to say otherwise
resources_controller: things
April 27th, 2008
RC's got a github home now
The subversion repo will still continue to be maintained for the foreseeable future.
RC's also reported as being one of the things under the hood at naked.
Lastly, I've been cooking my CI with garlic.
Two CSS Debugging Tips
April 25th, 2008
Ian may claim to be doing nothing but git-work (and what an unfortunate name that is), but the fact of the matter is that we’re both eyebrow-deep in client work. This business has been running since April 1999 & we’ve never been so busy.
When you’re so busy, the last thing you want is a series of bugs that won’t seem to go away. Since most of my work is in the HTML/CSS/Rails templates realm, I’m speaking mostly of visual bugs, things that seemingly won’t budge no matter how much time you put into them. I thought I’d share two tips which have helped me squash a considerable number of visual bugs, one created by someone else & the other merely a process that I follow.
CSS Debugging Tip 1: Burn it all to the ground
First, the work supplied by someone else: Eric Meyer’s CSS Reset. If you’re unfamiliar with it, go & read up on it ASAP. For those unfamiliar with why you’d need to reset something your CSS, the answer is simple: different browsers have different default sizes for fonts, lists, buttons & a hell of a lot else. By resetting all these items via CSS, you help ensure that all your browsers—Safari, Firefox, Opera & the thorniest of them all, Internet Explorer—start from a common vantage point.
The idea is not new. For years I’ve employed a very basic, simple reset:
html * { margin: 0; padding: 0; }
The problem is that this didn’t reset nearly enough things—and it often didn’t even reset everything it was supposed to! Eric’s reset is a total razing to the ground of all browser-specific sizing quirks & as such should be adopted by every designer. In my experience, it’s particularly useful for a project that you’re just starting up: my IE-specific stylesheets are a fraction of their former size. For pre-existing sites, however, it’s not going to be a magic bullet. You still assembled your CSS based on different assumptions & short of starting from scratch, it will be of more limited use (although still recommended in my book).
CSS Debugging Tip 2: Build it back up brick by brick
The second tip is merely a process that I’ve been following. I’m surely not the first person to do this, but since it doesn’t appear to be widely discussed I thought I’d write it up here.
I’m going to take a real-world example from a site we’re building. In this site, we’re using some Scriptaculous effects to aid in the creation of a visually compact secondary navigation for a database of imagery. The markup is simple:
<h4>Section Heading</h4>
<a href="subsection/1">Subsection 1</a>
<a href="subsection/2">Subsection 2</a>
...
Clicking on the H4 tag will cause the subnavigation links to reveal themselves, or hide themselves if they’re already revealed.
Unless you’re viewing in Internet Explorer 7, that is—no, the problem for once isn’t IE6! In IE7, the links were invisible—they were clickable, but you couldn’t see them.
I tore out what little hair I had left, for weeks, trying to figure out this bug. I even thought it might have been Scriptaculous’ fault. It wasn’t, however & eventually I realised I was compounding the problem by adding CSS declarations instead of removing them—instead of trying to figure out what was triggering the bug, I was trying to pave over the bug. If you’re adding more declarations in order to fix a bug, you may very well be creating a shifting target, which is definitely not what you want to be doing. Particularly when you have a lot of other work to do.
The answer is just a process & a very simple one at that: take your CSS declarations & strip them out. Add them incrementally, viewing in the target browser every time, until you trigger the bug.
In the example above, removing a declaration of a:link { display: block; } rendered the links visible again in IE7. I don’t know why—I’ve used this declaration countless times with no problems—but nevertheless the declaration wasn’t necessary & it was causing a big problem.
Again, though, it’s the process of stripping away your CSS & then re-implementing your declarations which is the key. It’s all too easy to add more & more to your declarations, but remember: you may only be making the job of fixing your problems worse.
Continuous Integration with Garlic
April 24th, 2008
So I've been curled up in a ball, riding the git avalanche, trying to sort out my rails plugins - making sure they're getting tested against the latest and greatest.
Inspired by this ticket for rspec, git's coolness, some menthol snuff, and a lot of coffee, I came up with garlic.
It's an extremely lightweight set of rake tasks that let you test your plugins or app against various version of rails, and other dependencies.
If you want to see it in action (on one of my plugins), do this:
git clone git://github.com/ianwhite/inherit_views cd inherit_views rake cruise
Sit back, watch it download all the dependencies, then create rails apps for each set, and run the rcov task for the plugin in each one... (the download only happens the first time you do it).
You configure it using a little dsl, like this:
garlic do
# default paths are 'garlic/work', and 'garlic/repos'
work_path "tmp/work"
repo_path "tmp/repos"
# repo, give a url, specify :local to use a local repo (faster
# and will still update from the origin url)
repo 'rails', :url => 'git://github.com/rails/rails' #, :local => "~/dev/vendor/rails"
repo 'rspec', :url => 'git://github.com/dchelimsky/rspec'
repo 'rspec-rails', :url => 'git://github.com/ianwhite/rspec-rails'
repo 'inherit_views', :url => '.'
# for target, default repo is 'rails', default branch is 'master'
target 'edge'
target '2.0-stable', :branch => 'origin/2-0-stable'
target '2.0.2', :tag => 'v2.0.2'
all_targets do
prepare do
plugin 'rspec'
plugin 'rspec-rails', :branch => 'origin/aliased-render-partial' do
sh "script/generate rspec -f"
end
plugin 'inherit_views'
end
run do
cd "vendor/plugins/inherit_views" do
sh "rake spec:rcov:verify"
end
end
end
end
Notice that I'm using my fork of rpsec-rails, and the plugin specifies that it should use a particular branch 'aliased-render-partial'. The reason for this is that I have some outstanding tickets on rspec, which haven't been resolved. In the meantime, I can just use my patched version. If the patch gets accepted, I can just change the url, and garlic will inform me that I need to remove and run rake garlic:install_repos to get the new one. This is just making use of the awesomely cool coolness of git.
Also notice the block passed to the 'rspec-rails' plugin. This will be executed inside the rails target after the plugin has been installed. Finally the run block says what should happen for the actual CI. In this case cding into the plugin and running an rcov task.
It's new stuff
So it probably has bugs and stuff.
Neocon Clone Math!
March 18th, 2008
Special Neoconservative Incompetence Cloning edition!
Soulless, chillingly evil US Veep Dick Cheney +
Formerly (and mysteriously) popular war criminal US Sec’y of Defense Donald Rumsfeld,
-( (hair/2) + (war criminality) ) * ( (avg. human sympathy)/10 ) =
Totally on-the-ball Sec’y of the Treasury Hank Paulson?
Fucking hell, where do they get these people? Aside from a petri dish, that is.
HP Total GoatseCare
February 28th, 2008
So I was reading an article this afternoon & noticed the HP advertisement that appeared right next to it:
And I kept thinking, that’s so familiar…
dynamic resolution + prototype
February 27th, 2008
You may have heard of the Dynamic CSS resolution switcher from Particletree, it's a neat bit of js that allows you to specify different css files depending on the browser resolution.
We love this script, but we had problems running it with Safari, and we are using prototype, so we wanted to make use of its goodness for the browser independent stuff.
So, if you're already using prototype, the following script achieves the same effect as the original particletree script. It also uses the dom:ready event, which fires after the dom is loaded, but before the screen is drawn, so you shouldn't see any 'twitch'.
Example
In the following example, we have three stylesheets that correspond to browser widths as follows:
thin up to 1020 wide 1021...1400 widest above 1400
For non js users we want to default to 'wide' (the middle one). In order for this to work properly, we disable all of the non-default stylesheet links.
In your html
In your html you need to link to the three stylesheets, give them each a title attribute, and disable the ones you don't want non-js users to see.
<link title="wide" href="/stylesheets/wide.css" rel="stylesheet" type="text/css" /> <link title="thin" disabled="true" href="/stylesheets/thin.css" rel="stylesheet" type="text/css" /> <link title="widest" disabled="true" href="/stylesheets/widest.css" rel="stylesheet" type="text/css" />
And link to the script, we'll call it dynamic_css.js
<script src="/javascripts/dynamic_css.js" type="text/javascript"></script>
The script
This is the script, it uses the title attribute of the stylesheets to disable or enable them. It is run when the dom is ready, and when the browser width changes.
// DYNAMIC RESOLUTION SWITCHER
// Originally from ParticleTree
// Simplified with Prototype by Ian White of Argument from Design 2008
// include prototype.js (>=1.6) before this file
// you need to edit this function as per your situation
function applyDynamicLayout() {
var width = document.viewport.getWidth();
if (width <= 1020 ) { applyStylesheet("thin") }
if (width > 1020 && width <= 1400) { applyStylesheet("wide") }
if (width > 1400) { applyStylesheet("widest") }
}
// you shouldn't need to edit past here
function applyStylesheet(title) {
var i, stylesheet;
for(i=0; (stylesheet = document.getElementsByTagName("link")[i]); i++) {
// is it a stylesheet with a title attribute?
if(stylesheet.getAttribute("rel").indexOf("style") != -1 && stylesheet.getAttribute("title")) {
stylesheet.disabled = true;
if (stylesheet.getAttribute("title") == title) {
stylesheet.disabled = false;
}
}
}
}
//Run applyDynamicLayout function when window is ready and when it resizes.
Event.observe(document, 'dom:ready', applyDynamicLayout);
Event.observe(window, 'resize', applyDynamicLayout);
That's it!
That's it, it works for us in Safari, Opera, FF and IE 6 or greater.
Also, you can have as many stylesheet links as you like with the same title. For example, let's say you have some IE6 specific kludges for the 'thin' layout. You would do this:
<!--[if lt IE 7]> <link title="thin" disabled="true" href="/stylesheets/thinie6.css" rel="stylesheet" type="text/css" /> <![endif]-->
resources_controller new trunk
February 26th, 2008
There's going to be some new features coming in resources_controller. Stay tuned...
Meanwhile, rc has got a new repository location (the old one will still work for a while, but will remain at the current version):
trunk: http://svn.ardes.com/resources_controller/trunk/resources_controller
tag 0.5: http://svn.ardes.com/resources_controller/tags/0.5/resources_controller
For those interested in providing patches, you should checkout http://svn.ardes.com/resources_controller/trunk and run rake pre_commit in that directory to check your changes. Then send a diff along, or post it on the google group.
Ruby muckin
February 12th, 2008
So I was writing a Rakefile and found myself doing stuff like this:
cmd = "svn co #{src} #{dest}"
puts cmd
system cmd
Everytime I wrote lines like this, a little corner of my heart died.
I dreamt of something like this:
"svn co #{src} #{dest}".to :puts, :system
But it's hard to do this properly, because you need to get hold of the receiver (in the above case main, or some Rake task) or binding, so that the methods can be sent where they ought. With crippled Kernel#caller, the the demise of Binding.of_caller (Ruby-debug solved the problem but there's significant overhead) it was looking like I should just wait for the next ruby release.
But I frowned like Hiro and came up with this:
pass("svn co #{src} #{dest}").to :puts, :system
Briefly, Object gets #pass which creates a PassProxy (basic object). It keeps hold of the receiver, but acts like the object (in this case the string). When you send #to(:method) to this PassProxy, it calls the original receiver with the object.
This is just sugar, but its nice sugar in some cases. Compare:
# plain ruby
msg = "oooh!"
MyObj.foo msg
MyObj.far msg
MyObj.faz msg
msg
# => 'oooh!'
# returning (ActiveSupport)
returning "oooh!" do |s|
MyObj.foo s
MyObj.far s
MyObj.faz s
end
# => 'oooh!'
# (pass) (this code)
MyObj.pass("oooh!").to :foo, :far, :faz
# => 'oooh!'
But eat too much sugar and your teeth will fall out: I realised that this probably has limited usefulness (how often do you need to send the same object to a bunch of different methods?). But at least I learned some things in that last couple of hours of coding.
Go get the code from pastie if you're interested.
Thanks for reading
A great start to 24 Ways 2007
December 1st, 2007
Since 2005, 24 Ways has been a great collection of web design tips & tricks in an “advent” format (i.e., one article per day in December before Christmas). This year already looks like it’s going to be a great one. Drew McLellan has a great opening article on dealing with transparent PNGs in Internet Explorer 6 & 5.5 (yes, many of us do have to factor in those old browsers in our designs).
This comes at a great time: currently we’re working on a site that uses 24-bit PNGs with alpha transparency, and as Drew says, the common solutions to the issue don’t help you when you want to use that type of PNG as a background image. He also mentions that it’s a big problem to use such PNGs behind a form—because of the way IE6 & earlier deals with the PNGs. IE effectively puts another layer on top of the area you’re looking at—meaning that form inputs are completely inaccessible. This is a problem not simply for forms, but indeed potentially for any design where you’re playing with positioning. For example, we’ve got an organisation’s logo dipping slightly below a masthead, spilling onto the crumbs bar below. Any links that happen to be in that PNG’s area were completely inaccessible, too. Our solution was to set z-index for both the #masthead img & #crumbs. Drew’s solution is better, however—it’s far more set & forget.