Recent News
Engineering happiness
I'm in love. Thursday's keynote at UX Week has definitely been the most engaging moment of the conference. Game designer and researcher Jane McGonigal gave a passionate talk about the intersection of gaming and real life, positing that "reality is broken" and games work better.
Why are games superior to our experience of everyday life? They offer better instructions, better feedback, better emotions ...and a better sense of community. Jane highlighted the disconnect between game and life feedback with the amusing scenario of wrapping up her keynote note speech and envisioning that her iPhone would ping, alerting her that's she's received 5 speaking credits. While this is an amusing, but not likely realistic scenario (unless you might be using Plusoneme,com), it points out that there are certain experiences that we desire to have, and games give us a way to find satisfaction.
If not given the experience of being good at something or the chance to be part of something larger, do satisfying work, or find a community that we feel a part of, these become quality of life problems. The crux of this keynote is that these issues are a user experience challenge that we can address through learning from game interactions.
While I've been thinking a bit about the future of UX and interaction design during this conference, Jane describes her vision of user experience as being directly related to life satisfaction – and UX practitioners therefore become the engineers of happiness. In this view, quality of life can looked at as a quantifiable brand metric.
For more information on Jane McGonigal's work, take a look at her website at avantgame.com and her current projects, The Lost Ring and The Superstruct Game.
written by ahaschke on August 15th, 2008 @ 10:37 AM
The future with gestures
The highlight of Wednesday lineup of events at the UX Week conference was, for me, Dan Saffer's workshop on designing gestural interfaces. The overall approach to this session was incredibly tactical, and we focused primarily on on exploring gesture through touch, with fingertips as input device. After a quick, but comprehensive walkthrough of critical considerations for prototyping a touch-based interface, the room broke into about six groups who each worked through the task of prototyping an installation for a music store who's been losing customers to Amazon and iTunes. With services like iTunes and Last.fm being such an integral part of my hunt for new music, this exercise presented a unique challenge is considering what experiences belong solely to the physical act of flipping through racks of vinyl or CDs that aren't normally replicated in an online experience.
The one question that I'm left with after this workshop, though, is how gestural interfaces might change how we interface with technology on a daily basis in the future. Touch-based interfaces already exist in many public locations from airline check-in kiosks to self check-out at the grocery store. But, with an iPhone in so many people's pockets (and I've never seen such a high penetration of iPhones in a distinct population as at this conference), how will touch and other gestures continue to impact personal computing?
The overall track of Tuesday's other sessions focused on the experience of service design. While hearing about how Zipcar has approached their business model and embraced experience as being essential – and exploring how Comedy Central tackled building an extensive archive of tagged clips for The Daily Show – uncovered interesting approaches to process, this thread didn't produce any lasting "a ha" moments for me to draw from. However, I did manage to end the day with the most exquisite service experience at Masa's, a SOMA restaurant that serves up new French cuisine. I have a feeling, though, that I might encounter some issues passing off the $200 bill as being a "research expense."
written by ahaschke on August 14th, 2008 @ 10:27 AM
Debugging Kentico sites in vs.net 2008/05 improve compilation time
Here is a tip for debugging the massive Kentico sites in vs.net in case you don’t know about it.
By default the website is configured to compile everything in the Kentico site when running F5 (debug) to start app the application in debug mode.
This causes big delays since Kentico websites have lots of code.
Instead what you want to do is compile only the page you are working on.
1) In vs.net 2008/05 right click on the website node in the tree navigation pane.
2) Select “Property Pages”.
3) In the Build page, Set your project to the following settings
a. Build Page (instead of Website)
“Build Web site as part of solution” option.
written by jperez on August 14th, 2008 @ 09:33 AM
Resistance ...is a good thing?
I've been spending the week away from the office at UX Week in San Fran, a conference for user experience practitioners that Adaptive Path hosts every year. This year's event has taken good strides towards making sure that attendees aren't sitting in a dim ballroom listening to talking heads for a majority of the day, and the programming has a healthy mix of lectures, working sessions and even field trips.
Day one of UX Week kicked off on Tuesday around the theme of "Fundamentals of User Experience." Interestingly, one thread that continued to surface throughout the day was the idea of resistance or constraints being a necessary part of the creative process. Jensen Harris from Microsoft was the first speaker to more directly speak about how finding resistance was an integral part of his team's progress in redeveloping the interface for Word 2007, and he referenced this quote from Igor Stravinsky:

