Custom Announcement display in SharePoint

In SharePoint, doing a custom rollup of a news article list is pretty easy: Point a CQWP at the list, apply a custom XSLT template, and you’re done.

Unfortunately, when a user clicks on a link in the rollup in order to view the entire article, they get taken to the default article page — which is, shall we say, not very attractive:

Default SP2013 list view

Wouldn’t it be better to send users to a page that displays the article like an article, instead of like a list item? That provides a better user experience, and it keeps users out of the administrative back end.

Fortunately you can do that with CQWPs, by passing the article title as a variable to another CQWP, which can then display it any way you want.

 What you need

  1. A news article list
  2. A CQWP and associated XSLT for the rollup
  3. A page for the article display
  4. A CQWP and associated XSLT for the article display
  5. Appropriate CSS to display each version (we won’t detail that here)

The list

The list is pretty straightforward — unless you make the body of the announcement a rich-text field. That gives you lots of flexibility in the display of the full article, but it also triggers a bug in the CQWP. See the next section for details on handling that.

CQWP rich-text bug

In 2013, there’s a bug in the CQWP that displays extraneous HTML markup when pulling in data from a column that uses a Rich Text Editor. To get rid of the markup, you need to add a callable template that strips out the markup.

For full details, visit http://benprins.wordpress.com/2012/06/06/remove-html-markup-in-content-query-web-part/

We’ll include this template and its use in the markup for this post.

XSLT to handle the CQWP bug

<xsl:template name="removeMarkup">
    <xsl:param name="string" />
    <xsl:choose>
    <xsl:when test="contains($string, '&lt;')">
       <xsl:variable name="nextString">
         <xsl:call-template name="removeMarkup">
            <xsl:with-param name="string" select="substring-after($string, '&gt;')" />
         </xsl:call-template>
       </xsl:variable>
          <xsl:value-of select="concat(substring-before($string, '&lt;'), $nextString)" />
    </xsl:when>
    <xsl:otherwise>
       <xsl:value-of select="$string" />
    </xsl:otherwise>
    </xsl:choose>                
 </xsl:template>

XSLT for the rollup

The following XSLT does a standard rollup, but we’re mostly interested in the part in red.

<xsl:template name="NewsList" match="Row[@Style='NewsList']" mode="itemstyle">
    <xsl:variable name="SafeLinkUrl">
        <xsl:call-template name="OuterTemplate.GetSafeLink">
            <xsl:with-param name="UrlColumnName" select="'LinkUrl'"/>
        </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="SafeImageUrl">
        <xsl:call-template name="OuterTemplate.GetSafeStaticUrl">
            <xsl:with-param name="UrlColumnName" select="'ImageUrl'"/>
        </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="DisplayTitle">
        <xsl:call-template name="OuterTemplate.GetTitle">
            <xsl:with-param name="Title" select="@Title"/>
            <xsl:with-param name="UrlColumnName" select="'LinkUrl'"/>
        </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="cleanBody">
        <xsl:call-template name="removeMarkup">
            <xsl:with-param name="string" select="@Description"/>
        </xsl:call-template>
    </xsl:variable>

    <div class="media">
        <a href="News-article.aspx?newstitle={$DisplayTitle}" title="{@LinkToolTip}" class="pull-left">
            <img class="media-object" src="{$SafeImageUrl}" alt="{@ImageUrlAltText}" title="{@ImageUrlAltText}" />
        </a>
        <div>
            <h4><a href="News-article.aspx?newstitle={$DisplayTitle}" title="{@LinkToolTip}"><xsl:value-of select="$DisplayTitle"/></a></h4>
            <p><xsl:value-of select="substring($cleanBody,1,300)" /> ... (<a href="News-article.aspx?newstitle={$DisplayTitle}" title="{@LinkToolTip}">Read the rest</a>)</p>
        </div>
    </div>
</xsl:template>

This creates a standard rollup with an image on the left, headline on the right, and below the headine the first 300 characters of the article, followed by a “Read the rest” link. Clicking on either the image, the headline or the “Read the rest” link takes the user to the full article.

A couple of things to note:

  1. The use of the “cleanBody” variable, which calls the “removeMarkup” template to handle the rich-text content.
  2. The links highlighted in red point to a page called “News-article.aspx”, and pass it the article headline as a variable.

The rollup CQWP

Create a CQWP, point it at the News article list, and apply the “NewsList” template above.

XSLT for the full article

Create the following XSLT template for the article display:

<xsl:template name="NewsFullArticle" match="Row[@Style='NewsFullArticle']" mode="itemstyle">
    <xsl:variable name="SafeImageUrl">
        <xsl:call-template name="OuterTemplate.GetSafeStaticUrl">
            <xsl:with-param name="UrlColumnName" select="'ImageUrl'"/>
        </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="DisplayTitle">
        <xsl:call-template name="OuterTemplate.GetTitle">
            <xsl:with-param name="Title" select="@Title"/>
            <xsl:with-param name="UrlColumnName" select="'LinkUrl'"/>
        </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="cleanBody">
        <xsl:call-template name="removeMarkup">
            <xsl:with-param name="string" select="@Description"/>
        </xsl:call-template>
    </xsl:variable>

    <div class="media">
        <div class="media-body">
            <h2><xsl:value-of select="$DisplayTitle"/></h2>
            <xsl:value-of select="$cleanBody" disable-output-escaping="yes" />
        </div>
    </div>
</xsl:template>

This displays the article title as an <H2>, and then the full text of the article, with whatever rich-text formatting there might be.

Create the article page

  1. Create a new page named “News-article.aspx”
  2. Place a CQWP on it

Configure the article-page CQWP

Configure this CQWP very much like the rollup (point to the News List, etc.), with the following differences:

Article page CQWP settings

Remember how the first CQWP passed the article title as a variable? This setting now checks that variable and looks for a News item with a matching title. Result: It only displays one article, the one the user wanted to see.

Under “Presentation”, limit the number of items to 1. Combined with the default setting of sorting by Create date, it means that if two articles happen to have the same headline, only the most recent one will be displayed.

For Item style, apply the “NewsFullArticle” template.

For “Fields to Display”, make sure the “Title” and “Description” fields contain the names of the corresponding columns in the News List.

Categories: App Development and Business Productivity.