How to place text in specific InDesign text frame using its text frame ID?

When my script tells InDesign to place text in text frame 1, for example, it works.

But when I modify that statement to place text in text frame id [number goes here], it fails with "Adobe InDesign got an error: file “example.docx” doesn’t understand the “place” message."

What is the proper syntax for the place command when it’s used with a specific text frame (that I know exists)?

– Try something like:
set fp to “DATA:test.txt” as «class furl» → an InDesign Tagged Text file

tell application id "com.adobe.indesign"
	tell document 1
		tell page 2
			--return properties of text frame 1 -- to get ID
			set theTextFrame to item 1 of every text frame whose id is 180516
			place fp on theTextFrame			
		end tell
	end tell
end tell

Using this syntax, unfortunately I get the error Can’t get parent story of {}.

Here’s some context that might be helpful?

For testing purposes, I had my script place text in text frame 1 instead of using an id number, which works fine.

tell active page of layout window 1 of active document
    	set theTextFrame to text frame 1 -- relevant line
    	place writingFile on first insertion point of parent story of theTextFrame 
end tell

When I replace the relevant line with anything pointing to a text frame id, such as the example below (where variable textFrameID represents a known text frame id), that’s when I get an error. This one below results in the Can’t get parent story error:

    	set theTextFrame to item 1 of every text frame whose id is textFrameID

And using either of these results in the error I included in the original post:

    	set theTextFrame to text frame whose id is textFrameID

    	set theTextFrame to text frame id textFrameID

Is this a syntax issue? How do I get this to work?

Try this:

    	set theTextFrame to text frame 1 whose id is textFrameID

Thanks. Unfortunately, then I receive this error: Adobe InDesign 2021 got an error: Can’t get text frame 1 of active page of layout window 1 of active document whose id = [the number].

That command is probably nested in a series of tells and it’s not clear at runtime who’s id you’re referring to.

This might help.

tell application "Adobe InDesign CS6"
	--tell page 1 of document 1
	
	tell active page of layout window 1 of active document
		set textFrameID to id of text frame 1
		
		set theTextFrame to (text frame 1 whose id is textFrameID)
	end tell
	
end tell

I’m sorry, even using parentheses I’m still getting the same error as above.

Interestingly, though, if I include your set textFrameID to id of text frame 1 first, then the code does place the text!

But unfortunately, I’m not trying to place text in text frame 1, but rather in a text frame selected by a previous script earlier in the program. (My earlier script returns the id of the largest text frame on the page; I need to place text in the text frame with the matching id number.)

Therefore, as it currently stands, any code specifying text frame 1 functions identically to my test code, which sometimes places text in the wrong text frame (for my needs) depending on the page.

This is hard to do without seeing more of your script, but you may also try using the index of the text frame rather than the ID. But, word of caution, the index will change when text frames are added, removed or moved forward or backward. (For my purposes I generally use index, unless I’m doing any of that stuff above.)

The id is supposed to always work, but doesn’t, possibly because it’s less direct.

text frame 1

as opposed to

text frame 1 whose id = x

Sorry, what is ‘index’ referring to?

The other script just returns lists with the areas of each text frame on the active page, and all text frame ids on the page, and parses the lists to return a single id value associated with the largest text frame.

Here’s some sample code (made from a highly condensed and stripped out snippet of the code) that returns a list of the IDs of every text frame on the page:

tell active page of layout window 1 of active document
	set everyTextFrame to every text frame
	set allTextFrameIDs to {}
	repeat with thisTextFrame in everyTextFrame
		copy id to the end of the |allTextFrameIDs|
	end repeat
end tell

Would I be able to return a unique ‘index’ for each instead?

the index is the number used to reference each text frame on the page in their order from front to back.

In the statement “text frame 1” 1 is the index of the frontmost text frames.
Something like this…

tell active page of layout window 1 of active document
set numberOfTextFrames to the count of text frames
set textFrames to {}
repeat with x from 1 to numberOfTextFrames
	set the end of textFrameIndexes to text frame x
end repeat
end tell

But, you may not actually need the index or the id.

Your statement:

set everyTextFrame to every text frame

stores a reference to every text frame in that list.

You can simply do something like this (not tested)

set everyTextFrame to every text frame
repeat with thisTextFrame in every text frame
   	place someText on first insertion point of parent story of thisTextFrame
end repeat 

I tried incorporating your repeat handler and modifying it for my purposes into my larger code, and it works! My program is still able to select the largest text frame when using a list of indexes rather than IDs, but with the index it can also place text without an error. Thank you very much for your help; it is much appreciated! :slight_smile:

Just to clarify, this part wouldn’t work for me, because it would place the same text on every text frame on the page. Apologies if it wasn’t clear; earlier I mentioned that my sample code omits a lot of my irrelevant code. No worries, though, as we have a solution!

I have one more question, if it isn’t too much. Which syntax is the proper or most reliable way to add an item to the end of an AppleScript list? Here are some examples.

set the end of myList to myItem -- option 1
set the end of |myList| to myItem -- option 2
copy myItem to the end of the |myList| -- option 3

I tested all of these formats and they all seem to work. Which option should I go with? It doesn’t seem to matter, but if one is more ‘accepted’ or more widely used, maybe it won’t break in a future OS update (as one hypothetical example)?

All of those should work.

Using the | can help you avoid a terminology conflict if the variable name conflicts with a term in the app’s dictionary (or a scripting addition, library, etc.)

Using copy avoids appending a reference to an item in a list rather than the item itself.

If you every see a list that looks something like this in SD’s variable watcher or the result, then copy would resolve it:

{“A”, 2, item 3 of aDifferentList}

2 Likes