When the designs came through for my latest Umbraco project, I
saw that on certain pages there were images embedded in the main
page content. Beneath these images were a caption header and
caption text. It looked great.
From my point of view, I saw that I had a number of options. I
could add three fields to each document type which could have such
an image: one for the image, one for the caption header, and one
for the caption text. Then I could create two templates - one that
had extra fields for the image, caption header and caption text,
and another without. Then the content editor could choose which
template was required. Or, I could create a macro to be used in the
richtext editor - a much more elegant solution. Here's how to do
it.
Firstly, I updated the image media type so that content editors
could add a caption header and caption text to any image that they
wanted to:

Then I created a new xslt macro called Image With Caption. Here
is the xslt. Note that it takes one parameter, which is a
mediaCurrent parameter type (hence the slightly unusual way of
accessing the macro parameter).
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp " "> ]>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxml="urn:schemas-microsoft-com:xslt"
xmlns:umbraco.library="urn:umbraco.library" xmlns:Exslt.ExsltCommon="urn:Exslt.ExsltCommon" xmlns:Exslt.ExsltDatesAndTimes="urn:Exslt.ExsltDatesAndTimes" xmlns:Exslt.ExsltMath="urn:Exslt.ExsltMath" xmlns:Exslt.ExsltRegularExpressions="urn:Exslt.ExsltRegularExpressions" xmlns:Exslt.ExsltStrings="urn:Exslt.ExsltStrings" xmlns:Exslt.ExsltSets="urn:Exslt.ExsltSets"
exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets ">
<xsl:output method="html" omit-xml-declaration="yes"/>
<xsl:param name="currentPage"/>
<xsl:param name="image" select="/macro/image/node"/>
<xsl:template match="/">
<div class="img img203">
<img class="left" height="138" width="203">
<xsl:attribute name="src">
<xsl:value-of select="$image/data[@alias = 'umbracoFile']"/>
</xsl:attribute>
<xsl:attribute name="alt">
<xsl:value-of select="$image/data[@alias = 'altText']"/>
</xsl:attribute>
</img>
<p class="caption">
<span class="highlight">
<xsl:value-of select="$image/data[@alias = 'captionHeading']"/>
</span> <xsl:value-of select="$image/data[@alias = 'captionText']"/>
</p>
</div>
</xsl:template>
</xsl:stylesheet>
And here is the macro. Note that I have checked the "use in
editor" checkbox - this means that you can use the macro in the
richtext editor, as you'll see.

I've also set up the macro with a single MediaCurrent parameter,
so that the user can specify which image they want to include in
the content:

And that's pretty much it for configuring the functionality. For
your content manager, they can now use the insert macro button to
insert a macro into their content:

When they click this button, they get a list of all macros that
you have defined for your site as being available to use in the
editor:

Click OK, and then they get to choose the image that they want
to display:

Click choose, and select the image required by browsing the
Media section of the site. Click on the image they want and then
click the OK button. Now themacro should appear in the content in
the richtext editor:

How it appears in the richtext editor is not necessarily how it
will appear on the site. It depends on the stylesheets on the site
and the markup in the xslt as to how it will appear. You'll notice
that my xslt file has a lot of custom markup like heights and
widths and classes in there to style the output.
So there you have it. A user-friendly way of inserting stylish
content straight into your richtext editor without any need for
content managers to mess about with html or understand xslt. Yet
another great feature of Umbraco!
David