Hi @41291280 oops! I forgot to attach demo.indd. I have posted it now on my original post.
Actually I never expected you literally open/close/re-open your real documents. I (wrongly) thought that you had hundreds of ad documents already existing and you wanted to get the parent folder name insert into them so all you needed to do was open them (once!).
But it sounds like you are creating new ad documents so a better way would be to use the "afterSave" and "afterSaveAs" events. See modified script below: now it will make the substitution every time you save or saveAs. This time I remembered to attach my demo.indd for you to try it out! Try saving my demo document into different folders—it should update the magenta text accordingly.
- Mark
/**
* @file Populate With Parent Folder Name.js
*
* Will start an "afterSave" event listener which will
* replace any text with the target paragraph style applied
* with the name of the document's parent folder.
*
* Once the script has been run, opening any document that has
* the target paragraph style will have the text(s) replaced.
* Note: the function will only happen when a document is opened.
*
* @author m1b
* @version 2025-12-13
* @discussion https://community.adobe.com/t5/indesign-discussions/textvariable-zu-speicherort/m-p/15629977/thread-id/644543
* @acknowledgement I am using Marc Autret's clever pattern for adding event listeners here.
*/
(function (ev) {
/** the name of the paragraph style to target */
const PARAGRAPH_STYLE_NAME = 'Parent Folder Name';
/** Populates the found text with tje document's parent folder's name. */
function populate(text) {
text.contents = decodeURI(doc.filePath.name);
};
var listener1, listener2;
if (!(ev || 0).isValid) {
// install the event listener (if not yet installed!)
const UID = 'populate_with_parent_folder_name';
// this script file
var file = File($.fileName);
if (app.eventListeners.itemByName(UID).isValid)
app.eventListeners.itemByName(UID).remove();
if (
file.exists
&& !(app.eventListeners.itemByName(UID)).isValid
) {
// note: this script file is the 2nd argument
listener1 = app.eventListeners.add('afterSave', file);
listener2 = app.eventListeners.add('afterSaveAs', file);
listener2.name = UID;
}
return alert('Listener is running.');
}
if (
'afterSave' !== ev.eventType
&& 'afterSaveAs' !== ev.eventType
)
// not the right event
return;
var doc = ev.target || 0;
if (!(doc instanceof Document))
// not the right target
return;
var targetParagraphStyle = getThing(doc.allParagraphStyles, 'name', PARAGRAPH_STYLE_NAME);
if (!targetParagraphStyle)
return;
// use doScript so that the undo stack is nice and clean
app.doScript(populateAllTextInParagraphStyle, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Auto Populate');
function populateAllTextInParagraphStyle() {
app.findGrepPreferences = NothingEnum.NOTHING;
app.findGrepPreferences.appliedParagraphStyle = targetParagraphStyle;
var texts = doc.findGrep();
for (var i = 0; i < texts.length; i++)
populate(texts[i]);
};
/**
* Returns a thing with matching property.
* If `key` is undefined, evaluate the object itself.
* @author m1b
* @version 2024-04-21
* @param {Array|Collection} things - the things to look through.
* @param {String} [key] - the property name (default: undefined).
* @param {*} value - the value to match.
* @returns {*?} - the thing, if found.
*/
function getThing(things, key, value) {
for (var i = 0; i < things.length; i++)
if ((undefined == key ? things[i] : things[i][key]) == value)
return things[i];
};
})($.global.evt);