Blog Categories

Subscribe to RSS feed


HOW-TO: Remove embedded HTML in CQWP roll-ups

On a recent project, we were rolling up discussion board posts, which include a RichHTML field. The design called for the contents of the most recent posts to be summarized on the site’s landing page using a Content Query Web Part (CQWP).

The RichHTML field in the post is a mixed blessing. Having the ability to supply rich formatting within a discussion board post? Great. Having that markup screw up the styling of the landing page when it’s rolled up? Less great.

So we set out to display just the content of each post without the formatting. The solution turned out to be reasonably straightforward.

(Note: If you’re not familiar with customizing the ItemStyle.xsl or ContentQueryMain.xsl files to format CQWP output, start here.)

The first step was to find some XSL that removes the HTML markup, which I found here; this post adds just a bit more context.

I put this XSL template into the ContentQueryMain.xsl file.

   1: <xsl:template name="OuterTemplate.RemoveHtmlTags">
   2:   <xsl:param name="html"/>
   3:   <xsl:choose>
   4:     <xsl:when test="contains($html, '&lt;')">
   5:       <xsl:value-of select="substring-before($html, '&lt;')"/>
   6:       <!-- Recurse through HTML -->
   7:       <xsl:call-template name="OuterTemplate.RemoveHtmlTags">
   8:         <xsl:with-param name="html" select="substring-after($html, '&gt;')"/>
   9:       </xsl:call-template>
  10:     </xsl:when>
  11:     <xsl:otherwise>
  12:       <xsl:value-of select="$html"/>
  13:     </xsl:otherwise>
  14:   </xsl:choose>
  15: </xsl:template>

And then this additional template goes in the ItemStyle.xsl file:

   1: <xsl:template name="Discussions" match="Row[@Style='Discussions']" mode="itemstyle">
   2:     <xsl:variable name="SafeLinkUrl">
   3:       <xsl:call-template name="OuterTemplate.GetSafeLink">
   4:         <xsl:with-param name="UrlColumnName" select="'LinkUrl'"/>
   5:       </xsl:call-template>
   6:     </xsl:variable>
   7:     <xsl:variable name="DisplayTitle">
   8:       <xsl:call-template name="OuterTemplate.GetTitle">
   9:         <xsl:with-param name="Title" select="@Title"/>
  10:         <xsl:with-param name="UrlColumnName" select="'LinkUrl'"/>
  11:       </xsl:call-template>
  12:     </xsl:variable>
  13:     <xsl:variable name="LinkTarget">
  14:       <xsl:if test="@OpenInNewWindow = 'True'" >_blank</xsl:if>
  15:     </xsl:variable>
  16:     <xsl:variable name="pureTextBody">
  17:       <xsl:call-template name="OuterTemplate.RemoveHtmlTags">
  18:         <xsl:with-param name="html" select="@Body" />
  19:       </xsl:call-template>
  20:     </xsl:variable>
  22:     <table width="100%" border="0">
  23:       <tr>
  24:         <td style="width: 12px;" valign="top">
  25:           <div id="linkitem" class="listing font_1 link-item cqwpbullet">
  26:             <img src="/_LAYOUTS/1033/IMAGES/4_bullets.gif" border="0" style="margin:4px 0px 0px 0px;" />
  27:           </div>
  28:         </td>
  29:         <td valign="top">
  30:           <div id="linkitem" class="listing font_1 link-item cqwpbullet">
  31:             <a href="{$SafeLinkUrl}" target="{$LinkTarget}" title="{@LinkToolTip}" class="listinHrf">
  32:               <xsl:value-of select="substring($pureTextBody, 1, 100)" disable-output-escaping="yes" />...
  33:             </a>
  34:           </div>
  35:         </td>
  36:       </tr>
  37:     </table>
  38: </xsl:template>

Note that the pureTextBody XSL variable (line 16) is called by passing the Body attribute to the OuterTemplate.RemoveHtmlTags template (lines 17-18) that we put into the ContentQueryMain.xsl file — and then that variable, cleansed of its HTML markup, is rendered as output (line 32).

That’s it. Now the content of the discussion posts roll up and have a consistent presentation on the site landing page, but have their formatting intact when the user clicks through to look at the full post.

Leave a Reply