• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers

Script or action to sync Layer comps outside Smart Object to Layer comp inside smart object

Explorer ,
Sep 13, 2022 Sep 13, 2022

Copy link to clipboard

Copied

Hi all,

I need just one last bit to complete an epic process. I have a multi language Smart Object embeded in a working psd.  In the Smart Object is a Layer Comp that controls visibility of each language.  Outside the Smart Object is the same Layer Comp list.  Using the properties panel I can sync the two Layer Comps, controlling the language visibility.  But it's a manual process.

When trying to build that behavior as an action using the "Next" button in the Layer Comp panel and the same named Layer Comp in the properties panel, I get an ID number.  Which would be fine, except when tried on a new working psd. Then it's not recognized.

 

If it's helpful, both in and out Layer Comps have identical names i.e. EN, JA, SP, FR, DA, ZH in the same order starting with EN.  Thanks in advance for any guidance.

 

TOPICS
Actions and scripting

Views

181

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Sep 25, 2022 Sep 25, 2022

I guess »Layer Comp Selection for Smart Objects« would have to be set in the Layer Comps in the containing document, but otherwise this might work: 

// if smart object has layer comps with same names as containing document select them and ipdate containing doc’s comps;
// 2022, use it at your own risk;
if (app.documents.length > 0) {
var myDocument = activeDocument;
var theLayerComps = getLayerCompsArray ();
var theSmartObjects = collectSmartObjectsLayerComps ();
// process layer comps;
for (var
...

Likes

Translate

Translate
Community Expert ,
Sep 13, 2022 Sep 13, 2022

Copy link to clipboard

Copied

I do not understand what exactly is problem. Testing Apply next layer comp using action and it works just fine. Can you post some screenshot to clarify what exactly you are doing and what is the problem?

 

This sentence is esspecially confusing to me: "When trying to build that behavior as an action using the "Next" button in the Layer Comp panel and the same named Layer Comp in the properties panel, I get an ID number. "

 

Here is my take, assuming that you have PSD file with layer comps which is placed inside another file. Action looks like this:
Edit Contents (embedded smart object with layer comps must be selected, record step before for that if necessary)

Apply next layer comp

Close (Saving:yes)

nextlayercompaction.jpg

 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Sep 13, 2022 Sep 13, 2022

Copy link to clipboard

Copied

My appologies, this is a complex workflow and I'm not sure a screen cap will do it. All this is for use with Export  Layer Comps, which creates specific psds named per the layer comp.  That part is fine.Layer Comp Sync.jpg

 

There are two identical layer comp lists.  One inside the embedded Smart object, EN, JA, NO.  The other in the comp/working psd, EN, JA, NO.  Again an Inside Layer Comp and Outside Layer Comp. To link the two I select "EN" Outside LC and via the Properties Panel go to the pull down menu and select the "EN" in the embedded LC, then sync/update the Outside layer comp.  I can manually do that for all the flags. When done, selecting the "NO" layer comp, changes the embedded Smart Object to the "NO" flag, and so on.

 

Making an action to select the next Outside LC and selecting the corresponding embedded LC via the properties panel comes up with a ID number unique to that choice.  The action fails on the next PSD. 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 14, 2022 Sep 14, 2022

Copy link to clipboard

Copied

You can change layer comp for current document then select and edith embedded PSD, change layer comp while in editing mode as shown in my screenshot above and deed will be done, if I can understand you. What is function of layer comps in document with one layer (embedded SO) only? I think you are overcomplicating without any need, if I do understand what are you trying to do. You can not export layer comps (File > Export > Layer Comps...) and isntruct Photoshop to change layer comp in embedded file for each layer comp in current document, at least I do not know for trick, especially using Photoshop actions.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Sep 14, 2022 Sep 14, 2022

Copy link to clipboard

Copied

My example is dumbed down and privacy concerns keep me from showing anything accurate  The end ask is for hundreds of combinations between product and language localization.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Sep 14, 2022 Sep 14, 2022

Copy link to clipboard

Copied

And yes the export layer comp script does exactly that.  It travels down the list of layer comps, adjusts the embedded layer comp as synced, then exports a separate file for each.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 14, 2022 Sep 14, 2022

Copy link to clipboard

Copied

I have used layer comps to files few times but I do not understand what is actual problem, apologies.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 14, 2022 Sep 14, 2022

Copy link to clipboard

Copied


@RoyBoySolorio wrote:

My example is dumbed down and privacy concerns keep me from showing anything accurate  The end ask is for hundreds of combinations between product and language localization.


Then please provide a meaningful mock-up file. 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Sep 14, 2022 Sep 14, 2022

Copy link to clipboard

Copied

Is there a way to post a psd to the forum? Or link?

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Sep 14, 2022 Sep 14, 2022

Copy link to clipboard

Copied

Attached is a psd working file.  It's been stripped down and renamed for security purposes.  Pull up the Layer Comp and properties panels.  Highlight the smart object.  Clicking on the layer comp name or arrowing through, the properties panel drives the layer comp within the embedded smart object to change. Changing the image in the Smart Object.

 

To get that behavior to work you manually sync the two layer comps. I'm looking for an action/script to do that routine.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 14, 2022 Sep 14, 2022

Copy link to clipboard

Copied

I downloaded and tested using your file. If you always have same layer comps, actually layer comps with same name in embedded file and you need exactly same layer comps in working document then the solution can be following:

 

  • Select embedded smart object manually or using action if its always named with exactly same name or it is always in the same relative position.
  • Edit contents,
  • Apply layer comp "EN"
  • Close with saving
  • Create new layer comp named EN
  • Edit contents
  • Apply layer comp "JA"
  • Close with saving
  • Create new layer comp named "JA"
  • Edit contents...

 

Here is how it looks when recorded without ID but with hard coded layer comp names.

apply layer comp and make new comp.jpg

 

In case that you have layer comps with different names in each new file and you want to copy name and create new layer comp with the same name in the working document then I must inform you it is not possible using Photoshop action.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Sep 14, 2022 Sep 14, 2022

Copy link to clipboard

Copied

Thanks Bojan,  I appreciate it but with the export layer comp system already established, entering an exiting the smart object doesn't flow with that.  I keep looking around.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 14, 2022 Sep 14, 2022

Copy link to clipboard

Copied

I do not understand what exactly you mean but let me try one more time. You have problem because there are already created layer comps in working file? Delete them , simply delete them for what you can record action steps. If you are always using same working file run same action with steps to delete existing layer comps then to open smart object and do things as shown above in screenshot with expanded action steps.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 25, 2022 Sep 25, 2022

Copy link to clipboard

Copied

I guess »Layer Comp Selection for Smart Objects« would have to be set in the Layer Comps in the containing document, but otherwise this might work: 

// if smart object has layer comps with same names as containing document select them and ipdate containing doc’s comps;
// 2022, use it at your own risk;
if (app.documents.length > 0) {
var myDocument = activeDocument;
var theLayerComps = getLayerCompsArray ();
var theSmartObjects = collectSmartObjectsLayerComps ();
// process layer comps;
for (var y = 0; y < theLayerComps.length; y++) {
    var thisComp = theLayerComps[y];
    for (var z = 0; z < theSmartObjects.length; z++) {
        for (var x = 0; x < theSmartObjects[z][2].length; x++) {
            var thisSOLC = theSmartObjects[z][2][x];
            if (thisComp[0] == thisSOLC[0]) {
                applyLayerComp (thisComp[2]);
                applyLayerCompToSmartObject(theSmartObjects[z][1], thisSOLC[1]);
            }
        }
        updateLayerComp ();
    };
}
};
////////////////////////////////////#
////// collect smart objects, probably based on code by paul, mike or x //////
function collectSmartObjectsLayerComps () {
// 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'));
// is smart object;
    if(layerDesc.hasKey(stringIDToTypeID('smartObject'))) {
// comps;
        var theSO = layerDesc.getObjectValue(stringIDToTypeID("smartObject"));
        var theCompsList = theSO.getObjectValue(stringIDToTypeID("compsList"));
        if (theCompsList.count > 2) {
        var theCompsList = theCompsList.getList(stringIDToTypeID("compList"));
        var theSOComps = new Array;
        for (var n = 0; n < theCompsList.count; n++) {
        var thisOne = theCompsList.getObjectValue(n);
        var theCompName = thisOne.getString(stringIDToTypeID("name"));
        var theCompID = thisOne.getInteger(stringIDToTypeID("ID"));
        var theComment = thisOne.getString(stringIDToTypeID("comment"));
        theSOComps.push([theCompName, theCompID, theComment]);
        };
// add to array;
        theLayers.push([theName, theID, theSOComps])
    }
}
}
} catch (e) {};
};
return theLayers
};
////// get array of layer comps’ properties //////
function getLayerCompsArray () {
    var ref = new ActionReference();
    ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") ); 
    var docDesc = executeActionGet(ref);
    var compList = docDesc.getList(stringIDToTypeID("compsList"));
    var theComps = new Array;
    for (var c = 0; c < compList.count; c++) {
    var thisOne = compList.getObjectValue(c);
    theComps.push(getObjectDesc(thisOne))
    };
    return theComps;
    };
