Keyboard Maestro 8.2.4 Actions

I use Javascript and KM to enter text variables in Adobe Illustrator. The variables are parsed from a JSON file. When the variable is blank or does not exist the variable %Name% gets entered into the Template placeholder. How can I prevent this? I've attached the relevant portion of my macro in case that helps.

Keyboard Maestro Actions.kmactions (1.7 KB)

We need clarification before we can really help.

Which variables? Where?
Please explicitly show us these variables, and where you use them.

Which variable? Where do you use "%Name%"?

If "Name" is the name of a KM variable, then it is best to use the full variable token, like this:

Thanks, JMichaelTX. I realize the simple solution is to test the variable before filling in the placeholder. Something like this:

var aDoc = app.activeDocument;
var myFrame = aDoc.textFrames["T_Back"];
var myText = "";
if (myText.length !== 0){
    myFrame.contents = myText;

As for using the %Variable%; why is this better? I have shortened them because they work and it reduces typing.

I realize I'm light on details. I hesitate to ask questions because there are so many details to share.

Specifically because it works in cases like this, and it is future-proof.

%Name% is by default a token. If I add a token for “Name” that returns, for example, your AddressBook name, then %Name% will do that in the future. Also, when the Name variable does not exist (as it does if you set it to the empty value, since as far as Keyboard Maestro is concerned, that is the same as it not existing), then %Name% will not be a token nor will it be a variable, so it will be nothing and result in %Name% in your resulting text.

So for a variable that may be empty, or that may clash with any future token, you need to use the %Variable%VarName% token format.


I'm not sure what you are trying to achieve here, but that logic will result in the if statement always being false, since just prior to it you set
var myText = "";

thus it's length will ALWAYS be zero.

Also, as mentioned before, please always use a Code Block with scripts/code. I have fixed your above post this last time.

1 Like

Thanks the explanation, Peter. I have updated my macros/script with %Variable% prefixes.

You're right, JMichaelTX, that did NOT work. I found another workaround to test the content of the placed text with a Regex:

//Delete if text is empty
if(^\%.*\%/i) !== -1){

It does work, but I realize it is not elegant. So, here is a more complete explanation of my workflow.

  • Capture KM Variables from JSON file embedded in our production website by running JXA script from KM.
  • Run JSX from KM (see original post - (variable names have been corrected)), to populate named text objects in Adobe Illustrator template.

My issue is, when a variable from the JSON is empty ("") KM populates the Illustrator template placeholder with the full Variable name. I don't know how to test the variable and delete the placeholder if there is no text in the variable.

Please show us the actual KM macro/actions where this happens.
Are you using the full variable token? It should be:

1 Like

Thank you for your persistence in helping me see the light. All is working as expected now, since updating the script with "%Variable%YourKMVarName%".
This is the script run through KM:

//Bookmark Script
var aDoc = app.activeDocument;
var theLayer = aDoc.layers["FRONT TEXT"];
var myScale = 100;
//Set layer visibility
theLayer.visible = true;
//FrontText.visible = true;

//set text
var targetFrame = aDoc.textFrames["T_FirstName"];
targetFrame.contents = "%Variable%firstName%";

targetFrame = aDoc.textFrames["T_LastName"];
targetFrame.contents = "%Variable%lastName%";

targetFrame = aDoc.textFrames["T_DateOfBirth"];
targetFrame.contents = "%Variable%dateOfBirth%";

targetFrame = aDoc.textFrames["T_DateOfDeath"];
targetFrame.contents = "%Variable%dateOfDeath%";

var targetFrame = aDoc.textFrames["T_Inscription"];
targetFrame.contents = "%Variable%frontInscription%";

targetFrame.textRange.characterAttributes.size = %Variable%MaxPoint% ;

//Get width from alignment object
var maxWidth = aDoc.pathItems["FRONT_Max"].width;
var maxHeight = aDoc.pathItems["FRONT_Max"].height;
var targetFrameWidth = targetFrame.width;

//set text width and height variables
var textWidth = maxWidth / targetFrameWidth * myScale;
var textHeight = maxHeight / targetFrameWidth * myScale;

if (targetFrameWidth > maxWidth) {
  targetFrame.resize(textWidth, textWidth);
selection = null;
aDoc.textFrames["T_Inscription"].selected = true;
var sel = selection;

var AlignObj = aDoc.pathItems["FRONT_Max"];

function alignToObj() {
  var keyCenter = getCenterPoint(AlignObj);
  var curItem, curCenter;

  //~     for (var x = 0, len = sel.length - 1; x < len; x++)
  for (var x = 0, len = sel.length; x < len; x++) {
    curItem = sel[x];
      //align the object horizontally  
      curItem.left = keyCenter.h - curItem.width / 2;
      //align the object vertically = keyCenter.v + curItem.height / 2;
  function getCenterPoint(item) {
    return {
      "h": item.left + item.width / 2,
      "v": - item.height / 2
//~ alignToObj();
selection = null;

var tfHeight = targetFrame.height;

if (tfHeight > maxHeight) {
  targetFrame.resize(maxHeight / tfHeight * myScale, maxHeight / tfHeight * myScale);
targetFrame.textRange.characterAttributes.autoLeading = true; =;
targetFrame.left = (AlignObj.left + (AlignObj.width / 2)) - (targetFrame.width / 2);
1 Like