Say you look up 'transform':
To build this type of result:
Your script is going to have to output XML.
<?xml version="1.0"?>
<items>
<item arg="http://caniuse.com/#feat=transforms2d" autocomplete="" uid="CSS3 Transforms" valid="yes">
<title>CSS3 Transforms [IE:9-px-, FF:9-px-, GC:9-px-, S:8-px-]</title>
<subtitle>Method of transforming an element including rotating, scaling, etc.</subtitle>
<icon>icon.png</icon>
</item>
</items>
Blecch! But with the builder
ruby gem, or any other library that abstracts the generation of the XML node, it's not so bad.
To get a result like the one above you have to populate the XML node with a few things, singled out with XPath (double blecch!) below:
/items/item[@arg]
(e.g. above is "http://caniuse.com/#feat=transforms2d") This is what will be used for the action, be it opening a URL or putting something in the clipboard, etc./items/item[@uid]
(e.g. above is "CSS3 Transforms") This is a value that should be unique across all of the results that your script may return. I assume this is for Alfred's internal use./items/item[@valid]
(e.g. above is "yes"). Not sure what this is, but I'm guessing it's so that Alfred can format something differently if the attempt to fetch the item resulted in an error./items/item/title/text()
(e.g. above is "CSS3 Transforms [IE:9-px-, FF:9-px-, GC:9-px-, S:8-px-]") This is the big text in each result./items/item/subtitle/text()
(e.g. above is "Method of transforming an element including rotating, scaling, etc.") This is the little text in each result.
This script will generate the XML node above, given some command-line arguments (that's what ARGV
is for), using the 'builder' gem. I didn't have to gem install
anything, so I'm assuming it's part of the standard library.
require 'builder'
arg = ARGV[0] || 'arg'
title = ARGV[1] || 'title'
subtitle = ARGV[2] || ''
valid = ARGV[3] || 'yes'
uid = ARGV[4] || (0...8).map { (65 + rand(26)).chr }.join
icon_path = ARGV[5] || 'icon.png'
xml = Builder::XmlMarkup.new target: STDOUT, indent: 2
xml.item(arg: arg, uid: uid, valid: valid) { |i|
i.title(title)
i.subtitle(subtitle)
i.icon(icon_path)
}
So—say it's called item_xml.rb
—from the command line you would do:
$ ruby item_xml.rb "http://caniuse.com/#feat=transforms2d" "CSS3 Transforms [IE:9-px-, FF:9-px-, GC:9-px-, S:8-px-]" "Method of transforming an element including rotating, scaling, etc." "yes" "CSS3 Transforms"
<item arg="http://caniuse.com/#feat=transforms2d" uid="CSS3 Transforms" valid="yes">
<title>CSS3 Transforms [IE:9-px-, FF:9-px-, GC:9-px-, S:8-px-]</title>
<subtitle>Method of transforming an element including rotating, scaling, etc.</subtitle>
<icon>icon.png</icon>
</item>
```bash
Now you can use this script in any workflow, from a main script. For example, this workflow will evaluate a ruby expression, so in the "main" script, in bash:
```bash
expr='{query}'
result=$(ruby -e "puts($expr)")
echo "<?xml version="1.0"?>"
echo "<items>"
ruby item_xml.rb "$result" "$result" "{query} => $result" "yes"
Now, it's entirely likely that I'll enter something that will raise an exception in Ruby, so let's add a bit that'll catch the exit code from ruby
:
expr='{query}'
result=$(ruby -e "puts($expr)")
valid=$([[ $? = 0 ]] && echo "yes" || echo "no")
echo "<?xml version="1.0"?>"
echo "<items>"
ruby item_xml.rb "$result" "$result" "{query} => $result" "$valid"