Set custom property/custom variable via CLI

Hello there.

I have an ODT document that contains fields. These fields shall be used to display text content defined in custom variables or custom document properties.

How can I set the variable or property value from the command line?
Since I’d like to update the variable or property just before exporting to PDF, is there a combined CLI command that sets the value and renders the PDF?

This would require calls to the API in a supported language such as Python or Java.

While it is not simple it can be done via Command Line Interface with lets say a python script.

OOO Development Tools (OooDev) Is a good resource for this. See the Italics Styler as an example that runs on the CLI.

Although it requires decent developer skills to write a script to accomplish what your asking.

1 Like

Seems like from the Italics Style I can learn how to open a document.
Then I would follow python-ooouno-ex/ex/auto/general/odev_doc_prop/start.py at main · Amourspirit/python-ooouno-ex · GitHub
And to save or print the document I could follow - save, or even better export the document to PDF (python-ooouno-ex/ex/auto/general/odev_doc_convert/start.py at main · Amourspirit/python-ooouno-ex · GitHub)

Sounds feasible, I will give that a shot. :slight_smile:

I finally have a solution - maybe others can benefit from it too. To run my code on a plain Ubuntu installation I recommend running

sudo apt-get install pip3
sudo pip install ooo-dev-tools

Once done, this python script can load the document, set any known user defined property, then save the document in any supported target format:

#!/bin/python3

import sys
from ooodev.utils.lo import Lo
from ooodev.utils.info import Info
from com.sun.star.beans import XPropertySet
from com.sun.star.beans import XPropertyAccess

doc = None

def main() -> int:
  print (sys.argv)

  with Lo.Loader(Lo.ConnectSocket(headless=True)) as loader:
    i = 0
    while i < len(sys.argv):
      arg = sys.argv[i]
      match arg:
        case "--load":
          i=i+1
          docname = sys.argv[i]
          print("loading " + docname)
          doc = Lo.open_doc(fnm=docname, loader=loader)
        case "--set":
          i=i+1
          val = sys.argv[i]
          items = val.split("=")
          name = items[0]
          value = items[1]
          print("setting " + name + "=>" + value)
          
          user_props = Info.get_user_defined_props(doc) # XPropertyContainer
          ps = Lo.qi(XPropertySet, user_props, True)
          
          try:
            ps.setPropertyValue(name, value)
          except Exception:
            pa = Lo.qi(XPropertyAccess, user_props, True)
            names = []
            for propertyvalue in pa.getPropertyValues():
              names.append(propertyvalue.Name)
            print ("Cannot set property '" + name + "'. Known properties are ", names)
            return 1
        case "--save":
          i=i+1
          docname = sys.argv[i]
          print("saving " + docname)
          Lo.save_doc(doc=doc, fnm=docname)
        case _:
          print (i, sys.argv[i])
      i=i+1
    return 0
  
if __name__ == "__main__":
    raise SystemExit(main())

Once installed, the script can be invoked like
convert.py --load mydoc.odt --set propname=propvalue -save mydoc.pdf

Be aware you can use all the options multiple times and they are evaluated from left to right.
That means you can load a document, set multiple properties, save it into two output documents, load the next…

I am not aware of any CLI option allowing to set a variable, even less to change properties.

As a workaround, you can restructure your document as a master document referencing a sub-document containing your variable initialisations. Unfortunately properties are “local” to a document, i.e. properties defined in the sub-document cannot be referenced from the master.

Your procedure will then be;

  1. Modify the variable values in the sub-document
  2. Launch LO on the master document in CLI mode with --convert-to pdf option

PS: when asking, always mention OS name, LO version and save format. From my workaround description, it is obvious that the document must be saved native, i.e. odm for master and odt for sub.

Hmmm. In the beginning you say there might be no CLI option t set a variable or property.

Then you suggest to split my document (which is odt by the way) into master/subdocument (where the subdocument would have to be odt anyway). The properties should be defined in the subdocument, so the odt (where I have them anyway). So remains the question how I would then update the variables or properties in the subdocument…

I was not clear enough. Your present document is turned into a master: it is the same as presently, except it doesn’t contain variable initialisation. The subdocument contains only variable definitions and initialisations. When you want to create a different version, you modify the variable values in the subdocument. Then you launch the master via CLI.

There is no solution for the properties.

I admit that my master+sub proposal doesn’t change your problem: you still have to change via GUI some document.

There could be an “acrobatic” and risky way to do it. Your document could be saved .fodt. This format is a non-compressed XML file which can be manipulated with CLI text editors like sed or macro-generators like awk. It is then possible to recognise the definition of properties and variables and substitute new values to the existing one. What you have to do is to write a bash script (or any scripting langage with regexp you feel comfortable with: Perl, Python, …).

2 Likes

Not really what I was after. But thanks for trying. :slight_smile: