Can you use procedures/functions in a JSON variable declaration?

0 votes
asked Jan 17, 2022 in Question / help by Eric

I have data that I wish to use in two separate diagrams, and thus want to declare it independently of the two diagrams. Within this data, I also have many repeated strings and thus want to use a procedure or function to generate them.

My first approach was to create the JSON structure in a `@startjson/@endjson` block:

@startjson data (id=data)
!procedure $db($obj)
"Store $obj in database"
!endprocedure

{
    "name": "Example JSON",
    "todo": [
        $db("username"),
        $db("password")
    ]
}
@endjson

While this works to define and visualize the JSON data, I can't seem to access the data in another UML (`@startuml/@enduml`) block. Something like `!$myData = %loadJSON(myFile.puml!data)` doesn't work because it's expecting a normal JSON file. Something like `!include myFile.puml!data` just results in a syntax error in the UML block because the JSON is not being declared under a variable name. Adding a variable name to the JSON block above results in a JSON format error.

My second approach was then to define the JSON as a variable in a UML block instead, so that the block could be included by other UML blocks and reference the variable name:

@startuml example
!procedure $db($obj)
"Store $obj in database"
!endprocedure

!$myData = {
    "name": "Example JSON",
    "todo": [
        $db("username"),
        $db("password")
    ]
}
@enduml

This only resulted in a JSON format error whenever the procedure is used. I played with using a function instead, and with the resulting value being quoted or unquoted, but to no avail. I'd guess the format check is occurring before the procedure/function is evaluated (if it's evaluated at all).

Is there anyway to use procedures/functions in a JSON variable declaration to fix this second approach? More generally, is there a way to get the behavior I'm looking for?

1 Answer

0 votes
answered Feb 18, 2022 by kirchsth (4,880 points)

Why do you want to calculate/modify the Json at all and don't directly use the original json input and call the calculation functions direct in the diagram (and don't modify the json itself)? These calculation functions could be stored in a common file.
E.g. this link has samples/ideas with Json based models in combination with C4-PlantUML (which uses internal a lot of conversion functions)

@startuml
!include https://raw.githubusercontent.com/kirchsth/C4-PlantUML/extended/C4_Component.puml

AddPersonTag("teamred", $bgColor="#red", $legendText ="member of team red")
AddPersonTag("teamblue", $bgColor="#blue", $legendText ="member of team blue")

!$data={"partlen": "2", "game": "GamePlantuml", "participants": [
{"name": "XYZ" ,"as": "xyz", "team": "A", "persons": ["A1", "A2", "A3"] },
{"name": "RST" ,"as": "rst", "team": "B", "persons": ["B1", "B2" ]},
{"name": "UVW" ,"as": "uvw", "team": "B", "persons": ["B2", "B3" ]}],
"color": {"A": "red", "B": "blue"}
}

!foreach $part in $data.participants
  Component($part.name, $part.as, "techn")
  !foreach $member in $part.persons
    !$teamTag = "team"+$data.color[$part.team]
    Person($member, $member, $tags = $teamTag)
    Rel($member, $part.name, "develop")
  !endfor
!endfor

SHOW_LEGEND()
@enduml

BR Helmut

...