jsonnet

Partially interpolate a format string in Jsonnet


Suppose I want to do:

local formatString = "Name: %(a)s Age: %(b)s";
local v = formatString % {a: "a"};
{
  asd: v % {b: "1"}
}

The above doesn't compile, is there any way to achieve this goal of doing string interpolation in two steps?

one thing that makes this tricky is that the format string is fixed at the beginning, I cannot realiably parse the format string with only the param I have


Solution

  • You can escape the 1st formatting via %%, as in the 1st example below. Alternatively (depending on the context/complexity of your code), you can "trick" the above snippet by passing b as a formatting string itself, so that you satisfy the 1st for required fields, but leave there ready the resulting string as a formatting one:

    1) escape the 1st formatting via %%

    local formatString = 'Name: %(a)s Age: %%(b)s';
    local v = formatString % { a: 'a' };
    {
      asd: v % { b: '1' },
    }
    

    2) using same formatting string

    local formatString = 'Name: %(a)s Age: %(b)s';
    local v = formatString % { a: 'a', b: '%(b)s' };
    {
      asd: v % { b: '1' },
    }
    

    3) using a variable for "lazy" (late) formatting

    Same as 2) but kinda generalized:

    local lazyEvalVar = 'someVar'; // `b` in the above example
    local lazyEvalString = '%(someVar)s';
    
    local formatString = 'Name: %(a)s Age: ' + lazyEvalString;
    local v = formatString % { a: 'a', [lazyEvalVar]: lazyEvalString };
    {
      asd: v % { [lazyEvalVar]: '1' },
    }