When I switched from WordPress to Octopress I heavily edited my .htaccess file on the assumption that no one would still have a bookmark to one of my old posts using an out-dated URL. That assumption was wrong.
In October 2003, for example, I posted a comment on a Kottke.org piece about the contents of your dock. And wouldn’t you know, that posting still gets traffic eight years later and that traffic still follows links buried in the comments, one of which leads to my site.
I know all of this thanks to Mint and the Error Tracker Pepper.
So this morning I reassembled my .htaccess file, bringing back in all the old MoveableType redirects, and while I was at it, I added one to catch all the old monthly archive pages too. The MoveableType redirects are specific to my site, but the basic format looks like this
Redirect 301 /blogs/######.html https://zanshin.net/YYYY/MM/DD/title-slug/I no longer have the script I used to generate these, but it read the meta data for each posting exported from MoveableType in order to match up the meaningless 6-digit posting number with the Year, Month, Day, and post title for each entry.
The monthly archive redirects were easier to deal with as that URL pattern could be neatly fit into a regular expression:
Redirect 301 /blogs/\d{4}_\d{2}.html https://zanshin.net/archives/In order to really clean things up I need to create a categories page that shows my remaining categories, with links to pages showing the entries for each of those categories, and once that hierarchy is in place, redirect old category links to that page. That will have to wait for another day. Until then the 404 page will have to suffice.
Fantastisch.
Fantastic tee-shirts imaging great scientists as rock band logos. I particularly like the Hawking and Tesla/Edison ones.
This would cause a bit of a stir at the nearby computer users group monthly meeting.
A mesmerizing video showing how pendulums of differing lengths interact when all started simultaneously.
When I setup Octopress I followed the directions outline on the Octopress Setup page. In a nutshell these steps create a Github repository for you to track your instance of Octopress with, and a local (i.e., on your computer) instance of Octopress where you create your website, generate it, and from where you deploy. Diagrammatically it looks something like this: 
From your local instance you can fetch updates from Octopress and keep your Github instance synchronized via git push origin master.
My Git-fu is not very strong yet, so I was at first mystified and then frustrated to discover that I couldn’t easily share a plugin I added to my Octopress installation with Brandon Mathis’ ur-Octopress. On Github, at least, without a fork tying your repository back to a source repository, there is no way to issue a pull request. It maybe that one can create the equivalent of a pull request on their local copy of a repository and send a pull request to the project owner, but my Git understanding doesn’t include that knowledge.
What I wanted and needed was an active fork of the ur-Octopress, a fork that was actively tied to my local instance of Octopress as well. After asking one of the developers I work with who has more Git experience than I, and after posting a question on StackOverflow, I took the following steps to “add” a fork to my Github Octopress repository.
I deleted my existing Github Octopress repository. It was named “Octopress” so any new fork of the ur-Octopress would result in the fork being called Octopress-1. Not what I wanted.
I forked the imathis/octopress repository.
I removed the, now broken, remote between my local git repository and the deleted Github repository using git remote rm origin
I created a new remote, called origin, to link my local git repository to the forked Octopress on Github, via git remote add origin git://github/zan5hin/octopress.git
When I tried to push my local git repository to Github (git push origin master) it failed with the following error message: ! [rejected] master -> master (non-fast-forward). The fork on Github contained changed not present in my local repository that I needed to resolve first. If I have updated locally before starting this process it is likely I wouldn’t have had this error. To resolve the error I ran git pull origin master.
I resolved the two minor merge conflicts created by the git pull.
I generated my site and viewed it via Pow to make sure everything was still working properly.
I synchronized my local repository with Github via git push origin master
The result of all this work is looks like this: 
All of my commits are in place, and I can now generate pull requests for Brandon to process as he sees fit.
Not sure I understand all I know about this, but it seems like a very cool idea.
For some time I have wanted to be able to include links to books or movies that I’ve read or watched on my site. I had seen Adam Polselli’s Readernaut Widget posting a couple of years ago, but had never taken the time to implement it. While I was searching to find it again, I came across this posting about Amazon liquid filters for Jekyll and realized it was exactly what I was looking for.
Here is how I took the Jekyll plugin that Michael Janssen describes and incorporated it into Octopress.
There is a Ruby gem that encapsulates the Amazon Web Services API, making it very simple to query Amazon and parse the result. Make sure you grab the ruby-aaws gem and not the older, deprecated ruby-aws one. If you are using RVM, you’ll need to ensure that you install the gem for the version of Ruby that supports your Octopress installation, in my case ruby-1.9.2.
$ rvm use ruby-1.9.2
$ gem install ruby-aawsJust for completeness sake, I also edited the Gemfile located in the root of the Octopress installation to add the new dependency on ruby-aaws.
source "http://rubygems.org"
gem 'rake'
gem 'rack'
gem 'jekyll'
gem 'rdiscount'
gem 'pygments.rb'
gem 'RedCloth'
gem 'haml', '>= 3.1'
gem 'compass', '>= 0.11'
gem 'rubypants'
gem 'rb-fsevent'
gem 'ruby-aaws'For the source of the plugin code I copied Mr. Janssen’s plugin from Github. Or you can copy it from below:
require 'amazon/aws'
require 'amazon/aws/search'
require 'cgi'
module Jekyll
class AmazonResultCache
def initialize
@result_cache = {}
end
@@instance = AmazonResultCache.new
def self.instance
@@instance
end
def item_lookup(asin)
asin.strip!
return @result_cache[asin] if @result_cache.has_key?(asin)
il = Amazon::AWS::ItemLookup.new('ASIN', {'ItemId' => asin})
resp = Amazon::AWS::Search::Request.new.search(il)
@result_cache[asin] = resp
return resp
end
private_class_method :new
end
module Filters
def amazon_link(text)
resp = AmazonResultCache.instance.item_lookup(text)
item = resp.item_lookup_response[0].items[0].item[0]
url = CGI::unescape(item.detail_page_url.to_s)
title = item.item_attributes.title.to_s.gsub(/ \[Blu-ray\]/, '').gsub(/ \(Ultimate Edition\)/, '')
'<a href="%s">%s</a>' % [url, title]
end
def amazon_authors(text)
resp = AmazonResultCache.instance.item_lookup(text)
item = resp.item_lookup_response[0].items[0].item[0]
authors = item.item_attributes.author.collect(&:to_s)
array_to_sentence_string(authors)
end
def amazon_medium_image(text)
resp = AmazonResultCache.instance.item_lookup(text)
item = resp.item_lookup_response[0].items[0].item[0]
url = CGI::unescape(item.detail_page_url.to_s)
image_url = item.image_sets.image_set[0].medium_image.url
'<a href="%s">{{ $image := .ResourceGetMatch "%s" }}
<img src="{{ $image.RelPermalink }}" >' % [url, image_url]
end
def amazon_large_image(text)
resp = AmazonResultCache.instance.item_lookup(text)
item = resp.item_lookup_response[0].items[0].item[0]
url = CGI::unescape(item.detail_page_url.to_s)
image_url = item.image_sets.image_set[0].large_image.url
'<a href="%s">{{ $image := .ResourceGetMatch "%s" }}
<img src="{{ $image.RelPermalink }}" >' % [url, image_url]
end
def amazon_small_image(text)
resp = AmazonResultCache.instance.item_lookup(text)
item = resp.item_lookup_response[0].items[0].item[0]
url = CGI::unescape(item.detail_page_url.to_s)
image_url = item.image_sets.image_set[0].small_image.url
'<a href="%s">{{ $image := .ResourceGetMatch "%s" }}
<img src="{{ $image.RelPermalink }}" >' % [url, image_url]
end
def amazon_release_date(text)
resp = AmazonResultCache.instance.item_lookup(text)
item = resp.item_lookup_response[0].items[0].item[0]
item.item_attributes.theatrical_release_date.to_s
end
# Movie specific
def amazon_actors(text)
resp = AmazonResultCache.instance.item_lookup(text)
item = resp.item_lookup_response[0].items[0].item[0]
actors = item.item_attributes.actor.collect(&:to_s)
array_to_sentence_string(actors)
end
def amazon_director(text)
resp = AmazonResultCache.instance.item_lookup(text)
item = resp.item_lookup_response[0].items[0].item[0]
item.item_attributes.director.to_s
end
def amazon_running_time(text)
resp = AmazonResultCache.instance.item_lookup(text)
item = resp.item_lookup_response[0].items[0].item[0]
item.item_attributes.running_time.to_s + " minutes"
end
end
endThis file goes in your plugins directory. It really doesn’t matter what you call this, what does matter is that you use one (or more) of the functions defined within the plugin inside Liquid tags to interact with AWS.
If you don’t already have one, create an Amazon Web Services (AWS) account. Depending on what you use it for in addition to the API lookups this plugin will perform, there may be a monthly charge for this service. As near as I can tell, the queries this plugin performs are free.
From your AWS account you will need your Access Key ID and your Secret Access Key. These can be found by going to the Account tab, and then clicking on the Security Credentials link in the left sidebar.
ruby-aaws uses a configuration file, that contains your AWS security credentials, to interact with Amazon. Create a file in your HOME directory called .amazonrc and copy and paste the following lines to it:
# My .amazonrc file for use with ruby-aaws.
key_id = 'YOUR-ACCESS-KEY-GOES-HERE'
secret_key_id = 'YOUR-SECRET-KEY-GOES-HERE'
associate = 'YOUR-ASSOCIATES-ID-GOES-HERE'
cache = false
locale = 'us'
encoding = 'UTF-8'Edit the file, substituting your Access Key, Secret Key, and Associate ID (if you have one) for the place holders. If you don’t have an Associate ID (and or you live where Amazon no long pays associates due to tax laws) and you want to be incredibly generous, you can use my id, zanshinnet.
The ruby-aaws gem will look for this file and use it on your machine when you generate your site and you’ve made use of one of the Amazon liquid tags. Since the .amazonrc file lives on your computer it is relatively safe, however, I changed the file permissions to ‘600’ (owner read/write only) just to be thorough.
Read through the README and INSTALL files that come with ruby-aaws for a complete set of documentation for using the gem. I haven’t yet explored the cache option in the .amazonrc file, but that may improve the gems performance, especially if you have large number of Amazon queries embedded in your site over time.
You are now ready to use the Amazon liquid tags in postings or asides. For any item you wish to link to find the ASIN number embedded in the Amazon URL and include it in a tag. For example, if I wanted a text-only link to the new Ruby book, {{ “1933988657” | amazon_link }}, I would embed this liquid tag in my code: {{ “1933988657” | amazon_link }}. I could just as easily display an image of the book’s cover with {{ “1933988657” | amazon_medium_image}}, like so:
{{ “1933988657” | amazon_medium_image }}
The ASIN is fairly easy to spot in the Amazon URL. In my case I wanted to have links to Amazon things appear (primarily) in the sidebar. So I created a new HTML file in source/_includes/custom/asides called aws.html that looks something like this:
{% raw %}
<section>
<h1>Recent Diversions</h1>
<p>
{{ "0743276396" | amazon_medium_image }}
</p>
<p>
{{ "0743276396" | amazon_link }}
by {{ "0743276396" | amazon_authors }}
</p>
</section>
{% endraw %}With all the pieces in place you are ready to generate your site. During generation the ruby-aaws gem will read your .amazonrc file, and will query AWS to look up any ASINs you’ve included. With only two books listed in my sidebar (I don’t plan on having more than two or three items at any one time) I didn’t notice an appreciable increase in site generation time. But I suspect that a large(r) number of queries could slow your generation down. As always, YMMV.
Outstanding. Makes me want to go out and buy Duck Tape just to support this kind of creativity.