26.2. Folder Actions
A folder action involves a script being called automatically when certain events take place in a designated folder in the Finder. A script to be used as a folder action does not live in the folder with which it is associated; rather, it should live in your user library, at ~/Library/Scripts/Folder Action Scripts. Alternatively, such a script may live in the top-level /Library/Scripts/Folder Action Scripts, where you'll find some useful examples of folder action scripts, but the location in your user library is the default.
Because the script and the folder are in different places, an extra step is required in order to form the explicit association between a particular script and a particular folder. In essence, this association is the folder action. To form such an association is to attach the script to the folder; to break the association is to remove the script from the folder. The script is not actually moved; attachment and removal are conceptual, not physical. Attachment and removal are implemented through the System Events application (see "System Events" in Chapter 23). System Events associates a folder with a script through a folder action object. These folder action objects are maintained as top-level elements of the System Events application class. System Events is then responsible for watching those folders to see whether an appropriate event takes place in the Finder, and, when it does, for sending the corresponding messages to any attached scripts. System Events doesn't do this, though, unless you also enable the folder actions mechanism as a wholeyou do this through its folder actions enabled property, which functions as a kind of master switch.
The relationship maintained by a folder action object is one-to-many: a folder action object has one folder path property, but it can have many script elements, meaning that more than one script is attached to that folder. Thus, the same folder can trigger multiple scripts. You might take advantage of this architecture, for example, to have different scripts respond when different kinds of event occur. Furthermore, a folder action object can be disabled (without turning off the folder actions mechanism), and a script attached to a folder action object can be disabled (without removing it from the folder action object, and without disabling the folder action object).
Because System Events is a scriptable application, you can give it all appropriate instructions explicitly by means of AppleScript. In general, however, there is no need to do so. Apple provides a graphical interface through the Configure Folder Actions application, located in /Applications/AppleScript. (You can start up Configure Folder Actions directly, or launch it from a button in the AppleScript Utility application.) With the checkbox at the top of the window, you toggle on or off the folder actions mechanism as a whole. Beneath this are two lists. The list on the left is called "Folders with Actions," but it is not a list of folders; it is a list of folder action objects. So, using the list on the left, you maintain the list of folder actions: you can create a new folder action, destroy an existing one, and even rename a folder action (this does not rename the assocated folder, of course). The list on the right shows the scripts associated with the folder action object selected on the left; here you can attach or remove a script from a folder action object. You can also toggle the enablement of a folder action object or an attached script, and you can open a script for editing.
Another interface is provided by way of a folder's contextual menu within a Finder window. This is a much simpler interface than the Configure Folder Actions application, because it is clear from the outset what folder is in questionit's the one whose contextual menu you're usingand because only commands appropriate to the state of the folder actually appear in the menu. Thus, if the folder actions mechanism is turned off, the only thing you can do here is turn it on. If the folder actions mechanism is turned on, you can attach, remove, or edit an associated script. The only thing you can't do is toggle the enablement of an existing folder action object or attached script.
If, on the other hand, you want to configure folder actions directly by using AppleScript to drive System Events, it is not difficult to do. There are some scripts located in /Library/Scripts/Folder Actions (accessible through the Script Menusee "Script Runner" in Chapter 2) that can serve as useful examples of common tasks:
So much for how to associate a script with a folder. What about the code that goes into a folder action script? The StandardAdditions scripting addition defines (in the Folder Actions suite ) five events that may be sent to a folder action script:
Your folder action script will contain a handler for each event to which you'd like it to respond. (One and the same script can respond to more than one event.) In this example , our folder automatically decodes any .hqx files that are put into it (it is assumed that you've installed StuffIt Expander , which doesn't come with Tiger):
on adding folder items to ff after receiving L tell application "Finder" repeat with f in L set n to name of f if n ends with ".hqx" then tell application "StuffIt Expander" to expand f end if end repeat end tell tell application "System Events" if process "StuffIt Expander" exists then tell application "StuffIt Expander" to quit end if end tell end adding folder items to
The script runs when any file is put into that folder, so the first step is to ignore everything except .hqx files. We call StuffIt Expander to decode each appropriate file. This leaves StuffIt Expander running, so at the end we look to see whether StuffIt Expander is running, and if it is, we quit it. A folder with this script attached functions as a kind of magic decoder drop box for .hqx files.
A common error is failing to take account of the fact that the folder action script may do something to an item in the folder such as to trigger the same (or a different) folder action script. This circularity is not a problem as long as it is not vicious. This is one reason why, in the previous script, we test the name of each file; as we expand a file whose name ends in .hqx, we create a new file that triggers the script again, but we ignore it because its name doesn't end in .hqx.