AppleScript: A brief description of "create location" and a handler

As questions about how to use create location arise quite often I’ve put together a description and a handler. Use the handler as is, take what you need from it or simply ignore it.

How “create location” works

  • If a group exists at a given location create location gets it.
    It can’t be used to create a new group with the same name as an existing group at a given location. If you want that use create record with instead.

  • If a group not exists at a given location create location creates it.
    All intermediate groups are created, i.e. if a group at /Group A exists and you use create location "/Group A/Group B/Group C/Group D" then Group B, Group C and Group D are created.

  • create location takes an absolute path, i.e. always start at the root.

  • create location defaults to the current database.
    If you want a specific database append in database "My database".

  • If the provided location contains a slash / it may be necessary to escape it.
    It’s necessary if you use name of. It’s not necessary to escape location of.
    If you manually provide a group name, e.g. Test/1, escape it directly: Test\\/1.

  • create location (location of theGroup) & "Test" creates a sibling of theGroup, i.e. they are on the same level. If you want a child of theGroup use create location (location of theGroup) & (name of theGroup) & "/" & "Test".


Everything below refers to the handler. It is not create location's default behaviour.


How the handler works

This handler takes 3 parameters, from left to right:

  • the name of the group you want to create/get

  • the location (without the name)
    If the provided location is an empty string "" then the database’s incoming group is used.

  • the name of the database
    If the provided name of the database is an empty string "" then the global inbox is used.

Captures

Providing no location:

Providing a non existing location:

Providing an existing location:

Providing a group reference instead of a location:

The option shown in the last capture wasn’t mentioned before as it might be confusing. It can be used if you already have a group reference and don’t want to check whether a subgroup with a given name exists or not.

-- Create location

tell application id "DNtp"
	try
		set theGroup to my createLocation("Test", "", "") -- name (string), location (string) or group (record), database name (string)
		
	on error error_message number error_number
		if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
		return
	end try
end tell

on createLocation(theName, theLocationOrGroup, theDatabaseName) -- string, string or record, string
	tell application id "DNtp"
		try
			if theName = "" then error "Please provide a name."
			
			if theDatabaseName = "inbox" or theDatabaseName = "" then
				set theDatabase to inbox
			else
				set theDatabase to database theDatabaseName
			end if
			
			set theClass to class of theLocationOrGroup
			if theClass = text then
				if theLocationOrGroup ≠ "" then
					set theLocation to theLocationOrGroup
				else
					if theDatabase = inbox then
						set theLocation to ""
					else
						set theIncomingGroup_Name to (name of (incoming group of theDatabase))
						if theIncomingGroup_Name contains "/" then
							set theIncomingGroup_Name to my escapeSlash(theIncomingGroup_Name)
						end if
						set theLocation to theIncomingGroup_Name
					end if
				end if
			else if theClass = parent then
				set theLocationOrGroup_Name to name of theLocationOrGroup
				if theLocationOrGroup_Name contains "/" then
					set theLocationOrGroup_Name to my escapeSlash(theLocationOrGroup_Name)
				end if
				set theLocation to (location of theLocationOrGroup) & theLocationOrGroup_Name
				set theDatabase to database of theLocationOrGroup
			end if
			
			if theName contains "/" then
				set theName to my escapeSlash(theName)
			end if
			
			set theGroup to (create location theLocation & "/" & theName in theDatabase)
			
		on error error_message number error_number
			activate
			display alert "Error: Handler \"createLocation\"" message error_message as warning
			error number -128
		end try
	end tell
end createLocation

on escapeSlash(theText)
	set d to AppleScript's text item delimiters
	set AppleScript's text item delimiters to "/"
	set theTextItems to every text item of theText
	set AppleScript's text item delimiters to "\\/"
	set theText_escaped to theTextItems as string
	set AppleScript's text item delimiters to d
	return theText_escaped
end escapeSlash

4 Likes