////// based on code by michael l hale //////
function getObjectDesc (theDesc) {
    var c = theDesc.count;
    var str = new Array;
    for(var i=0;i<c;i++){ //enumerate descriptor's keys
    //	str.push([i+' = '+typeIDToStringID(theDesc.getKey(i))+': '+theDesc.getType(theDesc.getKey(i))+'\n'+getValues (theDesc, i)]);
        str.push(getValues (theDesc, i));
        };
    return(str);
    };
////// check //////
function getValues (theDesc, theNumber) {
    switch (theDesc.getType(theDesc.getKey(theNumber))) {
    case DescValueType.ALIASTYPE:
    return theDesc.getPath(theDesc.getKey(theNumber));
    break;
    case DescValueType.BOOLEANTYPE:
    return theDesc.getBoolean(theDesc.getKey(theNumber));
    break;
    case DescValueType.CLASSTYPE:
    return theDesc.getClass(theDesc.getKey(theNumber));
    break;
    case DescValueType.DOUBLETYPE:
    return theDesc.getDouble(theDesc.getKey(theNumber));
    break;
    case DescValueType.ENUMERATEDTYPE:
    return (typeIDToStringID(theDesc.getEnumerationValue(theDesc.getKey(theNumber)))+"_"+typeIDToStringID(theDesc.getEnumerationType(theDesc.getKey(theNumber))));
    break;
    case DescValueType.INTEGERTYPE:
    return theDesc.getInteger(theDesc.getKey(theNumber));
    break;
    case DescValueType.LISTTYPE:
    return theDesc.getList(theDesc.getKey(theNumber));
    break;
    case DescValueType.OBJECTTYPE:
    return (theDesc.getObjectValue(theDesc.getKey(theNumber))+"_"+typeIDToStringID(theDesc.getObjectType(theDesc.getKey(theNumber))));
    break;
    case DescValueType.RAWTYPE:
    return theDesc.getReference(theDesc.getData(theNumber));
    break;
    case DescValueType.REFERENCETYPE:
    return theDesc.getReference(theDesc.getKey(theNumber));
    break;
    case DescValueType.STRINGTYPE:
    return theDesc.getString(theDesc.getKey(theNumber));
    break;
    case DescValueType.UNITDOUBLE:
    return (theDesc.getUnitDoubleValue(theDesc.getKey(theNumber))+"_"+typeIDToStringID(theDesc.getUnitDoubleType(theDesc.getKey(theNumber))));
    break;
    default: 
    break;
    };
    };
////// apply layercomp to smart object //////
function applyLayerCompToSmartObject (theLayerID, theID) {
    selectLayerByID(theLayerID, false);
        var desc9 = new ActionDescriptor();
            var ref3 = new ActionReference();
//            ref3.putIdentifier(charIDToTypeID( "Lyr " ), theLayerID);
            ref3.putEnumerated(charIDToTypeID( "Lyr " ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ));
        desc9.putReference( charIDToTypeID( "null" ), ref3 );
        desc9.putInteger( stringIDToTypeID( "compID" ), theID );
    executeAction( stringIDToTypeID( "setPlacedLayerComp" ), desc9, DialogModes.NO );
    };
////// apply layer comp //////
function applyLayerComp (theID) {
    // =======================================================
    var desc6 = new ActionDescriptor();
    var ref3 = new ActionReference();
    ref3.putIdentifier( stringIDToTypeID( "compsClass" ), theID );
    //ref3.putName( stringIDToTypeID( "compsClass" ), theName );
    desc6.putReference( stringIDToTypeID( "null" ), ref3 );
    executeAction( stringIDToTypeID( "applyComp" ), desc6, DialogModes.NO );
    };
////// update layer comp //////
function updateLayerComp () {
        var desc13 = new ActionDescriptor();
            var ref8 = new ActionReference();
            ref8.putEnumerated( stringIDToTypeID( "compsClass" ), stringIDToTypeID( "ordinal" ), stringIDToTypeID( "targetEnum" ) );
        desc13.putReference( stringIDToTypeID( "null" ), ref8 );
    executeAction( stringIDToTypeID( "recapture" ), desc13, DialogModes.NO );
    };
