Skip to main content
Known Participant
November 23, 2018
Answered

How to *smoothly* add keywords to several non-indentically tagged pics?

  • November 23, 2018
  • 1 reply
  • 6003 views

Hello, tagging with keywords in Bridge CC (preferred over Lightroom Classic), I often want to add one more keyword to several images in a row that already have various non-identical keywords. I want to add the new keyword(s) so that the existing keywords remain there and are not replaced, but added-to. I think LR has a specific field to type keywords into; they will be added to selected images, but existing keywords remain.

Example:

Image A:

Existing keyword 1: beach

Existing keyword 2: sunset

Image B:

Existing keyword 1: street

Existing keyword 2: traffic light

Both images should receive the new keyword icecream, while the existing, non-identical keywords remain in-image. But when I select both images in Bridge, open "File Info" (translating menu commands here from other language) and type the new keywords, the old keywords are lost. I believe only LR has the small box that accepts keywords as additions, not replacements.

I found these ways to add – not replace – keywords to several selected images in one go in Bridge, but none is totally satisfactory:

  1. 1. way: In Keywords panel, right-click on Other Keywords, add a new keyword, select your images and click into the desired keyword's check-box in the Keywords panel.
  2. 2. way: Select only one image, open File Info, type the new keywords in, the existing ones will remain, and close. Wait (patiently) until the fresh keywords appear in the Keywords panel, select the other images and click into the keyword's check-box in the Keywords panel.
  3. 3. way: For more often used (groups of) keywords, create metadata templates. They can be easily applied to selected images by menu command Add Metadata (not Replace Metadata)
  4. 4. way: For rarer keywords, create a generic metadata template called "1 metadata" (so it's alphabetically on top), fill it with your keywords du jour, save, select images, apply.

I am also aware of hierachical keywords and of importing tabbed text files as keywords. But I use many keywords and I am a fast and safe typer. On the other hand, my Keywords panel gets way too long very quickly, even if I empty it all the time; I don't like to use it. My list of metadata templates has grown too long too, but you can easily clean up by moving or deleting some xmp files.

Do you know a smoother way how to rapid-add keywords to several, already non-identically tagged images in Bridge?

  Thanks!

    This topic has been closed for replies.
    Correct answer Stephen Marsh

    Stephen, i did not try this. It is too complicated for me - more so when you tell me before it might not work.


    I just tested and It works in CC2019 on Windows… Although the script would need adjustment for nicer GUI colours!

     

    It is not too complicated, copy the following 194 lines of source code and paste into a plain text editor like TextEdit.app or Notepad.exe, and save the file with a .jsx extension rather than .txt:

     

    // https://stackoverflow.com/questions/47797219/edit-script-for-editing-metadata-in-adobe-bridge-how-should-i-put-key-words
    #target bridge
    
       if( BridgeTalk.appName == "bridge" ) {
    keyReplace = MenuElement.create("command", "Add-Replace-Remove Keyword", "at the end of tools");
    }
    keyReplace.onSelect = function () {
          mainReplaceKeyword();
          }
    
    function mainReplaceKeyword(){
    if(app.version.substr(0,app.version.indexOf('.'))==1){
    alert("Sorry You Need CS3 or CS4 to run this script!");
    return;
        }
    var dlg =
    "dialog{text:'Script Interface',bounds:[100,100,500,310],"+
    "panel0:Panel{bounds:[10,10,390,200] , text:'' ,properties:{borderStyle:'etched',su1PanelCoordinates:true},"+
    "title:StaticText{bounds:[60,10,350,40] , text:'Add/Replace/Remove Keyword' ,properties:{scrolling:undefined,multiline:undefined}},"+
    "panel1:Panel{bounds:[10,40,370,150] , text:'' ,properties:{borderStyle:'etched',su1PanelCoordinates:true},"+
    "addKey:Checkbox{bounds:[20,10,160,31] , text:'Add Keyword' },"+
    "statictext1:StaticText{bounds:[20,40,119,60] , text:'Replace' ,properties:{scrolling:undefined,multiline:undefined}},"+
    "From:EditText{bounds:[120,40,350,60] , text:'' ,properties:{multiline:false,noecho:false,readonly:false}},"+
    "statictext2:StaticText{bounds:[20,80,90,97] , text:'With' ,properties:{scrolling:undefined,multiline:undefined}},"+
    "To:EditText{bounds:[120,80,350,100] , text:'' ,properties:{multiline:false,noecho:false,readonly:false}}},"+
    "button0:Button{bounds:[10,160,180,181] , text:'Ok' },"+
    "button1:Button{bounds:[200,160,370,181] , text:'Cancel' }}};";
    var win = new Window(dlg,"Replace Keyword");
    win.center();
    
    win.panel0.title.graphics.font = ScriptUI.newFont("Times","BOLDITALIC",20);
    g = win.graphics;
    b=win.panel0.title.graphics;
    var myBrush = g.newBrush(g.BrushType.SOLID_COLOR, [0.99, 0.99, 0.20, 1]);
    g.backgroundColor = myBrush;
    var myPen =b.newPen (g.PenType.SOLID_COLOR, [0.00, 0.00, 0.99, 1],lineWidth=1);
    var myPen2 =b.newPen (g.PenType.SOLID_COLOR, [0.99, 0.00, 0.00, 1],lineWidth=1);
    g.foregroundColor = myPen;
    b.foregroundColor = myPen2;
    win.panel0.panel1.From.active=true;
    win.panel0.panel1.addKey.onClick = function() {
    if(win.panel0.panel1.addKey.value) {
        win.panel0.panel1.statictext1.text = "New Keyword";
        win.panel0.panel1.From.active=true;
        win.panel0.panel1.statictext2.visible=false;
        win.panel0.panel1.To.visible=false;
        }
    if(!win.panel0.panel1.addKey.value) {
        win.panel0.panel1.statictext1.text = "Replace";
        win.panel0.panel1.statictext2.visible=true;
        win.panel0.panel1.To.visible=true;
        win.panel0.panel1.From.active=true;
        }
    }
    win.center();
    var done = false;
        while (!done) {
          var x = win.show();
          if (x == 0 || x == 2) {
            win.canceled = true;
            done = true;
          } else if (x == 1) {
            done = true;
           var result = valiDate();
            if(result != true) {
                alert(result);
                return;
            }else{
                var Replace = win.panel0.panel1.From.text;
                var With = win.panel0.panel1.To.text;
                var addKey = win.panel0.panel1.addKey.value;
                processKeyword(Replace,With,addKey);
            }
          }
       }
    
    function valiDate(){
        if(win.panel0.panel1.From.text =='') return "No Keyword Entered!";
    return true;
    }
    function processKeyword(Replace,Witha,ddKey){
    try{
    loadXMPScript();
    }catch(e){
    alert("Can not load XMPScript\r" + e.message);
        }
    
    var items = app.document.selections;
      for (var i = 0; i < items.length; i++){
          var file=new Thumbnail(items[i]);
    try{
    var xmpFile = new XMPFile(file.path, XMPConst.UNKNOWN,XMPConst.OPEN_FOR_UPDATE);
    }catch(e){
            alert("Problem opening xmp for update:-\r" + file.path +"\r" +e.message);
            return;
        }
    try{
    var xmp = xmpFile.getXMP();
    }catch(e){
            alert("Problem opening xmp data:-\r"  + e.message);
            return;
        }
    try{
    var tmpCount =  xmp.countArrayItems(XMPConst.NS_DC, "subject");
    }catch(e){
        alert("Cannot get count \r" + e.message);
        }
                if(addKey){
                    xmp.appendArrayItem(XMPConst.NS_DC, "subject", Replace, 0,XMPConst.ARRAY_IS_ORDERED);
                    }
    if(tmpCount >0 && !addKey){
            for (var a =0;a<tmpCount;a++){
                var     Keyword = xmp.getArrayItem(XMPConst.NS_DC,'subject', a+1);
                if(Keyword == Replace && With == '') {
                    xmp.deleteArrayItem(XMPConst.NS_DC,'subject', a+1);
                    }
                if(Keyword == Replace && With != ''){
                    xmp.setArrayItem(XMPConst.NS_DC,'subject', a+1,With);
                    }
            }
    }
    
    if (xmpFile.canPutXMP(xmp)) {
    xmpFile.putXMP(xmp);
    }else{
    alert(e.message);
        }
    xmpFile.closeFile(XMPConst.CLOSE_UPDATE_SAFELY);
    }
    unloadXMPScript();
    }
    }
    
    function loadXMPScript()
    {
        var results = new XMPLibMsg("XMPScript Library already loaded", 0, false);
    
        if (!ExternalObject.AdobeXMPScript)
        {
            try
            {
                ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript');
                results.message = "XMPScript Library loaded";
            }
            catch (e)
            {
                alert("Could not load AdobeXMPScript \r" + e.message);
                results.message = "ERROR Loading AdobeXMPScript: " + e;
                results.line = e.line;
                results.error = true;
            }
        }
    
        return results;
    }
    function unloadXMPScript()
    {
        var results = new XMPLibMsg("XMPScript Library not loaded", 0, false);
    
        if( ExternalObject.AdobeXMPScript )
        {
            try
            {
                ExternalObject.AdobeXMPScript.unload();
                ExternalObject.AdobeXMPScript = undefined;
                results.message = "XMPScript Library successfully unloaded";
            }
            catch (e)
            {
                results.message = "ERROR unloading AdobeXMPScript: " + e;
                results.line = e.line;
                results.error = true;
            }
        }
    
        return results;
    }
    function XMPLibMsg (inMessage, inLine, inError)
    {
        this.message = inMessage;
        this.line = inLine;
        this.error = inError;
    }

     

    Then:

     

    1. Open Adobe Bridge, then open Bridge’s preferences dialog
    2. Under Startup Scripts - click the "Reveal My Startup Scripts" button
    3. Copy/Paste or drag-n-drop your .jsx script files into the folder/directory
    4. Quit and restart Bridge and answer "Yes" to enable the script.

     

    The script will be available under the Tools menu as "Add-Replace-Remove Keyword”.

     

    1 reply

    Stephen Marsh
    Community Expert
    Community Expert
    November 23, 2018

    I’m not having much luck with this one, however it probably just needs adjustment to work with later versions:

    https://stackoverflow.com/questions/47797219/edit-script-for-editing-metadata-in-adobe-bridge-how-should-i-put-key-words

    Known Participant
    November 24, 2018

    Stephen, thanks.

    Stephen Marsh
    Community Expert
    Community Expert
    November 24, 2018

    Your welcome… but does it work?

    The OK or Cancel buttons don’t do anything for me in Bridge CS6 or CC2018, so it is not possible to apply the new common keyword.

    I forgot to add the following to my original reply:

    Prepression: Downloading and Installing Adobe Scripts