Uploaded image for project: 'Confluence Data Center'
  1. Confluence Data Center
  2. CONFSERVER-32426

Cannot add macro parameters programmatically in Confluence version gt 5.2

      From Confluence 5.3 onwards it's not possible any more to add macro parameters when calling MacroDefinition.setParameters inside a MacroDefinitionUpdater, when the xhtml-macro definition declares any parameters.

      MacroDefinitionUpdaters are used from:

          String body = xhtmlContent.updateMacroDefinitions(ceo.getBodyAsString(), conversionContext, new MacroDefinitionUpdater(){
      

      This problem appears as soon as the macro has a parameter defined like

          <xhtml-macro name="macro-test" class="test.TestMacro" key="macroTest">
              <parameters>
                  <parameter name="name" type="string" required="true"/>
      ....
      

      Even if I add a placeholder in the macro definition for parameter I want updated, it is not added. Works in Confluence 4.3 - 5.2.

      Cause

      Confluence 5.3 now tries to maintain some structured values for macro params inside a new ac:structured-macro element. The storage macro marshaller for this element treats the MacroDefinition.typedParameters property as canonical in this case, and it only consults the (untyped) parameters property if the typedParameters property is null or empty.

      As of Confluence 5.8, the types of typedParameters values can be one of:

      • for xhtml-macro declared parameter type "username": UserResourceIdentifier
      • for "spacekey": SpaceResourceIdentifier
      • for "confluence-content": Link to a ResourceIdentifier
      • for "url": UrlResourceIdentifier
      • for "attachment": AttachmentResourceIdentifier
      • for "full_attachment" (new in 5.6.5 and 5.7): AttachmentResourceIdentifier, fully qualified with the containing page/blog post and spacekey
      • otherwise: String

      Right now, too many property types are still treated as strings for the typedParameters map to be a permanent replacement. Longer term, the parameters property will be deprecated, and callers will need to migrate to using the typedParameters API.

      Note also that handling for the default parameter is now also different: it is stored keyed by the empty string (""), rather than as a separate property. This applies to both the typedParameters and parameters properties.

      Workarounds

      For all of the workarounds below, you will need to define the macro parameter correctly in your xhtml-macro definition. You cannot rely on your parameter being parsed and stored safely without this. You can mark this parameter as hidden if you do not want it to show up in the macro editor.

      1. Update the MacroDefinition.typedParameters property to hold the value you want to add/update, using the types as described above. This is the safest and most forwards compatible option. OR
      2. Build a fresh MacroDefinition with the MacroDefinitionBuilder containing just the properties you want stored. This option risks shearing off additional attributes the Confluence internals want to store. OR
      3. Null the typedParameters, to force the persistence code to fall back to using the old parameters property instead. Note that this option may cause page, blog and attachment links to break again, due to the problems with wikimarkup special characters.

      Fix

      We could add a way of tracking if the MacroDefinition.parameters property was modified while invoking any of the XhtmlContent macro methods, and if so use it to persist the macro params instead of the typed parameters. Note that this may cause page, blog and attachment links to break again, due to the problems with wikimarkup special characters

            [CONFSERVER-32426] Cannot add macro parameters programmatically in Confluence version gt 5.2

            Atlassian Update - 27 March 2025

            Hi,

            At Atlassian, our goal is to ensure we’re providing the best experience for our customers. With our new Data Center strategy, Atlassian's focus is on security, compliance, and performance and is a key driver in prioritizing bugs. Closing the bugs that do not fall into those categories will allow us to focus on the ones in the most current versions of our products.

            This bug is being closed due to a lack of engagement in the last four years, including no new watchers, votes, or comments; this inactivity suggests a low impact.

            Please note the comments on this thread are not being monitored.

            You can read more about our bug fix policy here and how we prioritize bugs.

            To learn more about our recent investments in Confluence Data Center, please check our public roadmap and dashboards containing recently resolved issues, current work, and future plans.

            Kind regards,
            Confluence Data Center

            George Varghese added a comment - Atlassian Update - 27 March 2025 Hi, At Atlassian, our goal is to ensure we’re providing the best experience for our customers. With our new Data Center strategy, Atlassian's focus is on security, compliance, and performance and is a key driver in prioritizing bugs. Closing the bugs that do not fall into those categories will allow us to focus on the ones in the most current versions of our products. This bug is being closed due to a lack of engagement in the last four years , including no new watchers, votes, or comments; this inactivity suggests a low impact. Please note the comments on this thread are not being monitored. You can read more about our bug fix policy here and how we prioritize bugs. To learn more about our recent investments in Confluence Data Center, please check our public roadmap and dashboards containing recently resolved issues , current work, and future plans . Kind regards, Confluence Data Center

            alexander.baggett I can't give specific example code right now, but I hope my updates to the description are helpful, all the same.

            Richard Atkins added a comment - alexander.baggett I can't give specific example code right now, but I hope my updates to the description are helpful, all the same.

            Can you give some sample code?

            Alexander Baggett added a comment - Can you give some sample code?

            @mjensen - thanks, we're good for now.

            Ulrich Kuhnhardt [Comalatech] added a comment - @mjensen - thanks, we're good for now.

            ulrich1 - do you now have enough information to work around this change or is there something else we can help with?

            m@ (Inactive) added a comment - ulrich1 - do you now have enough information to work around this change or is there something else we can help with?

            Thanks Richard for the great update. That also explains why adding a parameter (not a typed parameter) to a macro without any pre-existing parameters worked.

            Ulrich Kuhnhardt [Comalatech] added a comment - Thanks Richard for the great update. That also explains why adding a parameter (not a typed parameter) to a macro without any pre-existing parameters worked.

            Hi ulrich1,

            The short answer is the MacroDefinition.parameters map is no longer canonical for what Confluence will save - you need to modify the MacroDefinition.typedParameters map instead, or create a new instance with the updated parameter and value you want to store.

            If the macro you're trying to modify was loaded and running last time Confluence saved it, it's been written to storage format as a ac:structured-macro. When this is parsed, Confluence will set the MacroDefinition.storageVersion to 2, populate the MacroDefinition.typedParameters property with the up to date values (using objects where it can parse the parameter into a structured type), and generate the MacroDefinition.parameters string values from these.

            When saving a macro, Confluence decides how to save it based on whether it can load its metadata, and it saves its parameters by serializing its typedParameters map. If that map is empty or null, only then will Confluence attempt to save from the values in the parameters map (converting these to match the types in their macro metadata from the xhtml-macro module definition).

            As of this date (approaching 5.5), the typeParameters map values can contain Strings, various types of ResourceIdentifiers, or Links containing ResourceIdentifiers. If the parameter isMultiple, then it will contain an Iterator of one of these. The set of types parsed is managed via MacroParameterTypeParserImpl.

            I'd like to include structure parameter support for Dates, booleans and integers in the future, but that much wasn't necessary to get content and user rename support working, so was left out of the change that shipped in 5.3. This followup work is not currently scheduled, however, so you're unlikely to see further churn in this area for some months yet.

            Richard Atkins added a comment - Hi ulrich1 , The short answer is the MacroDefinition.parameters map is no longer canonical for what Confluence will save - you need to modify the MacroDefinition.typedParameters map instead, or create a new instance with the updated parameter and value you want to store. If the macro you're trying to modify was loaded and running last time Confluence saved it, it's been written to storage format as a ac:structured-macro. When this is parsed, Confluence will set the MacroDefinition.storageVersion to 2, populate the MacroDefinition.typedParameters property with the up to date values (using objects where it can parse the parameter into a structured type), and generate the MacroDefinition.parameters string values from these. When saving a macro, Confluence decides how to save it based on whether it can load its metadata, and it saves its parameters by serializing its typedParameters map. If that map is empty or null, only then will Confluence attempt to save from the values in the parameters map (converting these to match the types in their macro metadata from the xhtml-macro module definition). As of this date (approaching 5.5), the typeParameters map values can contain Strings, various types of ResourceIdentifiers, or Links containing ResourceIdentifiers. If the parameter isMultiple, then it will contain an Iterator of one of these. The set of types parsed is managed via MacroParameterTypeParserImpl. I'd like to include structure parameter support for Dates, booleans and integers in the future, but that much wasn't necessary to get content and user rename support working, so was left out of the change that shipped in 5.3. This followup work is not currently scheduled, however, so you're unlikely to see further churn in this area for some months yet.

              Unassigned Unassigned
              10058912f876 Ulrich Kuhnhardt [Comalatech]
              Affected customers:
              4 This affects my team
              Watchers:
              10 Start watching this issue

                Created:
                Updated:
                Resolved: