Skip to main content
Andreas Resch
Inspiring
December 3, 2022
Question

Updating all linked object

  • December 3, 2022
  • 3 replies
  • 7658 views

How can I update all linked files in a master file - including the ones inside smart objects? Can't find any commands for that. Preferably I would love to get a warning when opening the master file, that linked files were updated. Similar to what happens in InDesign when linked files are changed.

3 replies

c.pfaffenbichler
Community Expert
Community Expert
December 9, 2022

One additional note: 

It seems perfectly possible to create a set-up in which an automation gets caught in a loop. 

Suppose an image contains two Linked Smart Objects (A and B) that each contain the other as a Linked Smart Object. 

Saving any changes in A will cause it to update in B, which upon saving will update in A etc.

Andreas Resch
Inspiring
December 9, 2022

One more reason why this would work better in the core code. They can probably better access a list of external files that are included in the parent file. And working that off is much easier than looping through layers. Probably doing a lot of repetitive tasks in doing so as well.

c.pfaffenbichler
Community Expert
Community Expert
December 9, 2022

Actually such a situation would seem like a problem no matter where the updating would be done. 

 

I suppose it would be possible to include

• either a check to verify if the updating actually results in any changed pixels (and otherwise abandon the process) 

• or check the whole reference tree for »loops« 

but both options would probably have costs. 

Stephen Marsh
Community Expert
Community Expert
December 4, 2022
Andreas Resch
Inspiring
December 5, 2022

Thanks for the link. But I'm not sure that this is the right script. I want to update my modified linked files and not relink them. Besides that the script takes several minutes to go through my layers until it gets to the prompted window. And this is one of my smaller files. 

Stephen Marsh
Community Expert
Community Expert
December 5, 2022

@Andreas Resch 

 

Perhaps this previous topic will help?

 

 
Although the following is removing photoshop:DocumentAncestors metadata inside nested smart objects, the base code could be used and the metadata removal replaced with code for updating linked smart objects.
 
 
c.pfaffenbichler
Community Expert
Community Expert
December 3, 2022

Layer > Smart Objects > Update All Modified Content does not apply to Linked Smart Objects within Smart Objects (and further down). 

 

One could automate that via a Script that opens all Smart Objects (and Smart Objects within Smart Objects and so on …) to verify if all Linked Smart Objects within those are up-to-date. 

Have you done a Forum search yet? Maybe someone already created such a Script. 

 

Andreas Resch
Inspiring
December 3, 2022

I found one script, but it didn't work properly. This should be included in the core code. I'm surprised, that it's not already in there. I have files with dozens of linked smart objects and I can't go through all of them individually. There's also a chance that I missed one. 

c.pfaffenbichler
Community Expert
Community Expert
December 9, 2022

Not sure what you want the sample file for. Is this still about updating linked files within smart objects? If so, that's a general issue and not related to my files specifically. If this is about some crossover issues about the slow performance of smart objects, which indeed is specific to some of my bigger files and not everybody would encounter due to my specific workflow, then this is already adressed by Adobe (hopefully).


You can try this 

