Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

How can i get a template variable to substitute properly in a metadata macro <ac:plain-text-body> tag?

Tai Ngo June 18, 2015

Space Blueprints plugin content templates containing a metadata macro with plain text body cdata tags.  How can we substitute space dialog form variable values into a metadata macro plain text body section during space creation so that the resulting metadata macro shows the proper substituted value in the content template once they are all created?  <at:var at:name=”spaceKey” /> is an example template variable that substitutes properly inside an <ac:structured-macro><ac:parameter><at:var at:name=”spaceKey” /></ac:parameter></ac:structured-macro> tag.  For some reason, it does not work inside <ac:structured-macro><ac:plain-text-body><![CDATA[<at:var at:name=”spaceKey” />]]></ac:plain-text-body></ac:structured-macro> tag.

4 answers

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

0 votes
Tai Ngo September 18, 2015

Then...in your atlassian-plugin.xml configuration file, be sure to specify your CustomContextProvider JAVA file in the content template tag as i did:

<content-template key="project-metadata-template" i18n-name-key="confluence.blueprints.space.example.project.metadata.name">

    <description key="confluence.blueprints.space.example.project.metadata.desc"/>
    <resource name="template" type="download" location="/xml/project-metadata.xml"/>
    <context-provider class="com.charter.plugins.confluence.blueprints.CustomContextProvider" />
</content-template>

That should allow you to then use atlas-clean, atlas-compile, atlas-package commands from the command line to build and package your plugin to be installed manually and tested.

0 votes
Tai Ngo September 18, 2015

Any substitution that fails using the <at:var name="somename" /> method can be done using a JAVA based CustomContextProvider class that implements ContextProvider interface and overrides the getContextMap() method.  This is all java based code executed inside a space blueprint plugin or any other plugin that needs custom contexts injected into the context map.  Below is an exerpt of one i used:

 

package com.charter.plugins.confluence.blueprints;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

import java.util.Date;
import java.util.Map;

import com.atlassian.plugin.PluginParseException;
import com.atlassian.plugin.web.ContextProvider;

