Aliases, Replicants, and Indexing - Recommendations & Scripts?

Before I started using DEVONthink, I used to create a fair amount of aliases for documents and folders in Finder. Like most researchers, my projects often rely on some of the same source materials. So instead of duplicating them, I used to just create aliases for them in the new project folder. These aliases were always annoyingly fragile, but even seeing a dead alias in the project folder was a good reminder of its relevance, etc. And, it’s easy to use Alfred or Spotlight to quickly locate the file anyways. In fact, I used aliases almost like a citation record of sorts for my projects.

One of the many things that’s brilliant about DEVONthink is the way it gets around these alias-related Finder problems through its use of replicants. It was one of the big reasons I decided to take the plunge and adopt DEVONthink. In any case, I have a couple of questions that I was hoping to bounce off the forum that are related to replicants, aliases, and indexing.


First, as a DEVONthink newbie that indexes Finder folders containing said aliases, I understand that these will not import/sync into my databases (i.e., they even show up on the Log as “skipped”). Has anyone created a script that will replace an alias located in an indexed Finder folder with a replicant of the file in DEVONthink? In other words, if the alias is pointing to a file or folder that is also indexed by DEVONthink, is there any way that DEVONthink could just place a replicant in its analogous location in the database? And, in cases where it can’t find the appropriate file, leave some other kind of indicator?

To be honest, this seemed like a bit of a pipe dream, but I thought it was worthing asking before I start doing it all manually. That’s a lot of elbow grease! I also got my hopes up when I saw the note in the “Changes since Beta 7” section of the manual indicating: “Improved handling of indexed items by resolving alias data if possible, especially if the same items are indexed in multiple databases and renamed in one database.” But perhaps this is something else?


