On my WordPress blog I ran a plugin called Download Monitor which allowed me to create download ids that could be inserted via short tags. When I updated a download version, any mention of it throughout the site would be updated to show the latest version and link to the most recent download package. I needed something similar on my Jekyll blog to keep things up to date. The following system is geared toward Jekyll but the concept could be adapted to any static blog.
I started by using a script that looped through all of the downloads listed in my WordPress database and generated a CSV file of all of my downloads and their associated metadata. For example:
id,title,file,version,description,info,icon,updated
1,Clippable to Evernote Service,/share/clippable-to-evernote.zip,1.0,"A Snow Leopard System Service [...]",http://brettterpstra.com/code/clippable-to-evernote-service/,/images/serviceicon.jpg,Tue Feb 23 21:55:00 -0600 2010
This file is editable in a plain text editor or in a spreadsheet app like Numbers, and doesn’t require an existing WordPress database to start, just a plain old CSV file with the appropriate data.
Next, I just needed a tag plugin that would let me create a tag like:
The tag would insert a templated “download card” with the appropriate data:
The current tag plugin I’m using has the template hardcoded and needs to be updated to handle an actual external template file, but it should give you the idea:
Updating a download’s row in the CSV file with a new download link, version number, update time and/or description change will recreate all of the references to it in the site next time I build it.
I also added a Rake task for searching my downloads and finding the ID for use in the tag:
desc"Find a download ID"task:find_download,:termdo|t,args|raise"### You haven't created a download csv yet."unlessFile.exists?('downloads.csv')results=CSV.read("downloads.csv").delete_if{|row|row[0].strip=~/^\d+$/&&row[1]+" "+row[4]=~/.*#{args.term}.*/i?false:true}results.sort!{|a,b|a[0].to_i<=>b[0].to_i}.map!{|res|res[0]+": "+res[1]+" v"+res[3]}results_menu(results,"download")print("Select download")whileline=Readline.readline(": ",true)if!line||line=~/^[a-z]/iputs"## Canceled"Process.exit0endline=line.to_iif(line>0&&line<=results.length)id=results[line.to_i-1].match(/^\d+/)[0]download_tag="{% download #{id} %}"%x{echo "#{download_tag}\\c"| pbcopy}puts%Q{Download tag in clipboard: "#{download_tag}"}Process.exit0elseputs"## Selection out of range"Process.exit0endendend# creates a user menu from a hash or arraydefresults_menu(res,type="file")counter=1putsres.reverse!res.eachdo|match|match=match.class==String?match:match[:path]iftype=="file"display=match.sub(/^.*?\/([^\/]+)$/,"\\1")display.gsub!(/^[\d-]+/,'')display.gsub!(/\.(md|markdown)$/,'')display.gsub!(/-/,' ')elsiftype=="download"display=match.sub(/^\d+:\s*/,'')elsedisplay=match.stripendprintf("%2d ) %s\n",counter,display)counter+=1endputsend
Now typing rake find_download[nvalt] will show me all downloads matching the search term “nvalt,” offer a menu of matches and put the complete Liquid tag for the selected result in my clipboard:
I also plan to add a Rake task to make adding new downloads and updating existing versions from the command line as simple as possible.
With a little modification, this system could easily be used to generate a “Downloads” page for my site, though I’ve decided that’s really not necessary. I may change my mind in the future, though.
Todo
What I’ve shared here is a functioning system that is currently in use. Before it’s “complete” and ready to share in my plugins repo, there are a few things I’d like to polish:
A template system
reads a template name from the tag
works with multiple templates
Rake tasks for adding and editing downloads more easily
script for adding downloads via Service or droplet
(Possibly) a plugin for generating a Downloads page