Image captions in TinyMCE

Indeed, there is a problem when the <img> that the rule tries to wrap with <figure> is inside <p> or other block-level elements. Part of the problem is that you have no control over which parent element TinyMCE will choose for an image when you insert it through the UI.

In any case, after some real-world use, this is the version I am currently using:

<replace css:content="div#parent-fieldname-text img:not([alt=''])">
  <xsl:variable name="parenttd" select="ancestor::td" />
  <xsl:variable name="parentth" select="ancestor::th" />
  <xsl:choose>
    <xsl:when test="$parenttd or $parentth">
      <xsl:copy-of select="." />
    </xsl:when>
    <xsl:otherwise>
      <figure>
        <xsl:attribute name="class"><xsl:value-of select="concat(./@class, ' caption')" /></xsl:attribute>
        <xsl:copy-of select="." />
        <figcaption>
          <div class="captiontitle">
            <xsl:value-of select="./@title" />
          </div>
          <div class="captiondescription">
            <xsl:value-of select="./@alt" />
          </div>
        </figcaption>
      </figure>
    </xsl:otherwise>
  </xsl:choose>
  <xsl:apply-templates />
</replace>

I made a couple of changes:

  1. the class on figure is now the same as the class on the img, plus ' caption'
  2. The alt attribute is the one deciding whether to use a caption or not, instead of the title. This is because image content items often have their title field automatically set to the filename of the image, and TinyMCE will use that, if present. If that's the case, and you don't want to use the title field, just put a space character in the title field in TinyMCE's insert/edit image dialog.
  3. Users of the site previously tried to "imitate" captions wrapping images in html tables, so I'm leaving those alone. That's what the variables parenttd and parentth are doing.
3 Likes