Jump to content

[HOW TO] Script Filters: Reusing a single script filter or chaining multiple together


Recommended Posts

This tutorial is aimed at Alfred 2. Alfred 3 allows you to connect one Script Filter to another, so these workarounds are not necessary. (They might still be interesting, however.) [added 2017-03-20 by deanishe]

 

Provided below is a workflow that provides a demonstration of how to reuse a single script filter or, how to chain multiple script filters together so that you can create the illusion of having multiple steps or allow you to further refine results from the first script filter, using the second.
 
FiltersDemo.jpg
 
Demo 1
This demo shows how you can use AppleScript to call the next step (another script filter) after the first script filter has completed. This could be used to send the value of the first script filter into the second, or, you could just save the values to file and then read them all back in when you are done. This example will save the value to file.
 
Demo 2
This demo shows how you can reuse a single script filter using autocompletion to separate multiple inputs with a delimiter. When the filter completes, you could then use that delimiter to split the string into its multiple parts. This works really well if your input data is numeric or short strings.
 
Demo 3
This demo shows how you can reuse a single script filter, with AppleScript to provide multiple inputs/steps to the end user.The data entered by the user is saved to file in each step, then read in and appended together at the end. You could separate the final output with a delimiter and pass it on to something else if you wanted.
 
There are many ways that this could be customized to your liking. Change the delimiters, how values are passed, etc. This thread is merely meant to provide examples of how this could be accomplished for those interested.
 
Download the demo workflow here.

Edited by deanishe
Add note that the tutorial is aimed at Alfred 2, not 3
Link to comment

This is great. However, I feel like there is a better way to go about this. Why can't we chain the output of a script filter to the input of another script filter? Applescript feels like a hack.

 

I am working on a workflow that gathers the coming weeks comic books from this website. I have scraped the page and stored the results in a file. I would like to start my workflow and see the publishers releasing comic books this week. Actioning on a publisher should bring you to a list of all the comics that specific publisher is releasing that week. Further actioning on a specific book would bring you to the item web page associated with that book.

 

Maybe the applescript way is sufficient, but intuitively I believed that you could chain script filters together and came here when I realized you could not.

 

Thanks for all the help though! I love Alfred!

Link to comment

I've got an implementation of my project working with autocomplete and no applescript. However, it requires that the script filter take a required argument in order to facilitate passing my next argument to my script. 

 

My script now takes an initial argument. In my script I decide which step of the workflow (essentially which "page" I want to be in) I am in based on this initial argument. I then generate different feedback based on this decision.

 

It works...but native chaining support would be greatly appreciated.

 

Also, native chaining support could introduce the ability to step forward and backward steps in the workflow. But that argument is probably for another day and another thread...

Link to comment

I've got an implementation of my project working with autocomplete and no applescript. However, it requires that the script filter take a required argument in order to facilitate passing my next argument to my script. 

 

My script now takes an initial argument. In my script I decide which step of the workflow (essentially which "page" I want to be in) I am in based on this initial argument. I then generate different feedback based on this decision.

 

It works...but native chaining support would be greatly appreciated.

 

Also, native chaining support could introduce the ability to step forward and backward steps in the workflow. But that argument is probably for another day and another thread...

 

 

The Applescript solution works for me with a small delay but I agree with Bueno. It would be nice to have native chaining support...

 

Guys,

I assure you that we are fully aware of the desire for more flexibility when it comes to chaining items together. However, everything can't make it into a single release. The reality of it is, releases will never happen if you keep adding until you cover every potential use case and feature requested. Andrew has many plans in mind to continue to expand the functionality of workflows in Alfred. So sit back and relax. This is only the beginning. 

Link to comment

David, thank you for these examples! Third one was not so obvious for me, but in the end I've cracked it :ph34r: .

In case that there is someone like me:

In demo3 first node is drawing the output, then pass this to the second node, which create the files and draw nothing, except when all three parts is filed, then, because empty output, last node(applescript one), trigger the script back again.

Link to comment
I assure you that we are fully aware of the desire for more flexibility when it comes to chaining items together.

 

Does this also mean calling a workflow from within another workflow? I was just looking for this to call the 'Shorten links' workflow instead of completely add the same functionality in my own workflow.

Link to comment

Does this also mean calling a workflow from within another workflow? I was just looking for this to call the 'Shorten links' workflow instead of completely add the same functionality in my own workflow.

 

Two of these examples do that, yes. The other doesn't. If the ability to simply call another workflow from the previous is what you are looking for, this can be done with Alfred 2's AppleScript support. Try the following with a Run Script action or output.

tell application "Alfred 2" to search "nextworkflow args"

 

In this situation, nextworkflow would be replaced with the keyword for the next workflow that you wish to call and args would be replaced with any data that you wish to send to it.

 

This solution will cause Alfred to blink really fast as he will have finished a workflow and simply uses AppleScript to call himself back up.

Link to comment

Hi David,

thanks for all this but I'm looking for something similar for file actions e.g. the Archiver Workflow. At the moment this workflow produces 4 actions in the actions menu. I would like to have one entry in the action menu, clicking on this opens a "submenu" which now shows all actions of this workflow. Possible?

Link to comment

Hi David,

thanks for all this but I'm looking for something similar for file actions e.g. the Archiver Workflow. At the moment this workflow produces 4 actions in the actions menu. I would like to have one entry in the action menu, clicking on this opens a "submenu" which now shows all actions of this workflow. Possible?

 

You could make the file action run Applescript to call Alfred back with the text box prefilled with a keyword and text necessary. That keyword would be a script filter that provided the 4 options

Link to comment

Guys,

I assure you that we are fully aware of the desire for more flexibility when it comes to chaining items together. However, everything can't make it into a single release. The reality of it is, releases will never happen if you keep adding until you cover every potential use case and feature requested. Andrew has many plans in mind to continue to expand the functionality of workflows in Alfred. So sit back and relax. This is only the beginning. 

That's good to hear. And thanks for those examples. Great stuff. :-)

Link to comment

Two of these examples do that, yes. The other doesn't. If the ability to simply call another workflow from the previous is what you are looking for, this can be done with Alfred 2's AppleScript support. Try the following with a Run Script action or output.

tell application "Alfred 2" to search "nextworkflow args"

 

In this situation, nextworkflow would be replaced with the keyword for the next workflow that you wish to call and args would be replaced with any data that you wish to send to it.

 

This solution will cause Alfred to blink really fast as he will have finished a workflow and simply uses AppleScript to call himself back up.

 

I'm doing something similar, but it leaves Alfred open. Here's my osascript:

tell application "Alfred 2" to search "openurl {query}"

 

But in this case, it should immediately hit enter. I don't know anything about Apple script, so hoping that's a snippet to simulate enter. I'm also guessing there's another command to open a new tab in Chrome and go to that URL, but I couldn't figure that out. 

 

Any good tutorials for Apple script?

Link to comment

I'm doing something similar, but it leaves Alfred open. Here's my osascript:

tell application "Alfred 2" to search "openurl {query}"

 

But in this case, it should immediately hit enter. I don't know anything about Apple script, so hoping that's a snippet to simulate enter. I'm also guessing there's another command to open a new tab in Chrome and go to that URL, but I couldn't figure that out. 

 

Any good tutorials for Apple script?

 

The AppleScript search command for Alfred 2 is performing as it should. It's meant to redisplay Alfred pre-populated with text or to adjust the text currently in the field. You can simulate pressing Enter by telling "System Events" to key code. Example:

tell application "TextEdit"
	activate
	tell application "System Events"
		key code 36
		keystroke "this is a test"
	end tell
end tell

 

That would activate the TextEdit window, press Enter to create a new line, and then type "this is a test".

 

As for opening a new tab in Chrome, it can be done with this:

tell application "Google Chrome"
	set myTab to make new tab at end of tabs of window 1
	set the URL of myTab to "http://yahoo.com"
end tell

Link to comment
  • 1 month later...

So currently the ScriptFilter or the Script both needs to be triggered by Enter

 

Is it possible this can be triggered in near-realtime?

 

Something like this:

 

> demo1<space>

Please enter your Firstname

> demo1 MyFirstName<space>

Please enter your Lastname

> demo1 MyFirstName MyLastName<space>

Now I've got all information I need, press ENTER to trigger a notification

 

If <space> is not a good idea to trigger the script, <tab> should be a good choice.

Link to comment

So currently the ScriptFilter or the Script both needs to be triggered by Enter

 

Is it possible this can be triggered in near-realtime?

 

Something like this:

 

> demo1<space>

Please enter your Firstname

> demo1 MyFirstName<space>

Please enter your Lastname

> demo1 MyFirstName MyLastName<space>

Now I've got all information I need, press ENTER to trigger a notification

 

If <space> is not a good idea to trigger the script, <tab> should be a good choice.

 

The script runs at every key press. So, the method you are describing could work, but without pressing enter, you would have to save the input each time in the script and use the same script to clear the input (using AppleScript) which will cause a short flash. What's being triggered when you press Enter (or Tab) is it filling Alfred with the autocomplete value, or, it sending the current value to the next step in the workflow.

Link to comment
  • 9 months later...

Could you maybe help me understand a little how this is working.  I'm kind of new to bash and really new to XML (except for HTML ha).  I know some basics but some of these options are confusing me.

 

- - - - - - - - - demo1: Script Filter - - - - - - - - - -

cat << CODE                                                               // Is this just taking what is typed into alfred and displaying it? What do

<?xml version="1.0"?>                                                // the << do?  I know in bash, cat means to just display contents of a file

<items>                                                                       // does it work the same way here? 

<item uid="demo" arg="{query}" valid="yes">  

<title>First Name</title>

<subtitle>Enter your first name</subtitle>

<icon>icon.png</icon>

</item>

</items>

CODE                                                                          // How does CODE work? 

 

- - - - - - - - - demo1: Run Script - - - - - - - - - -

if [ -f "saved.txt" ]; then               // What does -f do?
rm saved.txt
fi

in=$(echo "{query}" | tr -d "\\")   // How does this work?
                                                  // What does   | tr -d "\\"    do/mean?
echo "$in" > saved.txt            

 

                                                  // Where is saved.txt located in the file structure?

 

- - - - - - - - - demo2: Run Script - - - - - - - - - -

data=$(cat saved.txt)               
echo "$data {query}"                // Why do we need {query} after $data? I'm confused here.
rm saved.txt

 

 

Link to comment

Script filter 1 is just an easy way to output multiple lines in bash. So, it's regular XML with the format and the fields necessary for Alfred to read. The "cat" means read, and the <<< CODE [...] CODE delimits the string to read to the buffer (to Alfred).

 

--- demo 1

 

-f means file exists.

 

Alfred starts executing code in the workflow directory. Since this is just a demo, David was saving these to a text file in the workflow directory itself. If you were to implement this sort of thing, then you'd want to save the temp file to the caches directory.

 

tr translates/deletes characters ( see the man pages on tr ). The ${} structure in bash is string manipulation, so it's running the commands and outputting them into the "in" variable. "\" is an escape character, so if you want to search for a "\" you have to escape it; hence \\. So, the string takes the query and deletes and "\" from it, saving it into the variable "in".

 

Then the contents of "in" are saved into the "saved.txt" file.

 

--- demo 2

Takes the saved information in saved.txt and pulls it into a "data" variable.

 

echoing "$data {query}" combines the previous query (saved in saved.txt) and combines it with the current query.

 

---

 

The overall idea is that you can't get more than one argument out of a script filter, so this is a fun little hack in which you save previous queries in a temp file and read them into the query again to make it work as a "new" query that uses the same script filter but with a nice little delimiter so that you can see the progression, a little like breadcrumbs.

Link to comment
  • 8 months later...
  • 4 weeks later...

 

The AppleScript search command for Alfred 2 is performing as it should. It's meant to redisplay Alfred pre-populated with text or to adjust the text currently in the field. You can simulate pressing Enter by telling "System Events" to key code. Example:

tell application "TextEdit"
	activate
	tell application "System Events"
		key code 36
		keystroke "this is a test"
	end tell
end tell

That would activate the TextEdit window, press Enter to create a new line, and then type "this is a test".

 

As for opening a new tab in Chrome, it can be done with this:

tell application "Google Chrome"
	set myTab to make new tab at end of tabs of window 1
	set the URL of myTab to "http://yahoo.com"
end tell

 

 

 

Hi, David!

 

I'm trying to create something like real time progress indication for my Alfred workflow. So, I've tried:

tell application "Alfred 2" search "dpbo"
  tell application "System Events" to key code 36
end tell

Where "dpbo" - proper progress indication Script Filter (and it is linked with this osascript).

But it looks like Enter is not handled by Alfred - there is no auto refreshing happens.

If I press Enter by myself - all fine, info would properly refresh.

 

Can you plz help me? What am I doing wrong here?

Also, it would be great to add some sleep in this osascript to make refreshes each 2 seconds f.e. (to prevent Alfred blinks).

If you know how to do it in osascript - it would be very useful for me :)

 

Thanks!

Link to comment
  • 2 weeks later...

Hi, David!

 

I'm trying to create something like real time progress indication for my Alfred workflow. So, I've tried:

tell application "Alfred 2" search "dpbo"
  tell application "System Events" to key code 36
end tell

Where "dpbo" - proper progress indication Script Filter (and it is linked with this osascript).

But it looks like Enter is not handled by Alfred - there is no auto refreshing happens.

If I press Enter by myself - all fine, info would properly refresh.

 

Can you plz help me? What am I doing wrong here?

Also, it would be great to add some sleep in this osascript to make refreshes each 2 seconds f.e. (to prevent Alfred blinks).

If you know how to do it in osascript - it would be very useful for me :)

 

Thanks!

tell application "Alfred 2" to search "Safari"
delay 0.2
tell application "System Events" to key code 36

This seems to work perfectly fine for me. Could you test it and let me know how it works for you?

Link to comment
  • 2 weeks later...
tell application "Alfred 2" to search "Safari"
delay 0.2
tell application "System Events" to key code 36

This seems to work perfectly fine for me. Could you test it and let me know how it works for you?

 

 

Hi, David!

 

Yep, thats it! Thank you!  :)

I was so close  :D

 

Happy New Year and Merry Christmas! Thanks!  :)

Link to comment
  • 1 year later...
  • 2 weeks later...
  • 3 weeks later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...