Sure, I'll explain it kind of conceptually what's going on and how it's implemented.
The three key factors here:
* Building paths using a separator character (➣) in the query
* Autocompletion to help build those paths
* Using ids in the path
Based on the current "path" in the query i decide what results to show.
So if nothing has been entered yet, in the case of the workflow repository one, i show the 4 main menu entries, each of which autocompletes to a defined Tag + the separator.
The next invocation of the script might be with the query "Browse ➣ ".
In that case I present all workflows, each of which autocompletes to "Browse ➣ (bundle id of workflow) ➣ "
I use the bundle id in the path because the next menu needs to know what you chose. For the movie workflow I use the IMDb-ID.
It would be prettier if I could use "Shutter Island ➣ " in the path, but sadly that isn't unique enough. It would also allow deleting the separator character with backspace and thereby going back to the previous menu and still get sensible results back (as the query would then be "Shutter Island" and not "tt1130884", the IMDb-ID).
But the query string is the only transfer mechanism we have to determine what item has been chosen.
For more information on how do the autocompletion check this out (basically, set valid="no" and autocomplete="your path" on an item)
So far for the concept.
On the implementation side i have the helper module AlfredFeedback.
In there I have helper functions "get_path" and "get_query".
get_query returns the very last part of the actual query-string given to the script
get_path returns the current path as an array
So for example "Installed ➣ com.linuslundahl.alfred.phpfunctionsapi ➣ open" would result in
get_path: ["Installed", "com.linuslundahl.alfred.phpfunctionsapi"]
get_query "open"
These help in deciding what items to present.
(In that example, I check if path is two segments long, which would mean I'm in the submenu for a workflow.
The last segment is the bundle id of the chosen workflow and I show the "back", "update", "uninstall" and "open workflow folder" items.
I apply get_query as a filter so that only the "open workflow folder" item remains)
Next I have a simple class called Item that just holds all the information for an feedback result item (title, subtitle, icon, arg, …)
Extending that I have a class called Menu.
These are the items that bring you to a submenu.
They have their autocomplete-attribute automatically set to the current path + the argument of that item + separator, and valid to "no".
Lastly I have the class Feedback, which gathers Items (and Menus) with add_item and add_menu methods.
(I also have .fixed_order in there, which automatically gives the items an uid of timestamp + index in item list, thereby the items are always presented in the order they are specified)
(And .autofilter, which takes the query to filter the items before printing them out if set)
After that just print out the feedback.to_xml
As for allowing different kinds of action on an item:
I use argument-strings in the form of "(action):(parameter)". In the movie workflow I have a whole bunch of actions for showing an image, opening URLs, showing large text, ..
This argument-string is passed to an output-script and appropriate action is taken.