// Custom context provider class to add content variables to context templates in the plugin xml folder
// Any macro based variable should use the at:rawxhtml="true" attribute in the tag so the storage format will function
public class CustomContextProvider implements ContextProvider {
private static final Logger log = LogManager.getLogger("atlassian.plugin");

@Override
public void init(final Map<String, String> params) throws PluginParseException {
}

@Override
public Map<String,Object> getContextMap(final Map<String, Object> context) {

log.info("[BEGIN] [log4j initialized] [Project Space Blueprint:CustomContextProvider.java:getContextMap()]");

// begin standard content template context variables
String spaceKey = context.get("spaceKey").toString();
String projectIssueID = context.get("projectIssueID").toString();
context.put("creationDate", new Date());
// end standard content template context variables

// begin xml/raid.xml context template variables
String raidParentIssueID = projectIssueID;
String raidRequestID = context.get("raidRequestID").toString();
context.put("raidParentIssueID", projectIssueID);
context.put("raidRequestID", raidRequestID);

// begin not used currently due to hardcoded values in xml/raid.xml
//String raidIssueTypeID = context.get("raidIssueTypeID").toString();
//int raidIssueTypeIDInt = Integer.parseInt(raidIssueTypeID);
//int raidIssueTypeIDIntPlus1 = raidIssueTypeIDInt + 1;
//int raidIssueTypeIDIntPlus2 = raidIssueTypeIDInt + 2;
//int raidIssueTypeIDIntPlus3 = raidIssueTypeIDInt + 3;
//String raidIssueTypeIDPlus1 = String.valueOf(raidIssueTypeIDIntPlus1);
//String raidIssueTypeIDPlus2 = String.valueOf(raidIssueTypeIDIntPlus2);
//String raidIssueTypeIDPlus3 = String.valueOf(raidIssueTypeIDIntPlus3);
//context.put("raidIssueTypeID", raidIssueTypeID);
//context.put("raidIssueTypeIDPlus1", raidIssueTypeIDPlus1);
//context.put("raidIssueTypeIDPlus2", raidIssueTypeIDPlus2);
//context.put("raidIssueTypeIDPlus3", raidIssueTypeIDPlus3);
// end not used currently due to hardcoded values in xml/raid.xml

String raid1MacroXhtml = "<ac:structured-macro ac:name=\"sql-query\"><ac:parameter ac:name=\"id\">table-borders-all1</ac:parameter><ac:parameter ac:name=\"columnLabel\">true</ac:parameter><ac:parameter ac:name=\"macros\">true</ac:parameter><ac:parameter ac:name=\"sortColumn\">2</ac:parameter><ac:parameter ac:name=\"dataSource\">jiraDS</ac:parameter><ac:parameter ac:name=\"highlightColor\">#ecf2f8</ac:parameter><ac:parameter ac:name=\"columnAttributes\">,style=&quot;width:105px;&quot;,,,,,,,,,,,,style=&quot;width:110px;&quot;</ac:parameter><ac:parameter ac:name=\"class\">confluenceTable pdfexport</ac:parameter><ac:parameter ac:name=\"atlassian-macro-output-type\">INLINE</ac:parameter><ac:parameter ac:name=\"retainRowStyleOrder\">false</ac:parameter><ac:parameter ac:name=\"noDataMessage\">NO DATA - Either the field in the JIRA issue contains no data or the Project Metadata value is not filled in correctly.</ac:parameter><ac:plain-text-body><![CDATA[SELECT jiraissue.summary AS 'Risk',\n"
+ "CONCAT('<a href=\"https://jira.charter.com/browse/" + spaceKey + "-',jiraissue.issuenum,'\">" + spaceKey + "-',jiraissue.issuenum,'</a>') AS 'ID and Link',\n"
+ "CASE\n"
+ "WHEN priority.stringvalue = 17056 THEN 'P1'\n"
+ "WHEN priority.stringvalue = 17057 THEN 'P2'\n"
+ "WHEN priority.stringvalue = 17058 THEN 'P3'\n"
+ "ELSE '' END AS 'Priority',\n"
+ "CASE\n"
+ "WHEN impact.stringvalue = 17059 THEN CONCAT('{status:colour=red|title=High|subtle=true}')\n"
+ "WHEN impact.stringvalue = 17060 THEN CONCAT('{status:colour=yellow|title=Medium|subtle=true}')\n"
+ "WHEN impact.stringvalue = 17061 THEN CONCAT('{status:colour=blue|title=Low|subtle=true}')\n"
+ "ELSE '' END AS 'Impact', mitigation.textvalue AS 'Mitigation Strategy or Resolution',\n"
+ "functionalteam.stringvalue AS 'Functional Team',\n"
+ "CASE\n"
+ "WHEN DATEDIFF(jiraissue.duedate,CURDATE()) > 7 OR jiraissue.resolutiondate IS NOT NULL THEN DATE_FORMAT(jiraissue.duedate,'%b %d, %Y')\n"
+ "WHEN DATEDIFF(jiraissue.duedate,CURDATE()) > 0 AND DATEDIFF(jiraissue.duedate,CURDATE()) < 8 THEN CONCAT(DATE_FORMAT(duedate,'%b %d, %Y'),'<br />{status:color=yellow|title=Almost Due|subtle=true}')\n"
+ "WHEN DATEDIFF(jiraissue.duedate,CURDATE()) = 0 THEN CONCAT(DATE_FORMAT(duedate,'%b %d, %Y'),'<br />{status:color=yellow|title=Due Today}')\n"
+ "WHEN DATEDIFF(jiraissue.duedate,CURDATE()) < 0 THEN CONCAT(DATE_FORMAT(duedate,'%b %d, %Y'),'<br />{status:color=red|title=Past Due}')\n"
+ "END AS 'Date Needed',\n"
+ "CONCAT(DATEDIFF(CURDATE(),jiraissue.created),' days') AS Aging,\n"
+ "CONCAT(ownername.first_name,' ',ownername.last_name) AS 'Owner',\n"
+ "CASE\n"
+ "WHEN pname = 'New' THEN CONCAT('{status:colour=yellow|title=',pname,'}')\n"
+ "WHEN pname = 'In Progress' THEN CONCAT('{status:colour=blue|title=',pname,'}')\n"
+ "WHEN pname = 'Escalated' THEN CONCAT('{status:colour=red|title=',pname,'}')\n"
+ "WHEN pname = 'Resolved' THEN CONCAT('{status:colour=green|title=',pname,'}')\n"
+ "WHEN pname = 'Cancelled' THEN CONCAT('{status:colour=grey|title=',pname,'}')\n"
+ "END AS 'Status',\n"
+ "CASE\n"
+ "WHEN communicated.stringvalue = 17062 THEN 'Yes'\n"
+ "WHEN communicated.stringvalue = 17063 THEN 'No'\n"
+ "ELSE ''\n"
+ "END AS 'Comm',\n"
+ "CASE\n"
+ "WHEN realized.stringvalue = 17387 THEN 'Yes'\n"
+ "WHEN realized.stringvalue = 17388 THEN 'No'\n"
+ "ELSE ''\n"
+ "END AS 'Risk Realized',\n"
+ "DATE_FORMAT(jiraissue.resolutiondate,'%b %d, %Y') AS 'Resolution Date',\n"
+ "CONCAT('{tooltip:tip=',notes.textvalue,'}Hover for Notes{tooltip}') AS 'Notes'\n"
+ "FROM jiraissue\n"
+ "LEFT JOIN customfieldvalue priority ON priority.customfield=15815 AND jiraissue.id=priority.issue\n"
+ "LEFT JOIN customfieldvalue impact ON impact.customfield=15816 AND jiraissue.id=impact.issue\n"
+ "LEFT JOIN customfieldvalue mitigation ON mitigation.customfield=15817 AND jiraissue.id=mitigation.issue\n"
+ "LEFT JOIN customfieldvalue functionalteam ON functionalteam.customfield=15818 AND jiraissue.id=functionalteam.issue\n"
+ "LEFT JOIN customfieldvalue owner ON owner.customfield=14527 AND jiraissue.id=owner.issue\n"
+ "LEFT JOIN cwd_user ownername ON ownername.user_name=owner.stringvalue\n"
+ "LEFT JOIN customfieldvalue communicated ON communicated.customfield=15819 AND jiraissue.id=communicated.issue\n"
+ "LEFT JOIN customfieldvalue realized ON realized.customfield=16024 AND jiraissue.id=realized.issue\n"
+ "LEFT JOIN customfieldvalue notes ON notes.customfield=14530 AND jiraissue.id=notes.issue\n"
+ "LEFT JOIN issuestatus ON issuestatus.id=jiraissue.issuestatus AND jiraissue.issuetype=13110 AND jiraissue.PROJECT=(SELECT ID FROM project WHERE pkey='" + spaceKey + "')\n"
+ "WHERE jiraissue.issuetype=13110 AND jiraissue.PROJECT=(SELECT ID FROM project WHERE pkey='" + spaceKey + "');]]></ac:plain-text-body></ac:structured-macro>";

context.put("raid1MacroXhtml", raid1MacroXhtml);

log.info("[END] [log4j initialized] [Project Space Blueprint:CustomContextProvider.java:getContextMap()]");

// return the context
return context;
}

}

 

0 votes
Merijn de Jonge September 18, 2015

Did you find a solution yet?

0 votes
childnode
Contributor
June 20, 2015

you know what you do? XML: <![CDATA[]]>

perhaps http://stackoverflow.com/questions/2784183/what-does-cdata-in-xml-mean will answer what you are doing wrong wink Tip: remove the cdata encapsulation

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

TAGS
AUG Leaders

Atlassian Community Events