Commits

Theresa Henze committed 69492e9

Removed old naming

  • Participants
  • Parent commits 89cec4a

Comments (0)

Files changed (9)

+= Macro Magic =
+
+Tutorial and code samples to manipulate the creation and/or editing of Confluence macros.
+
+
+== Editor ==
+
+
+=== Formatting ===
+
+todo
+
+
+=== Insert Menu ===
+
+Done
+
+
+== Macros ==
+
+=== Insert with custom GUI ===
+
+Work in progress
+
+
+=== Macro Options ===
+
+Done
+
+
+=== Macro Parameters (name/value presentation) ===
+
+Done
+
+
+=== Image place holder ===
+
+todo
+
+
+= Helpful Links =
+
+* https://confluence.atlassian.com/pages/viewpage.action?pageId=225116740
+
+* http://www.slideshare.net/GoAtlassian/pimp-my-confluence-plugin-atlascamp-2011
+
+

src/main/java/com/example/plugin/confluence/BoxMacro.java

+package com.example.plugin.confluence;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.log4j.Logger;
+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 box macro with images. Preferably use section and column macros as
+ * containers.
+ * 
+ * @example {section} {column}
+ *          {box:size=small|title=Title}lorem ipsum{box}
+ *          {column} {section}
+ */
+public class BoxMacro extends BaseMacro implements Macro {
+	private final Logger logger = Logger.getLogger(BoxMacro.class);
+
+	private final String BOX_TEMPLATE = "vm/macro-box.vm";
+	private final Set<String> SIZES = new HashSet<String>(Arrays.asList(new String[] { "small", "medium", "large" }));
+	private final String DEFAULT_SIZE = "small";
+	private final Set<String> COLORS = new HashSet<String>(Arrays.asList(new String[] { "red", "grey" }));
+	private final String DEFAULT_COLOR = "red";
+
+	@SuppressWarnings("rawtypes")
+	@Override
+	public String execute(final Map params, final String body, final RenderContext renderContext) throws MacroException {
+		VelocityContext contextMap = new VelocityContext(MacroUtils.defaultVelocityContext());
+
+		putStringContextVar(contextMap, params, "size", SIZES, DEFAULT_SIZE);
+		putStringContextVar(contextMap, params, "color", COLORS, DEFAULT_COLOR);
+
+		// put title into map
+		contextMap.put("title", params.get("title"));
+
+		// put parts from body into map
+		putBodyPartsIntoMap(body, contextMap);
+
+		// check new tab option
+		if ("true".equals(params.get("newTab"))) {
+			contextMap.put("newTab", "open_new_window");
+		}
+
+		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);
+		}
+	}
+
+	private void putBodyPartsIntoMap(final String body, final VelocityContext contextMap) {
+		logger.debug("Raw body: " + body);
+		String finalBody = extractImageFromBody(body, contextMap);
+		finalBody = extractLinkFromBody(finalBody, contextMap);
+
+		finalBody = StringUtils.trimToEmpty(finalBody);
+		logger.debug("New body: " + finalBody);
+		contextMap.put("body", finalBody);
+	}
+
+	protected String extractLinkFromBody(String body, final VelocityContext contextMap) {
+		Matcher linkMatch = Pattern.compile("<a.*?</a>").matcher(body);
+		if (linkMatch.find()) {
+			final String link = linkMatch.group(0);
+			// remove link from body
+			body = body.replace(link, "");
+
+			// get href value from link
+			Matcher hrefMatch = Pattern.compile("href=\"(.*?)\"").matcher(link);
+			if (hrefMatch.find()) {
+				contextMap.put("url", hrefMatch.group(1));
+			}
+		}
+
+		return body;
+	}
+
+	protected String extractImageFromBody(String body, final VelocityContext contextMap) {
+		Matcher imageMatch = Pattern.compile("<img.*?>").matcher(body);
+		if (imageMatch.find()) {
+			final String image = imageMatch.group(0);
+			// extract image from body
+			body = body.replace(image, "");
+
+			// get src value from image
+			Matcher srcMatch = Pattern.compile("src=\"(.*?)\"").matcher(image);
+			if (srcMatch.find()) {
+				contextMap.put("imagesrc", srcMatch.group(1));
+			}
+		}
+		else {
+			contextMap.put("image", "");
+		}
+		return body;
+	}
+
+	@Override
+	public BodyType getBodyType() {
+		return BodyType.RICH_TEXT;
+	}
+
+	@Override
+	public OutputType getOutputType() {
+		return OutputType.BLOCK;
+	}
+
+	@Override
+	public boolean isInline() {
+		return false;
+	}
+
+	@Override
+	public boolean hasBody() {
+		return true;
+	}
+
+	@Override
+	public RenderMode getBodyRenderMode() {
+		return RenderMode.allow(RenderMode.F_LINKS | RenderMode.F_LINEBREAKS | RenderMode.F_MACROS
+				| RenderMode.F_MACROS_ERR_MSG | RenderMode.F_PHRASES);
+	}
+
+	@Override
+	public boolean suppressMacroRenderingDuringWysiwyg() {
+		return true;
+	}
+
+	@Override
+	public boolean suppressSurroundingTagDuringWysiwygRendering() {
+		return false;
+	}
+
+	/**
+	 * Setzt einen Wert aus einem Enum-Type-Parameter, wenn nicht vorhanden wird ein
+	 * Default-Wert gesetzt.
+	 * 
+	 * @param contextMap
+	 *          Context
+	 * @param params
+	 *          Makro-Parameter
+	 * @param paramname
+	 *          Parametername
+	 * @param set
+	 *          Enum-Set
+	 * @param def
+	 *          Default-Wert
+	 */
+	public static void putStringContextVar(final VelocityContext contextMap, final Map params, final String paramname,
+			final Set set, final String def) {
+		Object p = params.get(paramname);
+		if (set.contains(p)) {
+			contextMap.put(paramname, p);
+		}
+		else {
+			contextMap.put(paramname, def);
+		}
+	}
+}

src/main/java/com/example/plugin/confluence/TeaserItemMacro.java

-package com.example.plugin.confluence;
-
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.commons.lang3.StringUtils;
-import org.apache.log4j.Logger;
-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;
-
-/**
- * Macro zum Einfügen von Teasern mit Bildern zum Auflockern des Inhalts. Sollte
- * innerhalb eines Section/Column-Container stehen.
- * 
- * @example {section} {column}
- *          {teaser-item:icon=icon-name|title=Titel}lorem ipsum{teaser-item} ...
- *          {column} {section}
- * @author Lars-Erik Kimmel / Thomas Zobel
- */
-public class TeaserItemMacro extends BaseMacro implements Macro {
-	private final Logger logger = Logger.getLogger(TeaserItemMacro.class);
-
-	private final String TEASER_TEMPLATE = "vm/teaseritem.vm";
-	private final Set<String> SIZES = new HashSet<String>(Arrays.asList(new String[] { "small", "medium", "large" }));
-	private final String DEFAULT_SIZE = "small";
-	private final Set<String> COLORS = new HashSet<String>(Arrays.asList(new String[] { "red", "grey" }));
-	private final String DEFAULT_COLOR = "red";
-
-	@SuppressWarnings("rawtypes")
-	@Override
-	public String execute(final Map params, final String body, final RenderContext renderContext) throws MacroException {
-		VelocityContext contextMap = new VelocityContext(MacroUtils.defaultVelocityContext());
-
-		putStringContextVar(contextMap, params, "size", SIZES, DEFAULT_SIZE);
-		putStringContextVar(contextMap, params, "color", COLORS, DEFAULT_COLOR);
-
-		// put title into map
-		contextMap.put("title", params.get("title"));
-
-		// put parts from body into map
-		putBodyPartsIntoMap(body, contextMap);
-
-		// check new tab option
-		if ("true".equals(params.get("newTab"))) {
-			contextMap.put("newTab", "open_new_window");
-		}
-
-		return VelocityUtils.getRenderedTemplate(TEASER_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);
-		}
-	}
-
-	private void putBodyPartsIntoMap(final String body, final VelocityContext contextMap) {
-		logger.debug("Raw body: " + body);
-		String finalBody = extractImageFromBody(body, contextMap);
-		finalBody = extractLinkFromBody(finalBody, contextMap);
-
-		finalBody = StringUtils.trimToEmpty(finalBody);
-		logger.debug("New body: " + finalBody);
-		contextMap.put("body", finalBody);
-	}
-
-	protected String extractLinkFromBody(String body, final VelocityContext contextMap) {
-		Matcher linkMatch = Pattern.compile("<a.*?</a>").matcher(body);
-		if (linkMatch.find()) {
-			final String link = linkMatch.group(0);
-			// remove link from body
-			body = body.replace(link, "");
-
-			// get href value from link
-			Matcher hrefMatch = Pattern.compile("href=\"(.*?)\"").matcher(link);
-			if (hrefMatch.find()) {
-				contextMap.put("url", hrefMatch.group(1));
-			}
-		}
-
-		return body;
-	}
-
-	protected String extractImageFromBody(String body, final VelocityContext contextMap) {
-		Matcher imageMatch = Pattern.compile("<img.*?>").matcher(body);
-		if (imageMatch.find()) {
-			final String image = imageMatch.group(0);
-			// extract image from body
-			body = body.replace(image, "");
-
-			// get src value from image
-			Matcher srcMatch = Pattern.compile("src=\"(.*?)\"").matcher(image);
-			if (srcMatch.find()) {
-				contextMap.put("imagesrc", srcMatch.group(1));
-			}
-		}
-		else {
-			contextMap.put("image", "");
-		}
-		return body;
-	}
-
-	@Override
-	public BodyType getBodyType() {
-		return BodyType.RICH_TEXT;
-	}
-
-	@Override
-	public OutputType getOutputType() {
-		return OutputType.BLOCK;
-	}
-
-	@Override
-	public boolean isInline() {
-		return false;
-	}
-
-	@Override
-	public boolean hasBody() {
-		return true;
-	}
-
-	@Override
-	public RenderMode getBodyRenderMode() {
-		return RenderMode.allow(RenderMode.F_LINKS | RenderMode.F_LINEBREAKS | RenderMode.F_MACROS
-				| RenderMode.F_MACROS_ERR_MSG | RenderMode.F_PHRASES);
-	}
-
-	@Override
-	public boolean suppressMacroRenderingDuringWysiwyg() {
-		return true;
-	}
-
-	@Override
-	public boolean suppressSurroundingTagDuringWysiwygRendering() {
-		return false;
-	}
-
-	/**
-	 * Setzt einen Wert aus einem Enum-Type-Parameter, wenn nicht vorhanden wird ein
-	 * Default-Wert gesetzt.
-	 * 
-	 * @param contextMap
-	 *          Context
-	 * @param params
-	 *          Makro-Parameter
-	 * @param paramname
-	 *          Parametername
-	 * @param set
-	 *          Enum-Set
-	 * @param def
-	 *          Default-Wert
-	 */
-	public static void putStringContextVar(final VelocityContext contextMap, final Map params, final String paramname,
-			final Set set, final String def) {
-		Object p = params.get(paramname);
-		if (set.contains(p)) {
-			contextMap.put(paramname, p);
-		}
-		else {
-			contextMap.put(paramname, def);
-		}
-	}
-}

src/main/resources/atlassian-plugin.xml

         <param name="content-type" value="image/png"/>
     </resource>
     
-	<xhtml-macro name="teaser" class="com.example.plugin.confluence.TeaserItemMacro" key="teaser-xhtml">
-	    <!-- icon="/images/teaser-icon.png" documentation-url="" -->
+	<xhtml-macro name="box" class="com.example.plugin.confluence.BoxMacro" key="box-xhtml">
+	    <!-- icon="/images/box-icon.png" documentation-url="" -->
 		<category name="confluence-content" />
 		<parameters>
-		    <!-- 
 			<default>
 			    <option key="showValueInPlaceholder" value="true"/>
 			</default>
-			 -->
 			<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"/> -->
+				<option key="showValueInPlaceholder" value="true"/>
 			</parameter>
-			<parameter name="title" type="string"><!-- 
+			<parameter name="title" type="string">
 				<option key="showKeyInPlaceholder" value="false"/>
-				<option key="showValueInPlaceholder" value="true"/> -->
+				<option key="showValueInPlaceholder" value="true"/>
 			</parameter>
-			<parameter name="newTab" type="boolean"><!-- 
+			<parameter name="newTab" type="boolean"> 
 				<option key="showKeyInPlaceholder" value="false"/>
-				<option key="showValueInPlaceholder" value="true"/> -->
+				<option key="showValueInPlaceholder" value="true"/>
 			</parameter>
 		</parameters>
 		<property-panel>
 		</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 {teaser-item}..{teaser-item} -->
-	<macro name="teaser" class="com.example.plugin.confluence.TeaserItemMacro" key="teaser">
+	<!-- 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" />
 		<parameters>
 			<parameter name="size" type="enum" required="true" default="small">
 		</parameters>
 	</macro>
 	
-    <web-item key="editor-featured-macro-teaser-item" name="Insert Menu Link - Box Macro" section="system.editor.featured.macros.default" weight="11">
+    <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.teaser.label">Box</label>
-        <link linkId="teaser"/>
+        <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-teaser">
+    <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-teaser.js" location="js/editor-resource-teaser.js"/>
+        <resource type="download" name="editor-resource.js" location="js/editor-resource.js"/>
     </web-resource>
     
 </atlassian-plugin>

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

-(function() {
-	
-	var getMacroBody = function(macroDiv) {
-        /**
-         * 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.
-         */
-        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;
-	}
-	
-	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;
-	}
-	
-    var updateMacro = function(macroNode, param) {
-        var $macroDiv = AJS.$(macroNode);
-        AJS.Rte.getEditor().selection.select($macroDiv[0]);
-        AJS.Rte.BookmarkManager.storeBookmark();
-
-        var currentParams = getCurrentParams($macroDiv);
-        currentParams["size"] = param;
-        var macroBody = getMacroBody($macroDiv);
-        
-        var macroRenderRequest = {
-            contentId: Confluence.Editor.getContentId(),
-            macro: {
-                name: "teaser",
-                params: currentParams,
-                defaultParameterValue: "",
-                body : macroBody
-            }
-        };
-
-        tinymce.confluence.MacroUtils.insertMacro(macroRenderRequest);
-    };
-
-    AJS.Confluence.PropertyPanel.Macro.registerButtonHandler("Small", function(e, macroNode) {
-        updateMacro(macroNode, "small");
-    });
-
-    AJS.Confluence.PropertyPanel.Macro.registerButtonHandler("Medium", function(e, macroNode) {
-        updateMacro(macroNode, "medium");
-    });
-
-    AJS.Confluence.PropertyPanel.Macro.registerButtonHandler("Large", function(e, macroNode) {
-        updateMacro(macroNode, "large");
-    });
- 
-})();
-
-
-AJS.bind("init.rte", function() { 
-//	AJS.MacroBrowser.setMacroJsOverride('teaser', {opener: function() {
-//		AJS.log("DUMMY OPENER");
-//	    var popup = new AJS.Dialog(860, 530);
-//        popup.show();
-//	}})
-});

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

+(function() {
+	
+	
+	
+	var getMacroBody = function(macroDiv) {
+        /**
+         * 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.
+         */
+        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;
+	}
+	
+	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;
+	}
+	
+    var updateMacro = function(macroName, macroParam, macroNode, param) {
+        var $macroDiv = AJS.$(macroNode);
+        AJS.Rte.getEditor().selection.select($macroDiv[0]);
+        AJS.Rte.BookmarkManager.storeBookmark();
+
+        var currentParams = getCurrentParams($macroDiv);
+        currentParams[macroParam] = param;
+        var macroBody = getMacroBody($macroDiv);
+        
+        var macroRenderRequest = {
+            contentId: Confluence.Editor.getContentId(),
+            macro: {
+                name: macroName,
+                params: currentParams,
+                defaultParameterValue: "",
+                body : macroBody
+            }
+        };
+
+        tinymce.confluence.MacroUtils.insertMacro(macroRenderRequest);
+    };
+
+    AJS.Confluence.PropertyPanel.Macro.registerButtonHandler("box", "size", "Small", function(e, macroNode) {
+        updateMacro(macroNode, "small");
+    });
+
+    AJS.Confluence.PropertyPanel.Macro.registerButtonHandler("box", "size", "Medium", function(e, macroNode) {
+        updateMacro(macroNode, "medium");
+    });
+
+    AJS.Confluence.PropertyPanel.Macro.registerButtonHandler("box", "size", "Large", function(e, macroNode) {
+        updateMacro(macroNode, "large");
+    });
+ 
+})();
+
+
+AJS.bind("init.rte", function() { 
+//	AJS.MacroBrowser.setMacroJsOverride('box', {opener: function() {
+//		AJS.log("DUMMY OPENER");
+//	    var popup = new AJS.Dialog(860, 530);
+//        popup.show();
+//	}})
+});

src/main/resources/macromagic.properties

-#put any key/value pairs here
-my.plugin.name=Macro Magic
-
-com.example.plugin.confluence.macromagic.teaser.desc                   = Macro for adding a box.
-com.example.plugin.confluence.macromagic.teaser.label                  = Box
-com.example.plugin.confluence.macromagic.teaser.param.newTab.label     = Open link in new tab/window (subject to the settings of your browser).
-com.example.plugin.confluence.macromagic.teaser.param.size.label       = Box size
-com.example.plugin.confluence.macromagic.teaser.param.title.label      = Title
+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.param.size.label       = Box size
+com.example.plugin.confluence.macromagic.box.param.title.label      = Title

src/main/resources/vm/macro-box.vm

+<div class="box-frame box-frame-$!size">
+	#if ($size != "small")
+		<div class="box-top"></div>
+	#end
+	<div class="box box-$!size box-$!color">
+		#if ($size != "small")
+			#if ($image != "")
+				<img src="$!imagesrc" />
+			#end
+			<div class="box-title">$!title</div>
+			<div class="box-content">$!body</div>
+		#end
+		<div class="box-arrow">
+			#if ($size == 'small')
+				$!title 
+			#else 
+				$i18n.getText("more.text") 
+			#end
+		</div>
+		#if 
+			($size == "large")<div class="clear">&nbsp;</div>
+		#end
+		<a class="box-link $!newTab" href="$!url">$!title</a>
+	</div>
+</div>

src/main/resources/vm/teaseritem.vm

-<div class="teaser-frame teaser-frame-$!size">
-	#if ($size != "small")
-		<div class="teaser-top"></div>
-	#end
-	<div class="teaser teaser-$!size teaser-$!color">
-		#if ($size != "small")
-			#if ($image != "")
-				<img src="$!imagesrc" />
-			#end
-			<div class="teaser-title">$!title</div>
-			<div class="teaser-content">$!body</div>
-		#end
-		<div class="teaser-arrow">
-			#if ($size == 'small')
-				$!title 
-			#else 
-				$i18n.getText("more.text") 
-			#end
-		</div>
-		#if 
-			($size == "large")<div class="clear">&nbsp;</div>
-		#end
-		<a class="teaser-link $!newTab" href="$!url">$!title</a>
-	</div>
-</div>