Second, if I create replicants for all of the documents and folders/groups where I used to have aliases in Finder, is there a way for me to see the replicants in Finder? For example, this might sound odd, but is it possible to create a Finder alias for a replicant in DEVONthink (i.e., based on its item url - x-devonthink-item://…)? If so, does anyone have a script they can share (e.g., select something in DEVONthink that’s located in an indexed folder/group, and the script drops an alias for it in the analogous Finder location)? These aliases wouldn’t sync in DEVONthink, so I wouldn’t have to worry about seeing everything duplicated in DEVONthink, and now I could see a similar citation-like record in Finder (albeit ones that would open in DEVONthink, as opposed to an alias that points directly to the true file or folder in Finder and opens in its default viewer). This seems like a nice middle ground solution.

Thanks for any help you can lend. Also, if others have suggestions for newbies dealing with aliases and indexing, I’d love to hear how you approach these issues. Thanks again!

1 Like

is there a way for me to see the replicants in Finder?

No. Replicants don’t exist in places outside the initial import or index. (This is easily testable.)

OK - so that lampoons the second question.:cry: For some reason, I think I was mixing up the creation of a bookmark (which you could connect using the URL scheme) and an alias, which as you rightly point out would have to be tied to a concrete place/location in Finder. Thanks

I guess I could always create an alias using the file path of the original document, however?

I guess I could always create an alias using the file path of the original document, however?

When referring to indexed files, yes this is possible.

Great! Thanks, @BLUEFROG!

I’ve been working on the script a bit this morning (for dealing with the second question), and I can’t seem to figure out one key element, and I was wondering if you could give me a hint or help point me in the right direction.

Namely, once you’ve selected a replicant in DEVONthink, how do you obtain the file path of the corresponding parent folder/group where you’d like to make the new Finder alias? I’m sure I’m not using the correct terminology here, so I apologize. In layman’s terms, I’ve tried to lay out how the script would work below, and what I’m trying to ask about is step 2(B), in particular:

  1. Select a replicant in DEVONthink that is “sitting in” a group/folder that’s indexed by DEVONthink (though obviously, the user can’t see the replicant in Finder at that folder’s location)
  2. From that selection, (A) obtain the file path of the original/actual/indexed file (easy enough with the usual “path of theRecord” etc.), and (B) obtain the path of the parent folder/group where the replicant is displayed to the user (which is also indexed)
  3. Make Finder alias using path from 2(A) and drop it in path from 2(B)

When trying to get the corresponding path of the parent group from 2(B), I can only seem to get the actual/original file’s parent folder (e.g., 2(A)) and not the parent group where the replicant is being displayed to the user in the DEVONthink window. I’m really sorry for this description, I know I’m butchering some of these DEVONthink terms of art. Conceptually, I think I understand from the manual and other forum posts why DEVONthink returns this path, but I don’t understand how to modify the script accordingly. In the applescript dictionary for “records,” I couldn’t tell how to reference it either

In any case, since my description above is probably a little difficult to follow, I thought it might be easier to sketch out some of the script’s barebones below, so that it might be a little easier to see where I’m getting stuck (Step 2B):

tell application id "DNtp"
	activate
	set theSelection to the selection
	repeat with theRecord in theSelection
		set theFilePath to path of theRecord
		???? STEP 2B ????? - set ReplicantParentGroupPath ... ???
		Tell application "Finder"
			make new alias at (ReplicantParentGroupPath) to (theFilePath)
		end tell			
	end repeat
end tell

As always, thanks for any help you can lend. And thanks for your patience.

If you have replicated a file to a non-indexed group, there is no path for a regular group in a DEVONthink database as it does not exist in the filesystem.
No path means nothing to alias to. :slight_smile:

tell application id "DNtp"
	repeat with thisRecord in (selection as list)
		path of (parent of thisRecord)
                --> Returns a list of paths for any indexed parent groups, but not for regular groups.
                --> {"/Users/Me/Desktop/dt3/02", "", "/Users/Me/Desktop/dt3/iCloud Testing"}
	end repeat
end tell

Notice in the return there is a empty quoted value.
This is an indexed file, replicated into another indexed group and also into a regular, non-indexed group.

1 Like

Thanks a ton @BLUEFROG! Your explanation and script were really helpful for understanding how these work.

After doing some testing, I still can’t wrap my head around how to get the correct parent in the list of paths for the replicant that’s actually selected in DEVONthink (i.e., where said parent group of selected is indexed)? From what I can tell, the first item is always the parent group of the “original” file. But the other items don’t seem to be listed in any specific order. Perhaps, maybe, the order they were created, but it’s hard to tell. In any case, is it even possible to identify the parent group of the selected replicant? Or is this sucker just lost in the matrix? Ha

Thanks again!

Not 100% sure what u need but this may help.
The script will get all groups that are indexed to MacOS finder that contain the replicants of a selected item and show the results in main window.

The usual way of figuring out how to script in DT is to search for related terms in the DT dictionary in the script editor. In this case, I search for index and know that there is a property “indexed” for record, so start using that to try on something. At least that’s how I learn to script DT.

Disclaimer: Don’t trust my script 100%.

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

	tell application id "DNtp"
		Try
		if exists (content record) then
			set theDoc to content record
		else if (count of the selection) is 1 then
			set theDoc to item 1 of ((the selection) as list)
		else
			error ("No document is selected. Please select a document, then try again.")
		end if
		
		set theParents to (parents of theDoc whose tag type is not ordinary tag)
		
		set theIndexedParents to {}
		repeat with each in theParents
			if each is indexed then set end of theIndexedParents to each's item 1
		end repeat
		
		set search results of viewer window 1 to theIndexedParents
end try	
end tell
	
2 Likes

Replicants have multiple parents, so parent reports all the parents of a given file.

The location of a replicant seems to always and only report the location of the originally indexed / imported file.
While it seems reasonable the location of a selected replicant or content record should report the current location, @cgrunenberg would have to assess this.

1 Like

@ngan Thanks for sharing this script! Even though it doesn’t solve the problem, it was actually really helpful for understanding some other issues I was confused about (when trying to create some other scripts). This is great. Much appreciated!

@BLUEFROG As always, thanks for the helpful explanations, and for trying to tinker around with the issue. This was really helpful. And, I’m glad for once that I’m making “reasonable” requests! Ha :smiley: I’ll keep my fingers crossed that @cgrunenberg agrees! :crossed_fingers:

The only other thing that I could think of is to redo the script, so that it requires the user to select multiple items in a group, where at least one of them is not a replicant, and then the script could use that non-replicant file to identify the appropriate file path of the parent group for all of the selected replicants - but this seems problematic for several reasons.

In any case, thanks again for all of your help!

Yeah, there’s not a really good approach on this one.

As all replicants reference the same record, the returned location (which does not depend on the current frontmost window or selection) is always the same.

But…

  • since the selection is not always the first instance of the record
  • and the content record is not always the first instance of the record

…shouldn’t (couldn’t) it report the location in those cases?

The selection just contains records which are always the same, therefore that’s not possible.

I just did an experiment and found out that an index group won’t show the Finder’s aliases within. I guess u already knew this.
Just a possible indirect approach assuming you know of some 3rd party app such as Hazel rule that can do this (I’ve never used Hazel but everyone is saying that it can do many things!). In Mac OS finder, use this 3rd party app to search the aliases and create a dummy file wherever it finds the aliases in the Finder’s folder. This dummy file is a “file” and therefore it will be shown in DT’s index group. Therefore, you can search for it in DT and you will know which index groups are suppose to have the replicants, the rest is straight forward manual or script job (just search and replace). For this method, u will still see the aliases in Mac OS, you will see the replicants in the correct groups.

OR, use Hazel rule to duplicate the same file in each Mac OS Finder wherever it find the aliases. There will be multiple duplicates of the files in DT3. Then use the std Data>“Convert all duplicates into replicants” function in DT to turn all files into replicants? For this method, If you are planning to use DT as the hub of management, where the original file is located won’t matter.