M2doc: How to use optional template variables


some variables in a m2doc template may be optional, i.e. when the template is used for certain models they need not be mapped to any model element at all. So, effectively, in such case their value would be null and thus it would be possible, using m:if, to control what is included in the m2doc template. So, depending on the model, such optional parts are present in the generated document or not without a need to have any definition of constant names of elements in the template itself which belong into the genconf. E.g. a diagram may not be present in the Capella model causing the corresponding chapter to be left out in the document.

However, it is not possible in the genconf to define null values for variables.

Does anybody have an idea how could this use case be implemented in m2doc?


Any feedback on this?

You could pass an element that is always present and navigate to the optional element an test its presence with an if statement:

{ m:if presentElement.nagivate.to.optional.element <> null }
{ m:endif }

or if the element should be in a list:

{ m:if presentElement.nagivate.to.optional.elements->size() <> 0 }
{ m:endif }

Yes, you’re right, this is possible (and we have been using it), but it is not enough:

… that means that the actual element should be defined in the genconf. No constant name strings etc. in the m2doc template (to be able to navigate to the optional element), because they would make it much less generic, it would be a hidden dependency not visible in the genconf. The main principle of m2doc, as I understand it, is to have generic templates which are applicable (via genconf) to Capelal models, right?

You can pass the String as a variable of the template:

{ m:if presentElement.nagivate.to.optional.element.name <> variable }
{ m:endif }

Then you can set the type of the variable as String in the template properties wizard.

Not sure your expression was meant but thank you for pointing at String as type of template variables, which I was not aware of. Then it is possible to have a String variable with undefined value, e.g. rootLDFBDiagramName:

m:let rootLDFBDiagram = if rootLDFBDiagramName.size() > 0 then rootLDFBDiagramName.representationByName() else null endif

However, when attempting to have a undefined variable of some type in the metamodel, this is not possible - the following statement generates an error during generation. It is not clear why only String variables may remain undefined.

m:let rootLDFBDiagramName= if rootLDFBDiagram <> null then rootLDFBDiagram.name else null endif


another alternative I have spotted: if a template variable is of type OrderedSet or Sequence, it should be possible to set it to an empty value in the genconf, thus achieving optionality, shouldn´t it. E.g. an empty OrderedSet(diagram::DSemanticDiagram) would mean there is no suitable diagram in the model to be used in the generated document. Another advantage is that one can set more than one diagrams to be included in the document, if the appropriate processing is uincluded in the template.

Some work has been done lately to support Sequence and OrderedSet of objects as parameters of a template, but unfortunately the genconf itself doesn’t support the definition of Sequence and OrderedSet variable binding. I opened an issue for that: