XMenu - Alias Files from DTPO 2

I have been using XMenu with indexed files only. Is there a way to add a file to XMenu from DTPO without making it indexed?

I typically create an alias and then move a copy of it to the XMenu folder. How do I do this in DTPO 2?

You could reveal the file in the Finder (see menu Data > Reveal) and then create an alias.

1 Like

I have been using XMenu with indexed files only. Is there a way to add a file to XMenu from DTPO without making it indexed?

Can you clarify what you’re actually doing here? The terminology regarding Xmenu and indexed files (a DEVONThink concept) is unclear.

By Indexed files, I mean files that are not imported in DTPO but are in Dropbox or Google Drive and sometimes in the OmniPresence folder for OmniOutliner files. I make an alias of those files and then copy them in the XMenu folder.

I need one more clarification: should I copy the newly created alias file into the XMenu folder or should I drag the alias file into the XMenu folder?

So far I have used the first option, but I would rather not see the alias files in the original folder.

Thank you! It worked.

If you want to add aliases for DEVONthink records to XMenu on a regular basis consider this script. Set your username in the path and save the script with Script Editor.app to DEVONthink’s script menu.

-- Create alias for DEVONthink record in XMenu's custom folder

property theXMenuCustomFolderPath : "/Users/USERNAME/Library/Application Support/XMenu/Custom/"

tell application id "DNtp"
	try
		set windowClass to class of window 1
		if {viewer window, search window} contains windowClass then
			set currentRecord_s to selection of window 1
		else if windowClass = document window then
			set currentRecord_s to content record of window 1 as list
		end if
		
		set thePaths to {}
		repeat with thisRecord in currentRecord_s
			if (indexed of thisRecord) is true then
				set end of thePaths to (path of thisRecord)
			end if
		end repeat
		
	on error error_message number error_number
		if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
	end try
end tell

tell application "Finder"
	try
		repeat with thisItem in thePaths
			set theFile to file (POSIX file (thisItem as string) as alias)
			make new alias to theFile at (POSIX file theXMenuCustomFolderPath as alias)
		end repeat
		
	on error error_message number error_number
		if the error_number is not -128 then display alert "Finder" message error_message as warning
	end try
end tell

display notification "Created " & (count of thePaths) & " aliases in XMenu" with title "DEVONthink"

Thank you! This is way over my head since I use some scripts but very rarely add new ones. I will give this one a shot. Would it transfer to DT 3? I am considering switching at some point.

Yes, I use DEVONthink 3 Beta 3. (Not sure if you intentionally want to use aliases but if not then maybe this (or the idea behind it) might be of interest to you)

1 Like

This is not a wise approach unless you error-trapped to detect only indexed items. You should not link to internal paths of imported files.

Hi Jim, sorry I don’t get what you mean here. (I’ve learned (from reading this forum and especially your answers :slightly_smiling_face:) before that using aliases to DEVONthink records is nearly never recommend, but I also don’t remember that I ever “recommended” (in my small knowledge of DEVONthink or AppleScript) this to anybody). I’ve re-read my previous posts but can’t find anything that would fit your warning (probably because english is not my first language or because I’m “too dangerous” with my little AppleScript knowdlege (which I’m afraid it’s part of your concerns) or something else. Please let me know, I want to learn and really don’t want to write “stupid” or even dangerous stuff if I again think I know something that could help :slightly_smiling_face:

No worries! The issue is here…

set thePaths to {}
repeat with thisRecord in currentRecord_s
set end of thePaths to (path of thisRecord)
end repeat

This is getting the files paths of the content reocrd or the selection. If a file is imported, you’re going to process the path inside the database’s internals. That’s not advocated as that path could change.

I’m not intending to rewrite your entire script but I suggest you error-trap like so…
if (indexed of thisRecord) is true then…

Yes but (in that specific case) that’s what the OP asked for and would do (manually) anyway. As I tried to find a script solution (to the already solved) task I was aware of the limitation of using path. I thought of it for a moment but didn’t find a way to use uuid as the initial question was about setting an alias. I think we’re talking about different things as you wanted to clarify in your first post. If I got it right the OP used to copy aliases to DEVONthink records or other files (Dropbox, Google Drive) to XMenu’s custom folder. I tried myself on a script solution for creating imported DEVONthink records (that’s my “normal” understanding of records) to XMenu but never intended to cover anything else. Not sure where to add the indexed part, but I think now you want me to add it as “if indexed is false”.

From the original poster:

By Indexed files, I mean files that are not imported in DTPO but are in Dropbox or Google Drive and sometimes in the OmniPresence folder for OmniOutliner files. I make an alias of those files and then copy them in the XMenu folder.


but I think now you want me to add it as “if indexed is false”

I said…
if (indexed of thisRecord) is true then
If you wanted to approach it from the other direction, you could use…
if (indexed of thisRecord) is false then

Sorry, I really don’t get it. If the OP wants to add an alias to XMenu the first version of my script would have done this. I (hope I) do understand the limitations of path in general, but I don’t understand where the difference should be whether an alias (to a DEVONthink record) were created manually or by script.

I don’t get it. Were’s the difference of revealing a file and then making an alias manually to do the same with a script?

This has nothing to do with whether the alias is made manually or via script. The original poster is referring to indexed files NOT imported files. They are not the same thing.

The path of imported files should not be used for any longstanding process, like creating an alias to it. The path can change, leaving you with broken aliases strewn about.

Also, Data > Reveal reveals an item in its location in the database. That item can be imported or indexed, and again you shouldn’t create filesystem aliases to imported files.

PS:

if (indexed of thisRecord) is false then
set end of thePaths to (path of thisRecord)
end if

This is incorrect. This is actually doing the thing it shouldn’t be doing. It’s saying, “If the file is imported, process it…” It should not be. The code should be…

if (indexed of thisRecord) is true then
    set end of thePaths to (path of thisRecord)
end if

… to process only indexed files.

So, here is my situation:
Typically, the files that I have in XMenu are from an Indexed group. What I mean by that is that I have Indexed in DTPO my Dropbox folder. So form there I can create aliases and place a copy in the XMenu folder.

However, I recently faced another situation. I kept a file only in DTPO, not in Dropbox. So I did not know if I can add that file to XMenu, and if I can, how can I create the alias? I assume that I still have to make an alias and copy it into the XMenu folder.

My workaround would have been to drag that file onto my desk top, then to the Dropbox folder which is Indexed in DTPO and from the Dropbox folder, I can create an alias.

I hope this makes a bit more sense. Thanks for your patience.

In case you’re trying to run the script I posted in this thread you’ll find that it doesn’t work in DEVONthink 3.6.

That’s due to DEVONthink’s new handling of “invalide arguments”. After the release of DEVONthink 3 I decided to continue to use “search window” in scripts so that DEVONthink 2 users could use them in, well, search windows. With version 3.6 that’s not possible anymore.

If you want to use the script you’ll have to replace this voluminous block …

set windowClass to class of window 1
if {viewer window, search window} contains windowClass then
	set currentRecord_s to selection of window 1
else if windowClass = document window then
	set currentRecord_s to content record of window 1 as list
end if

… with this neat line …

set currentRecord_s to selected records

… which does what the six lines have done. Wow, that’s great! :smiley:

1 Like