URL
A URL (Uniform Resource Locator) is a string of text-characters used to identify a file or resource, either locally on the computing device, or on a network or the internet.
An essential component of HTML links, a URL is composed of text segments separated by forward-slash characters, like this URL that references an image file on an internet server:
https://omni-automation.com/wind/18207.JPG
In Omni Automation, URLs are used to reference local or networked files, often for importing into documents.
String to URL
fromString(string: String, relativeToURL: URL or null) → (URL or null) • Parses the string as a URL if possible and returns a new instance, or null otherwise. If baseURL is not null, the result is a relative URL.
fromPath(string: String, isDirectory: Boolean, relativeToURL: URL or null) → (URL or null) • Returns a new file URL with the given path and assumption of whether it is a directory.
You can create an instance of a URL object by calling the fromString() method on the URL class. This function takes the URL string as its direct parameter. In the example below, a URL string is converted into a URL object stored in the variable: aURL
URL Object from String
urlA = URL.fromString("https://omni-automation.com/wind/18207.JPG")
//--> [object URL: https://omni-automation.com/wind/18207.JPG] {string: "https://omni-automation.com/wind/18207.JPG", toObject: [object URL: https://omni-automation.com/wind/18207.JPG]}
Incorporating the relativeToURL property:
Derive URL from Base URL
baseURL = URL.fromString("https://www.omnigroup.com")
linkURL = URL.fromString("/blog", baseURL)
linkURL.string
//--> https://www.omnigroup.com/blog
Here’s a script that use the documentsDirectory property to generate a URL to the user’s Pictures folder (macOS):
Derive URL from Path
homeName = URL.documentsDirectory.pathComponents[2]
URL.fromPath(`/Users/${homeName}/Pictures/`, true)
Class Properties
currentAppScheme (String r/o) • Returns the current URL scheme for the current Omni application.
documentsDirectory (URL r/o) • Returns the application’s Documents directory. This is in the application’s sandbox, and on the Mac is not the user’s Documents directory. This is accessible by the application without using access(). (EXAMPLE)
Instance Properties
absoluteString (String r/o) • Returns the absolute string for the URL.
absoluteURL (URL r/o) • Returns the absolute URL.
baseURL (URL or null r/o) • Returns the base URL if this URL is relative, or null if it is absolute.
fragment (String or null r/o) • Returns the fragment component of the URL, or null.
hasDirectoryPath (Boolean r/o) • Returns true if the URL’s path represents a directory.
host (String or null r/o) • Returns the host component of the URL or null.
isFileURL (Boolean r/o) • Returns true if the scheme is file:.
lastPathComponent (String r/o) • Returns the last component of the URL’s path or an empty string.
password (String or null r/o) • Returns the password component of the URL or null.
path (String or null r/o) • Returns the path component of the URL or null.
pathComponents (Array of String r/o) • Returns the path of the URL as an array of components.
pathExtension (String r/o) • Returns the path extension of the last path component of the URL or the empty string.
port (Number or null r/o) • Returns the port component of the URL or null.
query (String or null r/o) • Returns the query component of the URL or null.
relativePath (String or null r/o) • Returns the relative path of the URL, or the absolute path if this URL is not relative.
relativeString (String r/o) • Returns the relative portion of the URL if it is relative, otherwise this returns the absolute string.
scheme (String or null r/o) • Returns the scheme of the URL.
string (String r/o) • String absoluteString representation of this URL.
user (String or null r/o) • Returns the user component of the URL or null.
The string instance property of the URL class can be used to extract a URL string from the URL object:
URL String from URL Object
aURL.string
//--> "https://omni-automation.com/gfx/18207.jpg"
See documentation on the URL.QueryItem class for more information regarding URL components.
URL Instance Functions
fetch(success: Function, failure: Function or null) → ( ) • Get the contents at the destination of this URL. (DOCUMENTATION)
call(success: Function, failure: Function or null) → ( ) • Invoke an x-callback-url API end-point, with the callback functions being invoked when a reply is received. When a reply is received, the parameters of that URL are decoded as JSON, or left as String values if not valid JSON, and stored as properties of a result object. For a successful reply, if the result object has one property, its value is passed as the first argument to the success function. If there are zero or more than one parameters, the full object is passed as the first argument. In both cases, the success function is passed a second argument that is the full object of parameters. The failure callback is always passed the object will all the result parameters, typically errorCode and errorMessage. (DOCUMENTATION)
open( ) → ( ) • Ask the system to open this URL. (DOCUMENTATION)
find(types: Array of TypeIdentifier, recurse: Boolean or null) → (RESULTOBJ) • Scan a directory URL for files of the given types. If recurse is specified and is false, only the immediate contents of the directory will be considered. If recurse is not specified or is true, the full directory tree will be scanned. (DOCUMENTATION)
toString( ) → (String) • Return a string representation of the URL instance. NOTE: you can also use the string property of the URL class.
appendingPathComponent(component: String) → (URL) • The new URL object with the provided string appended to the end.
deletingLastPathComponent( ) → (URL) • The new URL with the previous last component removed.
deletingPathExtension( ) → (URL) • (v4.0) Returns a new URL with the path extension (if any) of the last path component removed.
Here's an example of using URL editing functions to generate a second URL instance that uses the same directory as the first URL instance:
URL Edit Functions
urlA = URL.fromString("https://omni-automation.com/wind/18207.JPG")
//--> [object URL: https://omni-automation.com/wind/18207.JPG] {string: "https://omni-automation.com/wind/18207.JPG", toObject: [object URL: https://omni-automation.com/wind/18207.JPG]}
containingDirectoryURL = urlA.deletingLastPathComponent()
urlB = containingDirectoryURL.appendingPathComponent("16704.JPG")
//--> [object URL: https://omni-automation.com/wind/16704.JPG] {string: "https://omni-automation.com/wind/16704.JPG", toObject: [object URL: https://omni-automation.com/wind/16704.JPG]}
The open( ) Instance Function
The open( ) function of the URL class is used to open the specified URL object.
open( ) → ( ) • Ask the system to open this URL. Note: unlike the call(…) function, the open( ) function does not expect nor process a result from the execution of the URL.
Using the open( ) function to display a webpage:
Open Webpage
aURL = URL.fromString('https://omni-automation.com')
aURL.open()
Here’s the open( ) function used to pass text to a new BBEdit document. Note that the open( ) function may be appended to URL creation statement since the result of the statement is an instance of the URL class:
New BBEdit Text Document
textToPass = encodeURIComponent("How Now Brown Cow")
URL.fromString('x-bbedit://new-document/?text=' + textToPass).open()
And here’s the open() function used to pass text to a new Textastic document:
New Textastic Document
textToPass = encodeURIComponent("How Now Brown Cow")
URL.fromString('textastic://x-callback-url/new?text=' + textToPass).open()
And here’s an example of using the call() function to pass text to a new Drafts document:
New Drafts Document
urlStr = "drafts5://x-callback-url/create?text="
textToPass = encodeURIComponent("How now brown cow.")
URL.fromString(urlStr + textToPass).open()
NOTE: Because of the security protocols in iOS, iPadOS, and macOS, the open( ) function may be blocked from use with files not directly under control of the hosting application.
A URL for triggering a new entry dialog in the Contacts app (macOS):
New Address Book Entry
URL.fromString("addressbook://Omni%20Automation?edit").open()
URL to String
When working with URLs in your scripts, you may wish to extract the name of the file or resource from the URL object. This is accomplished by extracting the URL string from the URL object by accessing the value of its “string” property.
Once you retrieved the URL string from the URL object, you can use standard JavaScript tools for deriving the name, as shown in this example:
Get Resource Name from URL (Old Way)
aURL = URL.fromString('https://omni-automation.com/gfx/18207.jpg')
urlString = aURL.string
resourceName = urlString.substr(urlString.lastIndexOf('/') + 1)
//--> "18207.jpg"
A better mechanism for deriving the name of a resource from its url is to use the lastPathComponent property of the URL class:
Get Resource Name from URL (Best Way)
aURL = URL.fromString('https://omni-automation.com/gfx/18207.jpg')
resourceName = aURL.lastPathComponent
//--> "18207.jpg"
The currentAppScheme Property
Omni Automation script links begin with a schema that identifies the target Omni application. For example, here is a link that targets a task in OmniFocus:
omnifocus:///task/ieEZbhmwQLk
However, should you have multiple copies of an Omni application installed, such as both the standard and enterprise editions, you can use the currentAppScheme property of the URL class to derive the exact schema targeting the current running Omni application, as in this example script that generates a link to the selected OmniFocus task:
Generating a URL Link to a Task
var selectedTask = document.windows[0].selection.tasks[0]
var taskID = selectedTask.id.primaryKey
var appSchema = URL.currentAppScheme
var taskLinkStr = appSchema + "://localhost/task/" + taskID
//-> "com.omnigroup.OmniFocus3://localhost/task/ieEZbhmwQLk"
The value of the currentAppScheme property is the identifier string for current Omni application.
URL of a Plug-In Resource
Resource files place within Omni plugins are referenced using URLs. To derive the URL of a plugin resource file, use the following technique of identifying the host plugin by its identifier string, and then calling the resourceNamed() method on the plugin object:
URL of a Plug-In Resource
var plugin = PlugIn.find("com.omni-automation.og.example-plug-in")
var resourceName = "Australia.png"
var aURL = plugin.resourceNamed(resourceName)
Accessing the value of the returned URL object’s “string” property will be a file URL string pointing to the indicating file on disk:
file:///Users/sal/Library/Containers/com.omnigroup.OmniGraffle7/Data/Library/Application%20Support/PlugIns/SalsSnippets.omnigrafflejs/Resources/Australia.png
Storing and Retrieving Data (@)
Using the documentsDirectory property, data can be written to and retrieved from the Omni app’s documents folder without the need for user interaction. This provides an excellent mechanism for sharing data between plug-ins.
Here are functions for reading and writing data in JSON format:
Storing JSON Data in App Directory
function storeDataInAppFolder(dataObj, fileName, shouldOpenFolder){
try {
dataObjStr = JSON.stringify(dataObj)
data = Data.fromString(dataObjStr)
folderURL = URL.documentsDirectory
fileURL = folderURL.appendingPathComponent(fileName)
wrapper = FileWrapper.withContents(fileName, data)
wrapper.write(fileURL, [FileWrapper.WritingOptions.Atomic], null)
if(shouldOpenFolder && app.platformName === "macOS"){
folderURL.open()
}
}
catch(err){
new Alert(err.name, err.message).show()
}
}
Calling the Function
dataObj = {"name":"Samantha",
"id":"com.apple.speech.synthesis.voice.samantha.premium", "rate":0.45} storeDataInAppFolder(dataObj, "voice-data.json", true)
IMPORTANT: The fetch() function, which is used to read the stored data, runs asynchronously in relation to the rest of its host script and so any script code for processing the results of the fetch must be placed within a call-back function that is the direct parameter of the call. (see example below)
Retrieving JSON from App Directory
fileName = "voice-data.json"
folderURL = URL.documentsDirectory
fileURL = folderURL.appendingPathComponent(fileName)
fileURL.fetch(data => {
result = data.toString()
console.log(result)
json = JSON.parse(result)
// PROCESSING STATEMENTS GO HERE
}, err => {
new Alert(err.name, err.message).show()
})