Item Variables and Alfred’s Conditional Widget

Alfred’s Script Filter returns a list of items. When the user selects one and presses Enter, Alfred does not call Python again — it passes the item’s arg and variables to the next widget in the workflow graph.

afwf exploits this mechanism to let Python code declare the intended follow-up action directly on each item, while keeping the workflow graph (the Alfred UI) completely static. The Conditional widget reads the variables and routes to the correct downstream action widget.

The Core Pattern

Every set_* helper on Item writes a pair of variables:

  • a flag key set to "y" — the Conditional widget checks this

  • a payload key holding the data the downstream action widget needs

item = Item(title="Open Python docs")
item.open_url("https://docs.python.org/")

# item.variables is now:
# {
#     "open_url":     "y",
#     "open_url_arg": "https://docs.python.org/",
# }

The Alfred Conditional widget is configured once with a branch for each possible flag. At runtime it reads {var:open_url}, finds "y", and routes to the Open URL widget that reads {var:open_url_arg}. No Python code runs at this stage — Alfred handles the action entirely.

Variable Reference

The following table lists every flag/payload pair defined in VarKeyEnum, the Item method that sets them, and the Alfred widget that consumes them.

Item method

Flag key

Payload key

Alfred widget

open_url(url)

open_url

open_url_arg

Actions → Open URL; URL field: {var:open_url_arg}

open_file(path)

open_file

open_file_path

Actions → Open File; File: {var:open_file_path}

launch_app_or_file(path)

launch_app_or_file

launch_app_or_file_path

Actions → Launch Apps / Files

reveal_file_in_finder(path)

reveal_file_in_finder

reveal_file_in_finder_path

Actions → Reveal File in Finder

browse_in_terminal(path)

browse_in_terminal

browse_in_terminal_path

Actions → Browse in Terminal

browse_in_alfred(path)

browse_in_alfred

browse_in_alfred_path

Actions → Browse in Alfred

run_script(cmd)

run_script

run_script_arg

Actions → Run Script; Script: {query}; also sets item.arg

terminal_command(cmd)

terminal_command

terminal_command_arg

Actions → Terminal Command; Command: {query}; also sets item.arg

send_notification(title, subtitle)

send_notification

send_notification_title / send_notification_subtitle

Outputs → Post Notification

Note

run_script() and terminal_command() also set item.arg to the command string. Alfred passes arg as {query} into the connected Run Script / Terminal Command widget, so the command reaches the widget through both the variable and the arg.

Configuring the Conditional Widget

In Alfred’s workflow editor, add a Utilities → Conditional widget and connect the Script Filter to it. Add one condition branch per action type your Script Filter uses:

if  {var:open_url}              is equal to    y   →  Open URL widget
if  {var:open_file}             is equal to    y   →  Open File widget
if  {var:run_script}            is equal to    y   →  Run Script widget
if  {var:send_notification}     is equal to    y   →  Post Notification widget

Each downstream widget reads from the corresponding payload variable:

  • Open URL — URL field: {var:open_url_arg}

  • Open File — File field: {var:open_file_path}

  • Run Script — Script field: {query} (Alfred copies item.arg here)

  • Post Notification — Title: {var:send_notification_title}; Subtitle: {var:send_notification_subtitle}

Combining Multiple Actions

An item can set more than one action pair. Alfred evaluates the Conditional branches in order — the first matching branch wins. Arrange branches so the most specific checks come first.

A common combination is run_script + send_notification: the script runs, then Alfred shows a notification to confirm completion.

item = Item(title="Write file and notify")
item.run_script("/path/to/.venv/bin/afwf-examples write-file-request --content 'hello'")
item.send_notification(title="File written", subtitle="success")

# item.variables:
# {
#     "run_script":                  "y",
#     "run_script_arg":              "/path/to/...",
#     "send_notification":           "y",
#     "send_notification_title":     "File written",
#     "send_notification_subtitle":  "success",
# }

For this to work, the Conditional widget must have branches for both run_script and send_notification, and the Run Script widget must connect forward to the Post Notification widget.

Modifier Key Overrides

set_modifier() adds an entry to item.mods so that holding a modifier key (e.g. ) shows an alternate subtitle and passes a different arg.

By default a mod entry inherits the item’s variables. To prevent inheritance — for example, so that + Enter does something completely different — pass an explicit variables={} inside the mod dict.

See ModEnum for the full list of supported modifier key combinations.

Why This Design

Keeping the workflow graph static has a concrete advantage: the Alfred UI does not need to change when new behaviour is added. Adding a new action type only requires:

  1. A new VarKeyEnum / VarValueEnum pair in constants.py

  2. A new set_* method on Item

  3. A new branch in the Conditional widget (one-time, in Alfred’s UI)

All existing Script Filters that do not set the new variable are unaffected.