////// based on code by mike hale and paul riggott //////
function selectLayerByID(index,add){ 
    add = undefined ? add = false:add 
    var ref = new ActionReference();
        ref.putIdentifier(charIDToTypeID("Lyr "), index);
        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); 
    }
    };

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Sep 25, 2022 Sep 25, 2022

Copy link to clipboard

Copied

Super excited to test this out. This last piece of the puzzle is the only
part that is done manually. I'll be checking it out Monday night.

I guess part of being so busy is because you're good at what you do. May I
ask, why do you help folks like me out, probably on your own time?
Regardless of the outcome here, I am extremely grateful for your gift.
Thank you.

Regards,

(personal info removed)

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Sep 26, 2022 Sep 26, 2022

Copy link to clipboard

Copied

ABSOLUTLY BRILLIANT.  Did exactly what I needed. Thank you, thank you.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 26, 2022 Sep 26, 2022

Copy link to clipboard

Copied

May I ask, why do you help folks like me out, probably on your own time?

There is a proverb (or at least a a quote from a movie) – »If someone does you a favor, don’t pay it back, pass it on«. 

People on this Forum (respectively its previous incarnations) have helped me in the past, so trying to help others in turn seems only fair. 

And some Scripting tasks seem interesting to figure out … 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 27, 2022 Sep 27, 2022

Copy link to clipboard

Copied

@RoyBoySolorio wrote:
May I ask, why do you help folks like me out, probably on your own time?

 


Yes, @RoyBoySolorio  if you can set aside some time to work on a mockup file, maybe record a video explaining how to use the script, so that it could reach and help more people?


Or feel free to stick around and reply to some threads, help others in return!

Do something kind to a stranger, there are so many ways to make this world a better place...

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Sep 26, 2022 Sep 26, 2022

Copy link to clipboard

Copied

In my excitement I replied to myself on this. c.pfaffenbichler you nailed it.  I state it here too ABSOLUTELY BRILLIANT!!

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Sep 27, 2022 Sep 27, 2022

Copy link to clipboard

Copied

Ok, working comp posted. Someone asked about the whole process, so with a hat tip to c.pfaffenbichler I'll go through the workflow.

Part 1, building the UI to be used as a Smart Object for various product angles.   Using pngs, exported from Figma, with as many as 20 Locales.  The first action calls up the "Load Files into Stack Script". In the Posted PSD, the images brought in are EN, JA, NO, IT.  The action continues by building out a group for each, based on the language and putting a vector hiding mask over each group. The action continues by sorting the correct image layer into their named group. Finally the action makes a name based Layer Comp, controlling the visibility of each group. This saves as a UI Build that will go into various assets. In the end this psd has four Layer Comps named EN, JA, NO and IT

 

Part 2 is to place the UI Build as a Smart Object into the product or lifestyle comp.  Once complete an action builds out the same layer Comps EN, JA, NO, and IT.  Now both Layer Comps need to be synced/paired, the one inside the Smart Object with the Layer Comp in the working comp. This is the part c.pfaffenbichler resolved.  That action pairs and syncs them, doing away with a manual, potentially erroneous, result.  Now clicking on the Layer Comp in the worker, drives the change in the smart object with out having to open it.

 

The last action builds on the "Export Layer Comps to Files" script, with some twists, but in the end I'll have 4 files named EN.psd, JA.psd, NO.psd, and IT.psd

 

Hope this helps prompt new workflow ideas.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 02, 2022 Oct 02, 2022

Copy link to clipboard

Copied

LATEST

Thank you very much for this explanation, this forum is more complete thanks to you!

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines