Script: Create or update attribute with Tinderbox's current folder URL for relative linking

This script creates or updates a User Attribute with Tinderbox’s current folder URL.

It makes it easier to update relative links to resources after a Tinderbox or its folder has been renamed or moved.

I store all Tinderbox documents in their own local git repo and use relative links to a resources folder inside the repo. However, I also tend to rename repos quite often and always move them after I’m done. This of course breaks the links. The script makes it super easy to update them.

How it works

  • If it doesn’t exist a User Attribute is created and its default value is set to Tinderbox’s current folder URL.

  • If it exists then its default value is set to Tinderbox’s current folder URL, i.e. it’s updated.

Setup

  • Set property theAttributeName to a name of your liking

Usage

  • Open a Tinderbox
  • Run script

Result

The script results in a User Attribute whose default value is e.g.

file:///Users/user/Documents/Tinderbox/Bilder%20relativ%20zur%20Tinderbox%20verlinken/

It can then be used in a notes $Text, e.g. as an relative img link:

<img src="^value($URLSelfDirectory)^^value(urlEncode($MediaDirectory))^^value(urlEncode($MediaName))^">

References

Please see @satikusala’s videos on “Working with media”

@satikusala your videos and Tinderbox documents are very helpul, thanks a lot!


-- Create or update attribute with Tinderbox's current folder URL for relative linking

-- Makes usage of relative links and moving around a Tinderbox easier
-- Result: a User Attribute's default value set to the Tinderbox's current folder URL, e.g. "file:///Users/user/Documents/Tinderbox/Bilder%20relativ%20zur%20Tinderbox%20verlinken/"

use AppleScript version "2.4"
use framework "Foundation"
use scripting additions

property theAttributeName : "URLSelfDirectory"

tell application id "com.eastgate.Tinderbox-8"
	try
		set theDocument to front document
		set theDocumentPath to POSIX path of (file of theDocument as string)
		set theDirectoryURL to my directoryURL(theDocumentPath)
		
		if not (exists attribute theAttributeName in theDocument) then
			set theAttribute to make attribute in theDocument
			set type of theAttribute to "URL"
			set defaultValue of theAttribute to theDirectoryURL
			set name of theAttribute to theAttributeName
			display notification theDirectoryURL with title "Created Attribute \"" & theAttributeName & "\""
		else
			set defaultValue of attribute theAttributeName in theDocument to theDirectoryURL
			display notification theDirectoryURL with title "Updated Attribute \"" & theAttributeName & "\""
		end if
		
	on error error_message number error_number
		if the error_number is not -128 then display alert "Tinderbox" message error_message as warning
		return
	end try
end tell

on directoryURL(thePath)
	try
		set thePath to (current application's NSString's stringWithString:thePath)
		set theDirectory to thePath's stringByDeletingLastPathComponent()
		set theDirectory_URL to current application's |NSURL|'s fileURLWithPath:theDirectory
		return (theDirectory_URL's absoluteString()) as string
	on error error_message number error_number
		activate
		if the error_number is not -128 then display alert "Error: Handler \"directoryURL\"" message error_message as warning
		error number -128
	end try
end directoryURL

3 Likes

Thanks for sharing, @Pete. It might come in handy sometime.

I do the same. And I also have Arq backing up the folders every hour. I feel much safer this way.

1 Like

@Pete Great to have examples of external scripting here to study!

Here’s a more concise version that doesn’t need Foundation or scripting additions. Just plain vanilla AppleScript.

property theAttributeName : "URLSelfDirectory"

tell front document of application "Tinderbox 8"
	try
		set fileAlias to its file as alias -- "it" is front document
		tell application "Finder"
			set theFileURL to URL of fileAlias as string
			set my text item delimiters to "/"
			set theDirectoryURL to (text items 1 thru -2 of theFileURL as string) & "/"
		end tell
		
		if (exists attribute theAttributeName) then
			set defaultValue of attribute theAttributeName to theDirectoryURL
		else
			make new attribute with properties {name:theAttributeName, type:"URL", defaultValue:theDirectoryURL}
		end if
		
		display notification theDirectoryURL with title "Updated Attribute \"" & theAttributeName & "\""

	on error error_message number error_number
		if the error_number is not -128 then display alert "Tinderbox" message error_message as warning
	end try
end tell


Thanks, I wasn’t aware that make new attribute meanwhile accepts with properties.

I stopped using Finder in scripting as it’s slow, System Events is faster. However, for everything that involves paths I now use AppleScriptObjC as it’s the cleanest way, e.g. in case of trailing slashes.

I also stopped using Finder in general as I’m still on Mojave and Apple never fixed an issue with process iconservicesagent. This issue made my old mac sometimes completely unusable, so I switched to Path Finder (which has it’s own disadvantages).

Btw, do you have references about negative AppleScript changes starting with Catalina? I need to get a new mac and am evaluating whether I should use Mojave on that (if that’s possible at all).

If there were any notable problems running AppleScript on Catalina and later (I’m now on Big Sur 11.3) they skipped me. Security has gotten tighter, though, so I remember at one point making a trip to System Preferences > Security and Privacy > Privacy > Accessibility to make sure Script Editor and other apps were enabled there.

I understand iconservicesagent works fine in Catalina and after.

In a case like this, where speed is not a factor, scripting the Finder results in simpler and more understandable code, fewer than half as many lines as the “cleaner” alternative. :grinning:

Yes, make new <object> with properties did not work when Tinderbox first introduced AppleScript support, but now works as expected.

1 Like