8 Replies Latest reply on Feb 13, 2015 9:05 AM by regina63

    Setting a font on a PSD text item in javascript?

    regina63

      Hi there,

      I'm new to photoshop scripting and am having a bit of trouble editing a text layer in Photoshop using javascript.

       

      I have a few PSD templates in which I'd like to replace text on specific layers with javascript before generating hundreds of animated GIFs. I have placeholder text on the target layers and have been able to replace it with:

       

      "textItemRef.contents = "Hello, world";

       

      however this loses ALL text formatting. Is there a different way to replace existing text keeping sizes/colors/fonts in tact? All examples I can find create new layers needing all the attributes. I've tried assigning a paragraph style to the placeholder text using Photoshop cc 2014 stylesheets but that doesn't retain styles when the text is replaced, either.

       

      I also can't find mention of TEXT STYLESHEETS in the scripting guides or photoshop DOM references, presumably because they're so new? If anyone has been able to assign TEXT styles, what is the syntax? Or is there one for clearing overrides if that's possible?

       

      If the only way IS to style everything one attribute at a time, I am having problems with the font attribute. var myFont = app.fonts.getByName("Arial"); does not seem to work.

        • 1. Re: Setting a font on a PSD text item in javascript?
          matias.kiviniemi Level 3

          Don't have answers to all of your questions, but maybe some. My experience has been that setting content retains the layer default value (~same as double click text layer to select all and paste). Note that the Javascript API does not cover full PS text layer features. Like in PS you can style every single letter individually, but Javascript sets style for whole item. So you can one style for layer and then another for actual (visible) characters which could explain your behaviour. Forums have more info how to set more detailed settings with ActionDescriptors.

           

          Now, for setting the family, textItem.font wants the official font name while fonts.getByName returns the font object. So put layer.textItem.font = app.fonts.getByName(font_family).postScriptName (and add error handling).

          • 2. Re: Setting a font on a PSD text item in javascript?
            c.pfaffenbichler Level 9

            If you want to combine different fonts, sizes, colors etc. in one Type Layer created or edited via Scripting you probably need to resort to use ActionManager code (as record by ScriptingListener.plugin).

            But that generally does not seem particularly easy, especially if one is only accustomed to use DOM code.

            • 3. Re: Setting a font on a PSD text item in javascript?
              regina63 Level 1

              Matias,

              You are right! The layer should have kept its formatting. I tried this with a new file and there were no reformatting issues. I had started a new layer before thinking it might be the issue, but I must not have tried it in tandem with the correct script snippet, which I kept searching for.

               

              This is the leanest solution I could get from combining two examples for replacing text in specific photoshop layers. I wish it had been a bit easier to find, so sharing it here:

               

                  app.activeDocument.artLayers["headline"].textItem.contents = "MY HEADLINE HERE";

                  app.activeDocument.artLayers["sub_head"].textItem.contents = "Short subhead here";

                  app.activeDocument.artLayers["button"].textItem.contents = "LET'\S GO!";

              (note the bracketed quotes should contain your actual layer names, and must match the name exactly).

              Thanks

              • 4. Re: Setting a font on a PSD text item in javascript?
                regina63 Level 1

                Thanks c.pfaffenbichler,

                I actually just wanted to work layer by layer, and was having issues with the layer I was working on for some reason. Perhaps it was initially formatted with style sheets or something, and I haven't managed to override. Starting a new file solved the issues, provided the app.activeDocument.artLayers["headline"].textItem.contents = "MY HEADLINE HERE"; code is used to import the text.

                Still, thanks for the input.

                 

                I should have titled the question "Replacing text content on a specific PSD layer in Photoshop."

                • 5. Re: Setting a font on a PSD text item in javascript?
                  pixxxel schubser MVP & Adobe Community Professional

                  Hi regina63,

                  does this work for you:

                  var aLay = app.activeDocument.activeLayer;
                  if(aLay.textItem && aLay.textItem.contents != "") {
                  
                  var changedText= aLay.textItem.contents.replace (/.+/, "new Text");
                  aLay.textItem.contents = changedText;
                  }
                  
                  
                  

                   

                  regards

                  pixxxel schubser

                   

                  • 6. Re: Setting a font on a PSD text item in javascript?
                    regina63 Level 1

                    A follow-up for anyone experiencing this dropped style on a layer when importing new content... it turns out using paragraph styles AT ALL on a layer will make that layer lose its style when new text is imported with javascript (for some reason photoshop then incorrectly assumes you want to reset the formatting of the new layer to the DEFAULT paragraph style). This is the complete opposite of the results you'd want to use stylesheets to attain in the first place. But, starting with a layer that has only been manually styled with the font menus and character menu items will hold its attributes when importing new text.

                    I've recorded and copied below the ActionManager script happening behind the scenes when importing text, and all Photoshop does with the stylesheets because I've used a paragraph style:

                    // =======================================================

                    var idAdobeScriptAutomationScripts = stringIDToTypeID( "AdobeScriptAutomation Scripts" );

                        var desc459 = new ActionDescriptor();

                        var idjsCt = charIDToTypeID( "jsCt" );

                        desc459.putPath( idjsCt, new File( "/Applications/Adobe Photoshop CC 2014/Presets/Scripts/one-text-line-to-hdln.jsx" ) );

                        var idjsMs = charIDToTypeID( "jsMs" );

                        desc459.putString( idjsMs, """this is text""" );

                    executeAction( idAdobeScriptAutomationScripts, desc459, DialogModes.NO );

                     

                     

                    // =======================================================

                    var idsetd = charIDToTypeID( "setd" );

                        var desc460 = new ActionDescriptor();

                        var idnull = charIDToTypeID( "null" );

                            var ref36 = new ActionReference();

                            var idPrpr = charIDToTypeID( "Prpr" );

                            var idparagraphStyle = stringIDToTypeID( "paragraphStyle" );

                            ref36.putProperty( idPrpr, idparagraphStyle );

                            var idTxLr = charIDToTypeID( "TxLr" );

                            var idOrdn = charIDToTypeID( "Ordn" );

                            var idTrgt = charIDToTypeID( "Trgt" );

                            ref36.putEnumerated( idTxLr, idOrdn, idTrgt );

                        desc460.putReference( idnull, ref36 );

                        var idT = charIDToTypeID( "T   " );

                            var desc461 = new ActionDescriptor();

                            var idstyleSheetName = stringIDToTypeID( "styleSheetName" );

                            desc461.putString( idstyleSheetName, """Basic Paragraph""" );

                            var idtypeStyleOperationType = stringIDToTypeID( "typeStyleOperationType" );

                            desc461.putInteger( idtypeStyleOperationType, 1 );

                        var idparagraphStyle = stringIDToTypeID( "paragraphStyle" );

                        desc460.putObject( idT, idparagraphStyle, desc461 );

                    executeAction( idsetd, desc460, DialogModes.NO );

                    _____________

                    Now the same actions with no style applied to the layer getting new text.

                    • 7. Re: Setting a font on a PSD text item in javascript?
                      regina63 Level 1

                      (same actions when starting with text only styled using menu item, no further lines were generated after text was imported)

                      // =======================================================

                      var idAdobeScriptAutomationScripts = stringIDToTypeID( "AdobeScriptAutomation Scripts" );

                          var desc544 = new ActionDescriptor();

                          var idjsCt = charIDToTypeID( "jsCt" );

                          desc544.putPath( idjsCt, new File( "/Applications/Adobe Photoshop CC 2014/Presets/Scripts/one-text-line-to-hdln.jsx" ) );

                          var idjsMs = charIDToTypeID( "jsMs" );

                          desc544.putString( idjsMs, """this is text""" );

                      executeAction( idAdobeScriptAutomationScripts, desc544, DialogModes.NO );

                      • 8. Re: Setting a font on a PSD text item in javascript?
                        regina63 Level 1

                        Pixel,

                        Thanks for this! Your version works well, too, and provides the all-important IF statement to avoid a silly error...


                        I think the active layer phrase may work when we've used the other method of find by name... either of these statements by themselves will work:

                        app.activeDocument.artLayers['headline'].textItem.contents = "this is new text";

                        app.activeDocument.artLayers.getByName('headline').textItem.contents = ("this is new text");

                         

                        but for the script I was using I just go straight to the layer, and it may not be "active", so I've replaced activeLayer with the specific layer ref...

                         

                        var aLay = app.activeDocument.artLayers['headline'];

                        if(aLay.textItem && aLay.textItem.contents != "") {

                         

                        var changedText= aLay.textItem.contents.replace (/.+/, "new Text");

                        aLay.textItem.contents = changedText;

                        }