Changing a param value programmatically in a user macro
Asked by Brian Peters:

I'm writing a user macro (VTL) and want to programmatically change the value of an existing param (of type=string).

Problem is, I can't find any documentation indicating how to set the value of a param after the initial "## [@Param](/t5/user/viewprofilepage/user-id/1345631)..." definition (something like: $paramSomething.setValue("123") or $paramSomething.value = "123", etc.).

Anyone know how to do this?


Answers:
author: Nic Brough -Adaptavist-
body: Welcome to the Atlassian Community!

This is not really something you would ever want do with a parameter. A parameter is something that has been given to your code to tell it to do something. You're not supposed to ignore them, you might as well just not have parameters.

But if you re-cast the requirement as "do something based on some logic that looks at a parameter", then it makes perfect sense. Some really simple pseudocode:

For a really basic macro that just echoes the input:

```
$incomingParameter
```

But to prepare to do what you want:

```
#set ($mydata = $incomingParameter)
Output $mydata
```

And so you can see where I'm going with this:

```
#set ($mydata = $incomingParameter)
#if ( $mydata [contains bad words] )
? #set ($mydata = "no bad words allowed")
#endif
$mydata
```

comments: author: Brian Peters
body: Thanks for the quick reply and suggestion. I need my user to be able to pick a background color... and then need to programmatically change another parameter based on their selection so that the user can see it has changed. In other words, I need the change reflected back to the interface (otherwise they will perceive that it's broken). Is there no way to change the value of a parameter other than through user input on the interface?


author: Nic Brough -Adaptavist-
body: I think you might be confusing "parameter" with "variable" here.

A parameter (in computer speak) is a value you feed into a function or routine to give it some information to work with. It is not an output or result. It's not something you would change during a routine.

I'm English, so bear with my strained analogy - imagine making a pot of tea. The process needs parameters such as "amount of tea to put in pot", "type of tea", "how long to brew", "amount of water" and so-on.

None of those change as a result of making a pot of tea, they're purely inputs into the process. You might alter the process based on what you're given as parameters, but the parameters do not come out of the other end of the process, changed or intact.

So I am a little confused on what you are asking for when you say "change a parameter". A parameter only informs a specific process that takes it in. There's no point in changing it, it's not used outside or after that process run.

Anyway, that's me being fussy about how I'm not understanding your writing.

You also say "change reflected back to interface". That's nothing to do with parameters but does suggest that your macro should be doing something based on data fed into it.

Could you explain broadly what your macro is for? Forget the parameter/variable/etc stuff and explain roughly what the macro should be doing for your people?


author: Brian Peters
body: I am writing a User Macro for Confluence in the Velocity Template Language (because I can't figure out how to write it in anything else). In my user macro I have defined some named parameters, for example:

*** ** * ** ***

## [@Param](/t5/user/viewprofilepage/user-id/1345631) ButtonColor:title=Button Color\|type=enum\|enumValues=red,green,blue,white\|required=true\|desc=Choose a color for the button's background.\|default=green

## [@Param](/t5/user/viewprofilepage/user-id/1345631) ButtonTextColor:title=Button Text Color\|type=string\|required=false\|default=white\|desc=Enter a color for the button's text

... etc.

*** ** * ** ***

When the user adds the macro to a page these parameter definitions result in a dropdown and a text field on the edit pane.

I use the resulting values ($paramButtonColor and $paramButtonTextColor) in some CSS farther down in the script.

If the user selects white for the "Button Color" and enters nothing for "Button Text Color", I would like to programmatically change the "Button Text Color" field to say "gray". If they select any other color for "Button Color" and they still have not specified a "Button Text Color" I would like "Button Text Color" to show "white".

I could change the CSS with an "if" statement and some variables but my goal here is also to communicate to the user that "Button Text Color" is being changed based on their selection.

So, I'm looking for a method or something that will let me programmatically change the value of the text field created by the "@param ButtonTextColor" definition so that the new value is apparent to the person creating the button.

I've only been at this for a month or so and have already run into a couple instances where being able to change the value of one of these parameter fields on the macro's editor UI would be very useful. I'm new to VTL but not to coding and I can't imagine there's no way to control the UI (the Javascript equivalent would be something along the lines of: document.getElementById("ButtonTextColor").value = "white").


author: Brian Peters
body: I want to note that the macro ultimately produces a button on the page, but the user interface I am talking about here is the list of inputs shown when someone adds or edits the macro to specify the button characteristics.


author: Nic Brough -Adaptavist-
body: You keep talking about "changing parameters" which is something that would do precisely nothing. A parameter is a value fed into a routine at the time you use the routine and not used again, so there's no point changing it.

Again the tea analogy - you put tea leaves (the parameters are amount and type of tea) in a pot, you go through the process of steeping and pouring and end up with a cup of tea. Why are you trying to get the teapot to change the amount or type of tea partway through, or after?

I think I may be misunderstanding what you are looking for though. Could you explain a bit more? Maybe without using "parameters" or "inputs" type words, just run us through what you expect the macro to do for the users?


author: Brian Peters
body: I'm using the term "parameter" as described in the Atlassian documentation for User Macro Template Syntax (and trying to be a precise as possible in my description when choosing various terms):

<https://confluence.atlassian.com/doc/user-macro-template-syntax-223906130.html>

When trying to create a new button with my user macro, the user will set the value for various parameters, then use the "preview" feature to see how the resulting button looks. Most likely they will want to change something so they will change a few parameters (I have probably 10 parameters they can adjust such as: border width, font size, background color, etc.). Hopefully this makes more sense that the parameters will change during the editing session. I simply would like to change some of the parameters programmatically based on the user's selection of another parameter as described in my response above.


author: Nic Brough -Adaptavist-
body: Yes, they call them parameters because they are. The author selects or enters a parameter and that goes into the routine (macro) when it runs.

The process here is:

1. Author adds your macro to a page
2. They set the parameters for this instance of the macro on this page
3. Save it
4. When the page is rendered, the parameters are used to inform what the macro does.
5. Macro finishes execution, parameters are not used for anything else

I do not understand what you think changing a parameter will do or of what use it is.


author: Brian Peters
body: Ah, I think I see the confusion now. I'm only concerned about doing this *while* the author is setting the parameters for the button (or at least using the "preview") *not* after the page has rendered.

Optimally when the author sets the "Button Color" parameter, that change would trigger the "Button Text Color" field to change value.


author: Nic Brough -Adaptavist-
body: Oh, of course, now I see it, makes perfect sense now!

Thanks for spotting that and correcting me, I wasn't even thinking of that part of it, so I wasn't just "barking up the wrong tree", I was "barking in the wrong forest"!

So, I'm afraid the answer is a simple "no".

That dialog where the parameters is presented to the users is hard-coded. It reads from the ##@param line(s) at the beginning of the macro and throws up a simple list of them from a simple library of fields. There's nothing in there that would let you change those fields dynamically (the rest of the macro is only run when it is renderered, it's got no way to talk back to the dialog, even when it's previewed). It's too late to do anything with the dialog when its running.


author: Brian Peters
body: Well, that is truly disappointing, but I definitely appreciate you taking the time to understand what I was looking for.


Tags: confluence-server

server

user-macro

velocity