Jump to content
Acidham

Script Filter JSON Format

Recommended Posts

In the past I used XML format for generating output of Script Filter in Applescript. It seems that XML will be depreciated soon and the format for going forward will be JSON output. With Applescript the JSON format is quite cumbersome because when I am using repeat loop to generate icons the comma in between the items cannot be set properly. e.g.

 

{"items":

[

{<menu item 1>},

{<menu item 2>}

]

}

 

After menu item 1 i need a comma. with xml it was not a problem because i was able to loop and create new items without a comma.

 

Are there any best practices to use the Script JSON format with applescript and especially within repeat loops?

Share this post


Link to post

Really, you should be using a proper JSON library. But "manually" generating it is fine for simple cases.

 

What you want to do here is create a list of your lines of JSON, and when you're done, join them:

on joinWithCommas(theList)
	set oldDelims to AppleScript's text item delimiters
	set AppleScript's text item delimiters to ","
	set theString to theList as string
	set AppleScript's text item delimiters to oldDelims
	return theString
end joinWithCommas

set theItems to {"first string", "second string"}
set theJSON to my joinWithCommas(theItems)

 

Edited by deanishe

Share this post


Link to post

Everything is a pain in AppleScript.

 

But actually talking to apps is more difficult in JavaScript, imo. The API is awful and mostly undocumented.

Share this post


Link to post

Thats why I am using Applescript with Alfred. What about when Alfred would provide an Applescript function to create JSON Output?

 

Applescript is most efficient when you need to talk to other Apps. I was fine with XML but bad that it will disappear. 

Share this post


Link to post

@Andrew will correct me if I'm wrong, but I'm certain the XML support isn't going away (at least not in Alfred 3). There are too many very useful, but no longer updated, workflows that use it.

 

What the deprecation means is that going forward, the XML format is frozen, and new feedback features will only be available if you use JSON (starting with the new variables objects in item and mod, and the ability to specify a different icon via a mod).

 

Still, it wouldn't be a bad idea to use a JSON library with any new workflows you start.

 

Personally, my approach has always been to write the absolute minimum AppleScript and write the rest of the workflow in a sensible language, calling the AppleScript as needed.

Edited by deanishe

Share this post


Link to post

Yep, @deanishe is correct, Script Filter XML output will still be interpreted by Alfred for the foreseeable future, it just won't be getting feature updates like the JSON output.

 

Cheers,

Andrew

Share this post


Link to post

For usability reason I suggest better solution for Script Filter Output. Maybe it is all great from a developer perspective but for non developers and script kiddis like me it becomes really hard to deal with Script Filters. For me Alfred is an efficient tool to write quick and short scripts which helps me on my daily business. Lets hope to get better support for producing output from script filters in the future. 

Share this post


Link to post
14 minutes ago, Acidham said:

better solution for Script Filter Output

 

JSON is that better solution.

 

There is literally no easier-to-use data format for programs to communicate with each other. That's why JSON is so damn popular (even where it's not really appropriate).

 

Especially in beginner-friendly scripting languages like Python and Ruby, turning a native dictionary to JSON isn't even a single line of code. In JavaScript, well, JSON is JavaScript. XML, by contrast, practically requires the use of a library to generate workflow feedback because XML is so awful to work with.

 

That is to say, the problem isn't JSON or Alfred or Script Filters, it's that you aren't doing it properly.

 

30 minutes ago, Acidham said:

but for non developers and script kiddis like me it becomes really hard to deal with Script Filters

 

The reason for the difficulty is that you aren't writing a Script Filter, you're trying to write a JSON-generation library.

 

Don't do that. Like I said, use a proper library for generating JSON instead of trying to mash strings together. Problem solved.

 

Share this post


Link to post

Thx for the link and I tried it but I am not able to get a basic JSON with 

 

{"items":

[

{"title":"foo",{"uid":1}

{"title":"bar",{"uid":2} 

]}

 

together with the applescript

Share this post


Link to post

That isn't valid Alfred JSON. It should be:

{"items":
  [
    {"title":"foo", "uid":1},
    {"title":"bar", "uid":2}
  ]
}

(uid is a sibling of title.)

 

The corresponding AppleScript is:

-- import JSON library
tell application "Finder"
	set json_path to file "json.scpt" of folder of (path to me)
end tell
set json to load script (json_path as alias)

-- Create and add items
set theItems to {}
set end of theItems to json's createDictWith({{"title", "foo"}, {"uid", 1}})
set end of theItems to json's createDictWith({{"title", "bar"}, {"uid", 2}})


-- Create root items object and encode to JSON
set itemDict to json's createDict()
itemDict's setkv("items", theItems)
return json's encode(itemDict)

 

Share this post


Link to post

I am not able to get the "icon": {"type":"fileicon", {"path":"icon.png"}} piece into the dict. I tried

 

set theItems to {}
set end of theItems to json's createDictWith({{"title", "foo"}, {"uid", 1}})
set end of theItems to json's createDictWith({{"title", "bar"}, {"uid", 2}})
set theFileIcon to json's createDictWith({{"type", "fileicon"}, {"path", "icon.png"}})
set end of theItems to json's createDictWith("icon", theFileIcon)$

 

Share this post


Link to post

Again, that's not Alfred JSON. It should be "icon": {"type": "fileicon", "path": "icon.png"}. That said, you are creating the correct JSON in your AppleScript.

 

The problem is you're adding it to the list of items, not to an actual item:

-- Create list to add items to
set theItems to {}

-- Create an item
set theItem to json's createDictWith({{"title", "foo"}})
-- Set a UID
theItem's setkv("uid", "this-is-a-uid")
-- Add icon
set theIcon to json's createDictWith({{"type", "fileicon"}, {"path", "icon.png"}})
theItem's setkv("icon", theIcon)

-- Finally, add the finished item to the list
set end of theItems to theItem

 

 

Share this post


Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...