The notion of resistance as a tool for propelling projects forward presented itself again in an afternoon working session on, well, designing effective work sessions. Pulling from Adaptive Path's collective experience with structured ideation sessions (translation = "brainstorming"), it's critical to build a framework of resistance to help shape the direction of a group discussion and give participants something to react against.
I'll continue to post more followups as the conference continues, and day two delves into the theme of media and service design.
written by ahaschke on August 13th, 2008 @ 11:00 AM
Managing dashboard widgets on various external displays
Like everyone else at Cement Horses, I use a MacBook for daily work, along with an external monitor. When leaving the office, I take the Macbook and leave the monitor, naturally.
Dashboard widgets aren't like ordinary windows -- when I disconnect the external display, the Mac doesn't automatically move them all to the primary display. They simply stay positioned way offscreen, and inaccessible. I can tell you that logging in or restarting doesn't help, and here's the solution I've found.
Widget locations are kept in this plist:
~/Library/Preferences/com.apple.dashboard.plist |
If you have Apple's developer tools installed, you can open this in Property List Editor and simply edit each widget's pos-x and pos-y values. (You can just make them zero; as long as they're visible in the Dashboard, you can rearrange them that way.)

Once saved, you can reload/activate the plist from the Terminal, like so:
killall Dock |
If you switch displays regularly, you can try maintaining separate profiles:
1 2 3 4 |
~/Library/Preferences/com.apple.dashboard.plist.home ~/Library/Preferences/com.apple.dashboard.plist.work ~/Library/Preferences/com.apple.dashboard.plist.no |
A bash function like this one:
1 2 3 4 5 6 7 8 9 10 11 12 |
resetdash () {
if [ $# -ne 2 ]
then
echo "Usage: resetdash [current] [other]"
echo "Saves your current widget profile, and then activates the profile of your other (specified) setup."
else
mv "$HOME/Library/Preferences/com.apple.dashboard.plist" "$HOME/Library/Preferences/com.apple.dashboard.plist.$1";
mv "$HOME/Library/Preferences/com.apple.dashboard.plist.$2" "$HOME/Library/Preferences/com.apple.dashboard.plist";
killall Dock;
echo "Widget profile saved and reactivated.";
fi
|
Means you can run resetdash work none to change over to your no-external-display profile. (I'm not a pro at bash scripting, so you may have better ideas.)
written by shinji kuwayama on August 1st, 2008 @ 04:12 PM
Counting in CSS
One of the best things you can do as a Rails developer is remember to utilize everything at your disposal. Last week, I had this front-end task to set up dynamic footnotes; I initially assumed I would be doing this in Ruby, until i found this choice CSS2 “counter” support:
body { counter-reset: footnote; }
.footnote:before {
content: counter(footnote);
counter-increment: footnote 1;
}
No kidding! It’s a good reminder—CSS is quite evolved and mature, and it contains a lot of little-discussed functionality. Remember to exploit it as much as possible (IE6 notwithstanding)…
written by shinji kuwayama on July 28th, 2008 @ 04:11 PM
Take control of your server configuration with Capistrano
A typical Rails deployment involves configuring a number of services via configuration files. Common examples include httpd.conf, nginx.conf, memcached.conf, monitrc, my.cnf, haproxy.conf, et al. These little files are the laces that hold your app together; the tiniest mistake or misconfiguration will usually take your whole operation down. On top of this, if you’ve got multiple servers, you’ve got to make sure that every server is configured correctly.
So why don’t we put these under version control, and then use Capistrano to deploy configuration changes to one or more servers? Here’s one way to do it.
First, config files go in config/server.
In this example, the target servers are running Debian (Etch), and config/server/ corresponds to the root directory of the server—so we’ve got /var, /etc, and so on.
With this under version control along with the rest of the app, you can now roll back to earlier “known-good” configurations lickety-split.
As an added benefit, this increases transparency for your team, since developers can see how the deployment works without having to actually visit the servers.
And here’s where it gets even better—you can now use Capistrano to deploy configs!
Dig on this:
rake deploy:config
desc "Deploy server configurations"
task :config,:roles=>:app do
# Export to a temp directory, to avoid uploading .svn directories.
temp_dir = "/tmp/capistrano-#{Time.now.strftime("%Y%m%d%H%M%S")}"
system "svn export config/server #{temp_dir}"
system "scp -r #{temp_dir}/* #{user}@#{host}:/"
system "rm -rf #{temp_dir}"
sudo "chmod 700 /etc/monitrc"
sudo "chmod 600 /etc/mysql/my.cnf"
sudo "chmod -R a+wx /var/service/*"
sudo "chmod +x /home/deploy/backup_db"
deploy::reload_monit
deploy::restart_mysql
deploy::restart_mongrels
deploy::restart_apache
end
- This happens to be a subversion environment; if you’re on git you can probably just omit the exporting step.
- Make sure you completely understand how “scp” works—if this is new to you, bone up, because a mistake here can really ruin your day.
Please note that this code snippet will almost certainly not work for you as-is; you will have to adjust, rewrite, and optimize this for your unique situation.
One last tip: If you run into problems at first, make sure that permissions are reset correctly; these are idiosyncratic and tend to get wrecked in transition. It’s a simple/best practice to explicitly reset the permissions in your deployment.
You’ll thank yourself later—enjoy!
written by shinji kuwayama on July 23rd, 2008 @ 04:13 PM
Time Parseable
Nobody likes dropdowns. datetime_select and date_select? Ugly troupes of unwieldy elements, each of them. They form a line and rudely spit lists of numbers at you. Who wants that? I know how to type a date. Rails knows how to parse a date. Time.parse, let’s be friends!
$ script/plugin install git://github.com/cementhorses/time_parseable.git
Now, let’s say we have this object filled with timestamp attributes that we need to manage…
# create_table do |t|
# t.timestamp :published_at, :archived_at
# end
class NewsItem < ActiveRecord::Base
time_parseable
end
What? NewsItem now has published_at_string and archived_at_string? Yup. And on assignment, they are automatically parsed with Time.parse.
news_item.published_at_string = 'April 30, 2008'
news_item.published_at # => Wed Apr 30 00:00:00 -0000 2008
If you’re only parsing the published_at column, and magic is looking a bit too expensive for you, scope things down.
time_parseable :published_at
Wonderful.
Wait a second! Time.parse, you’re a good friend, but what are you doing?
Time.parse('Cement Horses') == Time.now # => true
Yes, “Cement Horses” is now, but I only want dates for dates. time_parseable, please work this out.
news_item.archived_at_string = 'Cement Horses'
news_item.archived_at # => nil
news_item.errors.on(:archived_at) # => 'is invalid'
Let’s just throw things in a form_for, and time_parseable will do the rest.
<%= f.label :published_at_string %>
<%= f.text_field :published_at_string %>
The field, once assigned, will return a strftime-formatted result. We can choose the format (but we must choose wisely—it should be able to parse to the same result).
time_parseable :format => '%I:%M %p on %b %d, %Y'
That’s it for now. Cutting down the form fields, one time at a time.
written by scelis on July 23rd, 2008 @ 04:11 PM
An SSH one-liner to authorize via public-key
Here's a two-part tip on SSH productivity--you can use public-key authentication and SSH's built-in configuration options to save some time every day.
1) Authorize your public key. If you're like me, it's a bother to remember each little step -- here's the one-liner I use for convenience.
> ssh someuser@remotehost.com "echo `cat ~/.ssh/id_rsa.pub` >> ~/.ssh/authorized_keys" |
This will append your key to the remote host's list of authorized keys.
Don't have a public key yet? You can generate one with:
> ssh-keygen |
You'll find a brand-new keypair in your ~/.ssh directory. Read up on public-key cryptography if it's new to you.
2) Now add the remote host to your (local) .ssh/config file:
1 2 3 |
Host rh Hostname remotehost.com User someuser |
The SSH config file can contain many entries; just add this to the list. "Host" is an alias/nickname/shortcut of your choosing.
So, you can now SSH to your remote host with:
> ssh rh |
This will save you a little typing. Public-key authentication is a "best practice" anyway -- it's good to develop the habit. For example, this is the only way to SSH into Amazon EC2 instances, and for administrators, it means you can share access to a SSH account (say, a deployer) without floating the password around.
Bonus tip: If you find Capistrano and Net::SSH behaving quirkily, make sure you have the latest versions of both. Recent updates to Net::SSH have included various updates and fixes relevant to public-key authentication.
cf. http://net-ssh.rubyforge.org/
cf. http://groups.google.com/group/capistrano/
written by shinji kuwayama on June 23rd, 2008 @ 02:46 PM
MicroApps (or little ditties) with Sinatra
Me and one of the other horses left the stables recently and went to RailsConf. Of all the sessions I attended, my favorite one was by far Erik Kastner’s talk entitled MicroApps for Fun and Profit.
Erik Kastner explained that MicroApps are small apps that you can write the bulk of the code in a day… or get completely done in one sitting (one day).
They can be simply HTML or HTML/CSS/JavaScript… they can be written in Camping, they can be API mashups, you could use Yahoo! Pipes, it could be just text on a page. You could use Ruby on Rails, you can use a blog engine… it doesn’t really matter, it just has to be done in one sitting.
The app he demoed (called Jeff4Good ) is a one-page web form that takes “donations” of stuff or money to help his friend Jeff who needed money for a hospital trip that cost him a bunch of money.
The Jeff4Good app uses the relatively new ruby microframework, Sinatra. He wrote it within one day. Personally, I have ideas for web apps all the time – it’s rare that I have time to actually get something out there, but the MicroApp “philosopy” that Erik Kastner proposes (along with things like the Sinatra framework) makes it seem so much more possible to get stuff out there. I love the idea of getting something completely done in one sitting – I’ve got waaaay too many ideas that haven’t been implemented right now.
Erik pointed out that the title of the talk should be “MicroApps for fun and Micro Profit” because most of the MicroApps that he has written were not profitable – or if they were, the profit wasn’t much.
The profit that you do gain, however, is that you get to learn something new and you build your portfolio. You can play around with ActiveRecord or DataMapper in new ways. You can start hacking on API’s that you haven’t played with before. You also get to build your portfolio of successful web apps. That can lead to promotions or job offers.
Erik also pointed out that he’s been able to work with some high profile developers and designers because he didn’t need a big commitment from them… you might be able to get a great designer to help out on a fun little project and make your MicroApp look super sweet.
Some examples of MicroApps:
metaatem.com/words (Spell your name in pictures from Flickr)
Twistori (twitter mashup)
Foamee (twitter mashup – tracks who you owe beer or coffee to)
CrocSpotting (a phoblog (photo blog) that uses Yahoo! Pipes & a Flickr feed of Crocs (you know those shoe things))
Learn more about the Sinatra Microframework at sinatrarb.com and gittr.com
Write your first “hello world” Sinatra app in less than 60 seconds:
$sudo gem install sinatra |
1 2 3 4 5 6 |
require 'rubygems' require 'sinatra' get '/' do "OMG, like, hey world!" end |
Save your 5 lines of code and then run the app:
$ruby frank.rb |
Then, it should say:
frank takes the stage on port 4567 |
Go to localhost:4567 in your browser.
“OMG, like, hey world!”
See – fun… and easy!
written by dustin anderson on June 17th, 2008 @ 06:50 PM
RoR: Schedulable
What it is.
If you have data that must go live on a specific date; If you have a model object you would like to query for it’s published state; If you would like the functions of publishing and un-publishing content to be precise and understandable, the Schedulable plugin may be for you. In short, adding Schedulable to your models will allow you to manage the publishing of your data through the liberal use of semantic sugar. The goal of the Schedulable plugin is to be intuitive, concise and easy while solving an often necessary and crucial business need: Scheduling your content.
How it works.
Calling schedulable automatically hooks a few methods to a published_at column:
scheduled?(trueif the item is scheduled to be published but isn’t yet)published?(trueif the item is published)
The real power is when expiration is a question
schedulable :end => :archived_at
or
schedulable :published_at, :archived_at
does a little more:
scheduled? :archived_at(trueifarchived_atis set in the future)archived?(trueif the item has been archived)
with a note:
published?returnsfalsewhenarchived?returnstrue.
It’s all semantic sugar:
schedulable :activated_at, :terminated_at, :end_required => true
therefore creates:
activated?terminated?
And that last option? It just adds a validation requiring the end to be set if the start is.
We have your other validations taken care of, too. We’re just more comfortable with things when they’re chronological.
How can I get it
On Edge:
$ script/plugin install git://github.com/cementhorses/schedulable.git
…otherwise
$ git clone git@github.com:cementhorses/schedulable.git vendor/plugins/schedulable
written by dbora on May 29th, 2008 @ 08:30 PM
Less work, more be-ing with quick shell aliasing
This weekend, after working an endless 5 hour work week, I decided that I want to implement new ways for me to continue to be even lazier than I already am…
After laboriously lifting my heavy 4” long fingers to ssh into another server that I couldn’t remember the IP address for, I started to think there has to be a better way.
Why am I always repeatedly type long lines of ssh logins, rake tasks, etc. into the command line? I’m always trying to stay DRY in my application code, and it’s got me thinking, how can I sort of stay “DRY” at the command line and limit the amount of work that I do?
Why don’t I create time saving aliases more often?
One big reason that I don’t create time saving aliases more often is because it’s not brain-dead-easy enough for me to edit my .bash_profile… so, I created an alias to quickly edit my .bash_profile:
# 'be' (for "bash edit") alias be='mate ~/.bash_profile'The really sweet version that re-sources your .bash_profile after you save your changes is:
alias be='mate -w ~/.bash_profile;source ~/.bash_profile'
Then, I decided to take a look at where I could reduce repetitive tasks, so I executed the history command to see what are some of the longer commands that I’ve written repetitively.
~ $ history 10 ssh deploy@myserver.railsmachina.com 13 cd Projects2/ 55 rake db:migrate 57 rake db:migrate RAILS_ENV=test 88 rake ultrasphinx:bootstrap
I see that I’m typing a lot of long rake tasks like rake db:migrate, rake ultrasphinx:bootstrap, cd Projects/post_it, cd Projects/my_project
alias rdb='rake db:migrate' alias rub='rake ultrasphinx:bootstrap' alias my_project='cd Projects/my_project/trunk/'I don’t want to go crazy in one day and add EVERYTHING, I’d rather fine tune this over time and make the process of adding and editing my bash_profile easier… So, by just adding the
be alias, I now have an easier way to create shortcuts and it makes me a much happier programmer:
alias be='mate ~/.bash_profile'
We discussed the possibility of writing a function (let’s call it balias) that could automatically add an alias to your bash_profile (e.g. balias myserver "ssh live@8.23.456.78"). My only hesitation with doing that is it could make your .bash_profile a disorganized mess… But, it would be very nice to just add new aliases via command line.
alias in your command line to remember what aliases you have added.
~ $ alias alias be='mate -w ~/.bash_profile;source ~/.bash_profile' alias ett='mate app config lib db public test vendor/plugins &' alias gd='git diff | mate' alias app_live_1='ssh live@8.22.345.67' alias app_live_2='ssh live@8.22.345.99' alias app_live_db='ssh live@8.22.345.222' alias app_sandbox='ssh sandbox@8.22.43.243' alias app_staging='ssh staging@8.22.43.244' alias rdb='rake db:migrate' alias rdbt='rake db:migrate RAILS_ENV=test' alias td='mate ~/Documents/todo.txt'Footnotes:
- See other people’s .bash_profiles here: http://dotfiles.org/
- You can also edit your .ssh/config, but I find it just as good to put them in the .bash_profile.
- You can set up autocomplete for ssh as well – using this Life changing shell function, I’m probably missing something about setting up .ssh/config, but right now, it’s not working well for me since all my logins are always
ssh username@8.34.56.123and not simplyssh domain_name.
written by dustin anderson on May 8th, 2008 @ 07:31 PM
Interceptor Methods
class Unicorn
attr_accessor :climate
def frolic
puts 'Frolic in a meadow, enchant other forest creatures with majesty'
end
end
# this class definition is locked away somewheres
# now let's reopen the class and add the interceptor
class Unicorn
# copy the original method so we can still call it
alias_method :old_frolic, :frolic
# let's intercept calls to frolic method
def frolic
if @climate == 'tundra' # new functionality
puts 'Frolic on a glittering glacier, under the Aurora Borealis'
else # conditionally default to old method definition
old_frolic
end
end
end
written by jjones on May 7th, 2008 @ 07:28 PM
cementhorses.com
Recent
- Engineering happiness (August 15th)
- The future with gestures (August 14th)
- Debugging Kentico sites in vs.net 2008/05 improve compilation time (August 14th)
- Resistance ...is a good thing? (August 13th)
- Managing dashboard widgets on various external displays (August 1st)
- Counting in CSS (July 28th)
- Take control of your server configuration with Capistrano (July 23rd)
- Time Parseable (July 23rd)
- An SSH one-liner to authorize via public-key (June 23rd)
- MicroApps (or little ditties) with Sinatra (June 17th)
- RoR: Schedulable (May 29th)
- Less work, more be-ing with quick shell aliasing (May 8th)
- Interceptor Methods (May 7th)
Comments
- Receengalge on Managing dashboard widgets on various external displays
- smuldegmelp on Managing dashboard widgets on various external displays
- urbakGurI on Managing dashboard widgets on various external displays
- typeRoathydop on Managing dashboard widgets on various external displays
- adulderve on Managing dashboard widgets on various external displays
- ladyalins on Managing dashboard widgets on various external displays
- Smoorogaums on Managing dashboard widgets on various external displays
- Luiz on MicroApps (or little ditties) with Sinatra
- Chris Schneider on MicroApps (or little ditties) with Sinatra
Categories
- Stuff You Already Know (6)
- Open Source (2)
Cement Horses Pics
Archives
- August 2008 (5)
- July 2008 (3)
- June 2008 (2)
- May 2008 (3)