// updateModifiedLinkedSmartObjectsInSmartObjects
// update all modified smart objects including in pixel smart objects;
// 2022, use it at your own risk;
if (app.documents.length > 0) {
	updateAllModifiedContent ();
	var theStuff = collectSmartObjectsX([]);
	var repeat = true;
	while (repeat == true) {
		for (var b = 0; b < theStuff.length; b++) {
			var theCount = 0;
			var thisOne = theStuff[b];
			app.activeDocument = thisOne;
			if (hasModifiedSmartObject() == true) {
				updateAllModifiedContent ();
				thisOne.save();
				theCount++
			};
		};
		if (theCount == 0) {repeat = false}
	};
	for (var c = 0; c < theStuff.length; c++) {
		var thisOne = theStuff[c];
		app.activeDocument = thisOne;
		if (thisOne.isDirty == false ) {thisOne.close()}
		else {thisOne.close(SaveOptions.SAVECHANGES)};
	};
};
////////////////////////////////////
////// collect smart objects, probably based on code by paul, mike or x //////
function collectSmartObjectsX (theDocs) {
	var myDocument = app.activeDocument;
	for (var a = 0; a < theDocs.length; a++) {
		if (theDocs[a] == app.activeDocument) {theCheck = false}
	};
	if (theCheck == true) {theDocs.push(app.activeDocument)};
// get number of layers;
	var ref = new ActionReference();
	ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
	var applicationDesc = executeActionGet(ref);
	var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
// process the layers;
	var theLayers = new Array;
	for (var m = 0; m <= theNumber; m++) {
	try {
	var ref = new ActionReference();
	ref.putIndex( charIDToTypeID( "Lyr " ), m);
	var layerDesc = executeActionGet(ref);
	var layerSet = typeIDToStringID(layerDesc.getEnumerationValue(stringIDToTypeID("layerSection")));
	var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));
// if not layer group collect values;
	if (layerSet != "layerSectionEnd" && layerSet != "layerSectionStart" && isBackground != true) {
	var theName = layerDesc.getString(stringIDToTypeID('name'));
	var theID = layerDesc.getInteger(stringIDToTypeID('layerID'));
	if(layerDesc.hasKey(stringIDToTypeID('smartObject'))) {
		var theSO = layerDesc.getObjectValue(stringIDToTypeID("smartObject"));
		var isVector = typeIDToStringID(theSO.getEnumerationValue(stringIDToTypeID('placed')));
		if (isVector == "rasterizeContent") {
			var isLinked = theSO.getBoolean(stringIDToTypeID("linked"));
			var theReference = theSO.getString(stringIDToTypeID('fileReference'));
			var docID = theSO.getString(stringIDToTypeID('documentID'));
			theLayers.push([theName, theID, isLinked, theReference, docID]);
			selectLayerByID (theID,false);
			openSmartObject ();
			var theCheck = true;
			for (var a = 0; a < theDocs.length; a++) {
				if (theDocs[a] == app.activeDocument) {theCheck = false}
			};
			if (theCheck == true) {theDocs.push(app.activeDocument)};
			collectSmartObjectsX (theDocs);
			app.activeDocument = myDocument;
		}
	}
	};
	}
	catch (e) {};
	};
	//return theLayers
	return theDocs
	};
////// based on code by mike hale, via paul riggott //////
function selectLayerByID(id,add){ 
add = undefined ? add = false:add 
var ref = new ActionReference();
	ref.putIdentifier(charIDToTypeID("Lyr "), id);
	var desc = new ActionDescriptor();
	desc.putReference(charIDToTypeID("null"), ref );
		if(add) desc.putEnumerated( stringIDToTypeID( "selectionModifier" ), stringIDToTypeID( "selectionModifierType" ), stringIDToTypeID( "addToSelection" ) ); 
		desc.putBoolean( charIDToTypeID( "MkVs" ), false ); 
	try{
	executeAction(charIDToTypeID("slct"), desc, DialogModes.NO );
}catch(e){
alert(e.message); 
}
};
////// update //////
function updateAllModifiedContent () {
var idplacedLayerUpdateAllModified = stringIDToTypeID( "placedLayerUpdateAllModified" );
executeAction( idplacedLayerUpdateAllModified, undefined, DialogModes.NO );
};
////// open smart object //////
function openSmartObject () {
    var desc2 = new ActionDescriptor();
    executeAction( stringIDToTypeID( "placedLayerEditContents" ), desc2, DialogModes.NO );
    return activeDocument;
    };
////// collect layers //////
function hasModifiedSmartObject () {
	// get number of layers;
	var ref = new ActionReference();
	ref.putProperty(stringIDToTypeID('property'), stringIDToTypeID('numberOfLayers'));
	ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
	var applicationDesc = executeActionGet(ref);
	var theNumber = applicationDesc.getInteger(stringIDToTypeID("numberOfLayers"));
	// process the layers;
	var theLayers = new Array;
	for (var m = 0; m <= theNumber; m++) {
	try {
	var ref = new ActionReference();
	ref.putIndex( charIDToTypeID( "Lyr " ), m);
	var layerDesc = executeActionGet(ref);
	var isSmartObject = layerDesc.hasKey(stringIDToTypeID("smartObject"));
	// collect smart object links;
	if (isSmartObject == true) {
	var theSO = layerDesc.getObjectValue(stringIDToTypeID("smartObject"));
	if (theSO.getBoolean(stringIDToTypeID("linked")) == true) {
	var isChanged = theSO.getBoolean(stringIDToTypeID('linkChanged'));
	var theLink = theSO.getPath(stringIDToTypeID("link"));
	//alert (isChanged);
	if (isChanged == true) {theLayers.push(theLink)};
	};
	};
	}
	catch (e) {};
	};
	if (theLayers.length > 0) {return true}
	else {return false}
	};