Commits

Theresa Henze committed 162940b Draft

Extended tutorial sources with hillsite macro

  • Participants
  • Parent commits 9be7765

Comments (0)

Files changed (26)

 
 ### Formatting
 
-todo
+WIP
 
 
 ### Insert Menu
 
 Done
+Note: Set icon with CSS instead with web-item icon
 
 
 ## Macros
 
+TODO: Icon, documentationURL, categories
+
 ### Insert with custom GUI
 
 Done
 Done
 
 
-### Macro Parameters (name/value presentation)
+### Macro Parameters
+
+#### Types
+
+TODO: single values, multiple, 
+
+
+#### Name/Value presentation
 
 Done
 
 
+#### Hidden Parameters
+
+Done
+
+
 ### Image place holder
 
-todo
+TODO
+
+
+## I18N
+
+TODO
+
+Description for the macro (Will be displayed in macro browser list)
+    [PLUGINKEY].[MACROKEY].desc = macro description
+Name for the macro (Will be displayed in macro browser list)
+    [PLUGINKEY].[MACROKEY].label = macro name
+Description for macro body
+    [PLUGINKEY].[MACROKEY].body.desc = macro body description
+Name for the macro body
+    [PLUGINKEY].[MACROKEY].body.label = macro body name 
+Description for the macro parameter (Will be displayed in macro browser in macro view)
+    [PLUGINKEY].[MACROKEY].param.[PARAMETER_NAME].desc = macro parameter description
+Name for the macro parameter (Will be displayed in macro browser in macro view)
+   [PLUGINKEY].[MACROKEY].param.[PARAMETER_NAME].label = macro parameter name
+
 
 
 # Helpful Links #
 
 * [http://www.slideshare.net/GoAtlassian/pimp-my-confluence-plugin-atlascamp-2011](http://www.slideshare.net/GoAtlassian/pimp-my-confluence-plugin-atlascamp-2011)
 
+
+# License
+
+All graphics used in this plugin were publisher under GNU Lesser General Public License on [http://www.openwebgraphics.com](http://www.openwebgraphics.com).
+
+
 ***
 
 *This guide was created during work at [//SEIBERT/MEDIA](http://www.seibert-media.net)*

File src/main/java/com/example/plugin/confluence/HillsiteMacro.java

+package com.example.plugin.confluence;
+
+import java.util.Map;
+
+import org.apache.velocity.VelocityContext;
+
+import com.atlassian.confluence.content.render.xhtml.ConversionContext;
+import com.atlassian.confluence.content.render.xhtml.DefaultConversionContext;
+import com.atlassian.confluence.macro.Macro;
+import com.atlassian.confluence.macro.MacroExecutionException;
+import com.atlassian.confluence.renderer.radeox.macros.MacroUtils;
+import com.atlassian.confluence.util.velocity.VelocityUtils;
+import com.atlassian.renderer.RenderContext;
+import com.atlassian.renderer.v2.RenderMode;
+import com.atlassian.renderer.v2.macro.BaseMacro;
+import com.atlassian.renderer.v2.macro.MacroException;
+
+/**
+ * Creates a hillsite macro.
+ */
+public class HillsiteMacro extends BaseMacro implements Macro {
+
+	private final String BOX_TEMPLATE = "vm/macro-hillsite.vm";
+
+	@SuppressWarnings("rawtypes")
+	@Override
+	public String execute(final Map params, final String body, final RenderContext renderContext) throws MacroException {
+		VelocityContext contextMap = new VelocityContext(MacroUtils.defaultVelocityContext());
+		return VelocityUtils.getRenderedTemplate(BOX_TEMPLATE, contextMap);
+	}
+
+	@Override
+	public String execute(final Map<String, String> params, final String body, final ConversionContext cc)
+			throws MacroExecutionException {
+		try {
+			DefaultConversionContext defaultConversionContext = (DefaultConversionContext) cc;
+			RenderContext renderContext = defaultConversionContext.getPageContext();
+			return execute(params, body, renderContext);
+		}
+		catch (MacroException e) {
+			throw new MacroExecutionException(e);
+		}
+	}
+
+	@Override
+	public BodyType getBodyType() {
+		return BodyType.NONE;
+	}
+
+	@Override
+	public OutputType getOutputType() {
+		return OutputType.BLOCK;
+	}
+
+	@Override
+	public boolean isInline() {
+		return false;
+	}
+
+	@Override
+	public boolean hasBody() {
+		return false;
+	}
+
+	@Override
+	public RenderMode getBodyRenderMode() {
+		return RenderMode.ALL;
+	}
+
+	@Override
+	public boolean suppressMacroRenderingDuringWysiwyg() {
+		return true;
+	}
+
+	@Override
+	public boolean suppressSurroundingTagDuringWysiwygRendering() {
+		return false;
+	}
+}

File src/main/resources/atlassian-plugin.xml

-<atlassian-plugin key="${project.groupId}.${project.artifactId}" name="${project.name}" plugins-version="2">
-    <plugin-info>
-        <description>${project.description}</description>
-        <version>${project.version}</version>
-        <vendor name="${project.organization.name}" url="${project.organization.url}" />
-        <param name="plugin-icon">images/pluginIcon.png</param>
-        <param name="plugin-logo">images/pluginLogo.png</param>
-    </plugin-info>
+<atlassian-plugin key="${project.groupId}.${project.artifactId}"
+	name="${project.name}" plugins-version="2">
+	<plugin-info>
+		<description>${project.description}</description>
+		<version>${project.version}</version>
+		<vendor name="${project.organization.name}" url="${project.organization.url}" />
+		<param name="plugin-icon">images/16x16_package.png</param>
+		<param name="plugin-logo">images/64x64_package.png</param>
+	</plugin-info>
 
-    <!-- add our i18n resource -->
-    <resource type="i18n" name="i18n" location="macromagic"/>
-    
-    <resource type="download" name="images/" location="images">
-        <param name="content-type" value="image/png"/>
-    </resource>
-    
-	<xhtml-macro name="box" class="com.example.plugin.confluence.BoxMacro" key="box-xhtml">
-	    <!-- icon="/images/box-icon.png" documentation-url="" -->
-		<category name="confluence-content" />
+	<resource type="i18n" name="i18n" location="macromagic">
+		<description>I18n resource</description>
+	</resource>
+
+	<resource type="download" name="images/" location="images">
+		<description>Image resource</description>
+		<param name="content-type" value="image/png" />
+	</resource>
+
+	<web-item key="editor-awesome-format" name="AwesomeFormat"
+		section="system.editor.more.formats" weight="10">
+		<description>Custom format in editor menu</description>
+		<label key="com.example.plugin.confluence.macromagic.customformat" />
+		<link linkId="my-awesome-format" />
+	</web-item>
+
+	<xhtml-macro name="box" class="com.example.plugin.confluence.BoxMacro"
+		key="box-xhtml"
+		icon="/download/resources/com.example.plugin.confluence.macromagic/images/64x64_package.png">
+		<!-- documentation-url="" -->
+		<description>Little boxes ... or big ones</description>
+
+		<!-- Select a category to which the macro belongs -->
+		<category name="visuals" />
+
+		<!-- The parameters node is REQUIRED, but may be empty -->
 		<parameters>
 			<default>
-			    <option key="showValueInPlaceholder" value="true"/>
+				<option key="showValueInPlaceholder" value="true" />
 			</default>
+
+			<parameter name="willbehidden" type="string" />
+
+			<!-- type: one of (string, boolean, enum, int, relativedate, url, color, 
+				label, date, username, group, confluence-content, spacekey) -->
 			<parameter name="size" type="enum" required="true" default="small">
 				<value name="small" />
 				<value name="medium" />
 				<value name="large" />
-				<option key="showKeyInPlaceholder" value="false"/>
-				<option key="showValueInPlaceholder" value="true"/>
+
+				<!-- display mode for parameter key/value -->
+				<option key="showKeyInPlaceholder" value="false" />
+				<option key="showValueInPlaceholder" value="true" />
 			</parameter>
 			<parameter name="title" type="string">
-				<option key="showKeyInPlaceholder" value="false"/>
-				<option key="showValueInPlaceholder" value="true"/>
-			</parameter>
-			<parameter name="newTab" type="boolean"> 
-				<option key="showKeyInPlaceholder" value="false"/>
-				<option key="showValueInPlaceholder" value="true"/>
+
+				<!-- aliases for parameter -->
+				<alias name="" />
+				<alias name="name" />
+
+				<!-- display mode for parameter key/value -->
+				<option key="showKeyInPlaceholder" value="false" />
+				<option key="showValueInPlaceholder" value="true" />
 			</parameter>
 		</parameters>
+
+		<!-- Additional option buttons in editor between 'edit' and 'remove' -->
 		<property-panel>
-		    <spacer/>
-		    <button id="Small" label="S"/>
-		    <button id="Medium" label="M"/>
-		    <button id="Large" label="L"/>
-		    <spacer/>
+			<spacer />
+			<button id="Small" label="S" />
+			<button id="Medium" label="M" />
+			<button id="Large" label="L" />
+			<spacer />
 		</property-panel>
 	</xhtml-macro>
-	
-	<!-- This is the legacy definition for the same macro for Confluence <= 3.x. We need it to have the macro work within wiki-markup like {box}..{box} -->
-	<macro name="box" class="com.example.plugin.confluence.BoxMacro" key="box">
-		<category name="confluence-content" />
+
+	<macro name="box" class="com.example.plugin.confluence.BoxMacro"
+		key="box">
+		<description>This is the legacy definition for the same macro for
+			Confluence less or equal 3.x. We need it to have the macro work
+			within wiki-markup like {box}..{box}
+		</description>
+		<category name="visuals" />
 		<parameters>
 			<parameter name="size" type="enum" required="true" default="small">
 				<value name="small" />
 				<value name="medium" />
 				<value name="large" />
 			</parameter>
-			<parameter name="title" type="string" />
+			<parameter name="title" type="string">
+				<alias name="" />
+				<alias name="name" />
+			</parameter>
 			<parameter name="newTab" type="boolean" />
 		</parameters>
 	</macro>
-	
-    <web-item key="editor-featured-macro-box-item" name="Insert Menu Link - Box Macro" section="system.editor.featured.macros.default" weight="11">
-        <description>Displays an insert box macro link in the tinymce insert menu</description>
-        <label key="com.example.plugin.confluence.macromagic.box.label">Box</label>
-        <link linkId="box"/>
-		<icon height="16" width="16">
-		    <!-- icon als css angeben -->
-		    <link>/images/sm-plugin-logo.png</link>
-		</icon>
-    </web-item>
 
-    <web-resource name="Box Resources" key="macroeditor-resources">
-        <context>editor</context>
-        <!-- <dependency>com.atlassian.confluence.tinymceplugin:editor-resources</dependency>-->
-        <resource type="download" name="editor-resource.js" location="js/editor-resource.js"/>
-    </web-resource>
-    
+	<xhtml-macro name="hillsite"
+		class="com.example.plugin.confluence.HillsiteMacro" key="hillsite-xhtml"
+		icon="/download/resources/com.example.plugin.confluence.macromagic/images/64x64_image.png">
+		<!-- documentation-url="" -->
+		<description>Nice hillsite to relax</description>
+
+		<!-- Select a category to which the macro belongs -->
+		<category name="visuals" />
+
+		<!-- The parameters node is REQUIRED, but may be empty -->
+		<parameters />
+	</xhtml-macro>
+
+	<macro name="hillsite" class="com.example.plugin.confluence.HillsiteMacro"
+		key="hillsite">
+		<description>This is the legacy definition for the same macro for
+			Confluence less or equal 3.x. We need it to have the macro work
+			within wiki-markup like {hillsite}
+		</description>
+		<category name="visuals" />
+		<parameters />
+	</macro>
+
+	<web-item name="menu-link" key="editor-featured-macro-box-item"
+		section="system.editor.featured.macros.default" weight="11">
+		<description>Displays an insert box macro link in the tinymce insert
+			menu
+		</description>
+		<label key="com.example.plugin.confluence.macromagic.box.label">Box</label>
+		<link linkId="box" />
+	</web-item>
+
+	<web-resource name="Box Resource - handle macro with JS"
+		key="macroeditor-box-resources">
+		<description>Box macro related JS resource</description>
+		<context>editor</context>
+		
+		<!-- JS to set properties S,M,L on box macro -->
+		<resource type="download" name="editor-box.js" location="js/editor-box.js" />
+
+		<!-- JS for custom macro gui without using macro browser (for hillsite 
+			macro) -->
+		<resource type="download" name="editor-hillsite.js" location="js/editor-hillsite.js" />
+
+		<!-- JS to insert format in editor -->
+		<resource type="download" name="editor-format.js" location="js/editor-format.js" />
+	</web-resource>
+
+	<web-resource name="Box Resource - add a hidden field"
+		key="hidden-field-parameter">
+		<description>Hide parameter field in box macro</description>
+		<resource type="download" name="hidden-parameter.js"
+			location="js/hidden-parameter.js" />
+		<dependency>confluence.editor.actions:editor-macro-browser
+		</dependency>
+		<context>macro-browser</context>
+	</web-resource>
+
+	<web-resource name="CSS Resource" key="css-resources">
+		<description>CSS resource for all macros</description>
+		<context>editor</context>
+		<resource type="download" name="macromagic.css" location="css/macromagic.css" />
+	</web-resource>
+
 </atlassian-plugin>

File src/main/resources/css/macromagic.css

+#insert-menu .aui-dropdown #insert-macro-box .icon {
+	background-image: url(images/16x16_package.png);
+	background-position: left center;
+	background-repeat: no-repeat;
+}

File src/main/resources/images/128x128_image.png

Added
New image

File src/main/resources/images/129x129_package.png

Added
New image

File src/main/resources/images/16x16_image.png

Added
New image

File src/main/resources/images/16x16_package.png

Added
New image

File src/main/resources/images/22x22_image.png

Added
New image

File src/main/resources/images/24x24_image.png

Added
New image

File src/main/resources/images/32x32_image.png

Added
New image

File src/main/resources/images/32x32_package.png

Added
New image

File src/main/resources/images/48x48_image.png

Added
New image

File src/main/resources/images/48x48_package.png

Added
New image

File src/main/resources/images/64x64_image.png

Added
New image

File src/main/resources/images/64x64_package.png

Added
New image

File src/main/resources/images/hillsite.jpg

Added
New image

File src/main/resources/images/pluginIcon.png

Removed
Old image

File src/main/resources/images/pluginLogo.png

Removed
Old image

File src/main/resources/js/editor-box.js

+(function() {
+
+	var macroName = 'box';
+	
+    /**
+     * Resolves the macro body content.
+     * 
+     * serialize() to ensure that any bogus tinymce tags + dirty browser markup are cleaned up.
+     * macro node should be cloned before serialization, as we don't want serialization tampering with the actual DOM element.
+     * 
+     * Note: we handle with DOM nodes here, not jQuery objects!
+     */
+	var getMacroBody = function(macroDiv) {
+        var macroBodyNode = AJS.$("td.wysiwyg-macro-body", macroDiv).clone()[0];
+        var macroBodyHtml = AJS.Rte.getEditor().serializer.serialize(macroBodyNode, {
+        	forced_root_block: false // Prevent serialize from wrapping in a <p></p>
+        });
+        return macroBodyHtml;
+	}
+	
+	/**
+	 * get current parameters and split them into a nice object
+	 */ 
+	var getCurrentParams = function(macroDiv) {
+        var currentParams = {};
+        if (macroDiv.attr("data-macro-parameters")) {
+            AJS.$.each(macroDiv.attr("data-macro-parameters").split("|"), function(idx, item) {
+                var param = item.split("=");
+                currentParams[param[0]] = param[1];
+            });
+        }
+        return currentParams;
+	}
+	
+	/**
+	 * Update macro parameter/body
+	 */
+    var updateMacro = function(macroId, macroNode, macroParam, param) {
+        var $macroDiv = AJS.$(macroNode);
+        
+        // celect current macro
+        AJS.Rte.getEditor().selection.select($macroDiv[0]);
+        
+        //  Stores the currently selected range and scroll position of the editor
+        AJS.Rte.BookmarkManager.storeBookmark();
+
+        // get/set parameters and body of macro
+        var currentParams = getCurrentParams($macroDiv);
+        currentParams[macroParam] = param;
+        var macroBody = getMacroBody($macroDiv);
+        
+        // create macro request object
+        var macroRenderRequest = {
+            contentId: Confluence.Editor.getContentId(),
+            macro: {
+                name: macroId,
+                params: currentParams,
+                defaultParameterValue: "",
+                body : macroBody
+            }
+        };
+
+        // insert new macro content
+        tinymce.confluence.MacroUtils.insertMacro(macroRenderRequest);
+    };
+
+    /*
+     * Note to myself: This means, that two macros having the same options
+     * will have to be treated with caution to not overwrite them with each others content???
+     * TODO: check this
+     */
+    
+    // register handlers for different option buttons 
+    AJS.Confluence.PropertyPanel.Macro.registerButtonHandler("Small", function(e, macroNode) {
+        updateMacro(macroName, macroNode, "size", "small");
+    });
+    AJS.Confluence.PropertyPanel.Macro.registerButtonHandler("Medium", function(e, macroNode) {
+        updateMacro(macroName, macroNode, "size", "medium");
+    });
+    AJS.Confluence.PropertyPanel.Macro.registerButtonHandler("Large", function(e, macroNode) {
+        updateMacro(macroName, macroNode, "size", "large");
+    });
+ 
+})();

File src/main/resources/js/editor-format.js

+// bind on initialization of editor
+AJS.bind("init.rte", function() { 
+	$("#my-awesome-format").click(function() {
+		/* execCommand
+	 	 * c = Command to perform for example Bold.
+		 * u = Optional boolean state if a UI should be presented for the command or not.
+		 * v = Optional value parameter like for example an URL to a link.
+		 * 
+		 * How to set a CSS class for that???
+		 */
+		tinymce.activeEditor.execCommand("FormatBlock", false, "span");
+	});
+}); 

File src/main/resources/js/editor-hillsite.js

+// bind on initialization of editor
+AJS.bind("init.rte", function() { 
+	
+	var macroName = 'hillsite';
+	
+	// create dialog to add macro
+	var dialog = new AJS.Dialog(400, 320);
+	
+	// hide dialog
+	dialog.addCancel("Cancel", function() {
+		dialog.hide();
+	});
+	
+	// add macro to editor
+	dialog.addSubmit("Create Macro", function() {
+
+		// get current selection in editor
+		var selection = AJS.Rte.getEditor().selection.getNode();
+		var macro = {
+				name: macroName
+// we don't have parameters or a body
+//				params: {
+//					title: 'some title'
+//				},
+//              defaultParameterValue: "",
+//				body: ''
+		};
+		
+		// convert macro and insert in DOM
+		tinymce.plugins.Autoconvert.convertMacroToDom(macro, function(data, textStatus, jqXHR ) {
+			AJS.$(selection).html(data + "<p><br/></p>");
+		}, function(jqXHR, textStatus, errorThrown ) {
+			AJS.log("error converting macro to DOM");
+		});
+		dialog.hide();
+	});
+	
+	// bind event to open macro browser
+	AJS.MacroBrowser.setMacroJsOverride(macroName, {opener: function(macro) {
+		// instead open dialog
+        dialog.show();
+		AJS.log(macro);
+	}});
+}); 

File src/main/resources/js/editor-resource.js

-(function() {
-
-    /**
-     * Resolves the macro body content.
-     * 
-     * serialize() to ensure that any bogus tinymce tags + dirty browser markup are cleaned up.
-     * macro node should be cloned before serialization, as we don't want serialization tampering with the actual DOM element.
-     * 
-     * Note: we handle with DOM nodes here, not jQuery objects!
-     */
-	var getMacroBody = function(macroDiv) {
-        var macroBodyNode = AJS.$("td.wysiwyg-macro-body", macroDiv).clone()[0];
-        var macroBodyHtml = AJS.Rte.getEditor().serializer.serialize(macroBodyNode, {
-        	forced_root_block: false // Prevent serialize from wrapping in a <p></p>
-        });
-        return macroBodyHtml;
-	}
-	
-	/**
-	 * get current parameters and split them into a nice object
-	 */ 
-	var getCurrentParams = function(macroDiv) {
-        var currentParams = {};
-        if (macroDiv.attr("data-macro-parameters")) {
-            AJS.$.each(macroDiv.attr("data-macro-parameters").split("|"), function(idx, item) {
-                var param = item.split("=");
-                currentParams[param[0]] = param[1];
-            });
-        }
-        return currentParams;
-	}
-	
-	/**
-	 * Update macro parameter/body
-	 */
-    var updateMacro = function(macroName, macroParam, macroNode, param) {
-        var $macroDiv = AJS.$(macroNode);
-        
-        // celect current macro
-        AJS.Rte.getEditor().selection.select($macroDiv[0]);
-        
-        //  Stores the currently selected range and scroll position of the editor
-        AJS.Rte.BookmarkManager.storeBookmark();
-
-        // get/set parameters and body of macro
-        var currentParams = getCurrentParams($macroDiv);
-        currentParams[macroParam] = param;
-        var macroBody = getMacroBody($macroDiv);
-        
-        // create macro request object
-        var macroRenderRequest = {
-            contentId: Confluence.Editor.getContentId(),
-            macro: {
-                name: macroName,
-                params: currentParams,
-                defaultParameterValue: "",
-                body : macroBody
-            }
-        };
-
-        // insert new macro content
-        tinymce.confluence.MacroUtils.insertMacro(macroRenderRequest);
-    };
-
-    /*
-     * Note to myself: This means, that two macros having the same options
-     * will have to be treated with caution to not overwrite them with each others content???
-     */
-    
-    // register handlers for different option buttons 
-    AJS.Confluence.PropertyPanel.Macro.registerButtonHandler("Small", function(e, macroNode) {
-        updateMacro("box", "size", macroNode, "small");
-    });
-    AJS.Confluence.PropertyPanel.Macro.registerButtonHandler("Medium", function(e, macroNode) {
-        updateMacro("box", "size", macroNode, "medium");
-    });
-    AJS.Confluence.PropertyPanel.Macro.registerButtonHandler("Large", function(e, macroNode) {
-        updateMacro("box", "size", macroNode, "large");
-    });
- 
-})();
-
-
-// bind on initialization of editor
-AJS.bind("init.rte", function() { 
-	
-	// create dialog to add macro
-	var dialog = new AJS.Dialog(400, 320);
-	
-	// hide dialog
-	dialog.addCancel("Cancel", function() {
-		dialog.hide();
-	});
-	
-	
-	// add macro to editor
-	dialog.addSubmit("Create Macro", function() {
-
-		// get current selection in editor
-		var selection = AJS.Rte.getEditor().selection.getNode();
-		var macro = {
-				name: 'box', 
-				params: {
-					size: 'small',
-					title: 'TEST'
-				},
-                defaultParameterValue: "",
-				body: 'warg'
-		};
-		
-		// convert macro and insert in DOM
-		tinymce.plugins.Autoconvert.convertMacroToDom(macro, function(data, textStatus, jqXHR ) {
-			AJS.$(selection).html(data);
-		}, function(jqXHR, textStatus, errorThrown ) {
-			AJS.log("error converting macro to DOM");
-		});
-		dialog.hide();
-	});
-	
-	// bind event to open macro browser
-	AJS.MacroBrowser.setMacroJsOverride('box', {opener: function() {
-		// instead open dialog
-        dialog.show();
-	}})
-}); 

File src/main/resources/js/hidden-parameter.js

+AJS.MacroBrowser.getMacroJsOverride("box").fields.string = {
+  "willbehidden": function(param) {
+    var parameterField = AJS.MacroBrowser.ParameterFields["_hidden"] (param, {});
+    if (!parameterField.getValue()) {
+      parameterField.setValue('hidden field value');
+    }
+    return parameterField;
+  }
+};

File src/main/resources/macromagic.properties

+# [PLUGINKEY].[MACROKEY].desc = Description for the macro (Will be displayed in macro browser list)
+# [PLUGINKEY].[MACROKEY].label = Name for the macro (Will be displayed in macro browser list)
+# [PLUGINKEY].[MACROKEY].body.desc = Description for macro body
+# [PLUGINKEY].[MACROKEY].body.label = Name for the macro body
+# [PLUGINKEY].[MACROKEY].param.[PARAMETER_NAME].desc = Description for the macro parameter (Will be displayed in macro browser in macro view)
+# [PLUGINKEY].[MACROKEY].param.[PARAMETER_NAME].label = Name for the macro parameter (Will be displayed in macro browser in macro view)
+
 com.example.plugin.confluence.macromagic.box.desc                   = Macro for adding a box.
 com.example.plugin.confluence.macromagic.box.label                  = Box
-com.example.plugin.confluence.macromagic.box.param.newTab.label     = Open link in new tab/window (subject to the settings of your browser).
+com.example.plugin.confluence.macromagic.box.body.desc              = Content of the box element
+com.example.plugin.confluence.macromagic.box.body.label             = Box content
 com.example.plugin.confluence.macromagic.box.param.size.label       = Box size
-com.example.plugin.confluence.macromagic.box.param.title.label      = Title
+com.example.plugin.confluence.macromagic.box.param.title.label      = Title
+
+com.example.plugin.confluence.macromagic.customformat 				= Pull into box
+
+com.example.plugin.confluence.macromagic.hillsite.desc              = Nice relaxing hillsite.
+com.example.plugin.confluence.macromagic.hillsite.label             = Hillsite

File src/test/resources/atlassian-plugin.xml

-<atlassian-plugin key="${project.groupId}.${project.artifactId}-tests" name="${project.name}" plugins-version="2">
-    <plugin-info>
-        <description>${project.description}</description>
-        <version>${project.version}</version>
-        <vendor name="${project.organization.name}" url="${project.organization.url}" />
-    </plugin-info>
-
-    <!-- from our base plugin -->
-    <component-import key="myComponent" interface="com.example.plugin.confluence.MyPluginComponent"/>
-
-    <!-- from the product container -->
-    <component-import key="applicationProperties" interface="com.atlassian.sal.api.ApplicationProperties" />
-    
-</atlassian-plugin>