SPXSLT (SharePoint XSL Templates) Release 0.0.9

SPXSLTI’ve just released a new version of the SPXSLT Codeplex Project, version 0.0.9.

In this release, I added one new template called FixAmpersands. FixAmpersands is useful when you want to “join’ two lists in an AggregateDataSource in a Data View Web Part (DVWP) and the column you are uisng as the key may contain ampersands. This isn’t all that unusual if the keys are text values that don’t represent some sort of coding scheme, like a Product Code. Sometimes you may need to “join” two column values that contain ampersands, like “Beef & Kidney Pie” or “Tool & Die”. Because of the way that ampersands must be encoded on the Web, the primary value will contain the ampersand & but the secondary value will contain an encoded ampersand &. By calling FixAmpersands on the primary value, the “join” will work because the & will be replaced with &. (In fact, I had to monkey with the representations of the ampersands in that last sentence to get them to display correctly.)

The template is recursive, so it will replace *all* occurrences of & with &.

FixAmpersands looks like this:

<xsl:template name="FixAmpersands">
  <xsl:param name="StringValue"/>
  <xsl:variable name="Ampersand" select="'&amp;'" />
  <xsl:choose>
    <xsl:when test="contains($StringValue, $Ampersand)">
      <xsl:value-of select="concat(substring-before($StringValue, $Ampersand), '&amp;amp;', substring-after($StringValue, $Ampersand))"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$StringValue"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

And you call it like this:

<xsl:varaible name="FixedTitle">
  <xsl:call-template name="FixAmpersands">
    <xsl:with-param name="StringValue" select="@Title"/>
  </xsl:call-template>
</xsl:variable>

In the examples above, here’s what would happen:

Title FixedTitle
Beef & Kidney Pie Beef &amp; Kidney Pie
Tool & Die Tool &amp; Die
Sugar & Spice & Everything Nice Sugar &amp; Spice &amp; Everything Nice

I also fixed a small issue I noticed with the MultiSelectValueCheck.xsl file, which was missing the stylesheet wrapper.

SPXSLT (SharePoint XSL Templates) Release 0.0.6

SPXSLT Codeplex Project

I just released a new version of the SPXSLT Codeplex Project with a few minor changes.

I’ve added a new template called GetUserNames. It’s very similar to GetUserIDs, except that it parses out the user names (rather than IDs) from a Person or Group column value. It requires the GetUserName template to function.

Both GetUserNames and GetUserIDs now accept a parameter called Separator (inventively) which allows you to pass separator text which will be inserted between the values. GetUserIDs in prior versions had a semicolon hardwired rather than allowing you to pass a separator value, so this is a minor improvement.

<UPDATE dateTime=”2011-05-16 15:10″>Josh McCarty spotted an issue in FormatFileSize, which I fixed in v0.0.7. Thanks joshmccarty!</UPDATE>

SPXSLT (SharePoint XSL Templates) Release 0.0.1

SPXSLT Codeplex ProjectThe SPXSLT Codeplex Project has been languishing a bit due to a lack of time to focus on it on my part. (See my earlier blog post New CodePlex Project: SharePoint XSL Templates (SPXSLT) for more information on what this project is about.) These XSL templates can be used in your Data View Web Parts (DVWPs), Content Query Web Parts (CQWPs), and any other Web Parts you may have which rely on XSL transformations to display data.

Tonight I’ve packaged up the first real downloadable release, v0.0.1. The SPXSLT ZIPped download file contains each individual template wrapped up for individual use.

The main impetus for the change was a little Twitter conversation I had with Matt Hawley over at Codeplex in which he let me know that technically the project wasn’t “legal” for Codeplex because it didn’t have any code downloads available. I had the code embedded in the documentation rather than available for download.)

The project is gathering momentum and can benefit greatly from your contributions. Submit your useful XSL templates by posting them to the Discussions (if it’s a new template or template idea) or the Issue Tracker (if there’s a problem with an existing template) or contact me directly via the Codeplex site.

If you’ve submitted a template and don’t see it in the releases yet, I apologize for any delay. While I want to post any and all useful templates, I also want to validate each one, and that requires time (a precious commodity!). Please be patient, and don’t hesitate to ping me if you think I’ve forgotten about your submission.

Usage

To use a template within your own Data View Web Parts (DVWPs), Content Query Web Parts (CQWPs), etc., you only need each template itself. For example, if you wanted to use the ToUpper template, you would simply add the XSL below into your DVWP’s XSL section:

<xsl:template name="ToUpper">
    <xsl:param name="StringValue"/>
    <xsl:value-of select="translate($StringValue, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
</xsl:template>

Generally, you’ll want to add the templates to the bottom of the XSL section. In a simple DVWP, this would mean below the dvt_1.rowview template.

If you’d like to centralize your XSL template for greater reuse (highly recommended), you can put the individual XSL files into a Document Library for storage. In a WSS or SharePoint Foundation environment, I’d recommend using a Document Library in the root site of your Site Collection. In a MOSS or SharePoint 2010 environment, I’d recommend placing the XSL files in the /Style Library/XSL Style Sheets location, as this is where SharePoint stores it’s XSL by default.

If you want to use more than one of these templates on a regular basis, you should combine them into fewer files, or even one file. Only you will be able to determine what is the most efficient configuration, as it will be a balancing act between the number of files and the number of templates you use on a regular basis. I often will put all of the templates I use frequently into a single file called Utilities.XSL.

As I mentioned above, each of the XSL files are packaged for individual use. If you’d like to use the ToUpper template and have stored it in /Style Library/XSL Style Sheets, then you can include it in your DVWP with the xsl:import tag:

<xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" version="1.0" exclude-result-prefixes="xsl msxsl ddwrt" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"  xmlns:SharePoint="Microsoft.SharePoint.WebControls" xmlns:ddwrt2="urn:frontpage:internal">
    <xsl:import href="/Style Library/XSL Style Sheets/ToUpper.xsl"/>
    <xsl:output method="html" indent="no"/>

Note that the xsl:import tag must be in exactly this location at the top of your XSL section to work. Also, the namespace definitions which are included as part of the xsl:stylesheet tag are required and should not be changed.

In each individual XSL file, the template has the required wrapper for the xsl:import approach to work:

<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" version="1.0" exclude-result-prefixes="xsl msxsl ddwrt" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"  xmlns:SharePoint="Microsoft.SharePoint.WebControls" xmlns:ddwrt2="urn:frontpage:internal">
    <xsl:output method="html" indent="no"/>

    <xsl:template name="ToUpper">
        <xsl:param name="StringValue"/>
        <xsl:value-of select="translate($StringValue, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
    </xsl:template>

</xsl:stylesheet>

If you combine templates into a single file, there should only be a single wrapper for all of the templates in the file, like this:

<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" version="1.0" exclude-result-prefixes="xsl msxsl ddwrt" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"  xmlns:SharePoint="Microsoft.SharePoint.WebControls" xmlns:ddwrt2="urn:frontpage:internal">
    <xsl:output method="html" indent="no"/>

    <xsl:template name="ToUpper">
        <xsl:param name="StringValue"/>
        <xsl:value-of select="translate($StringValue, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
    </xsl:template>

    <xsl:template name="ToLower">
        <xsl:param name="StringValue"/>
        <xsl:value-of select="translate($StringValue, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"/>
    </xsl:template>
</xsl:stylesheet>

Available Templates

Name Short Description Dependencies Type Categories
ConvertToCelsius Converts a temperature in degrees Farenheit to degrees Celsius. NA Template Conversion
FirstNWords Displays the first N words from a string of text. (Use StripHTML first if your content includes markup.) NA Template String
GetPercentileValue Given a nodeset and a percentile (expressed as a number from 0-100), returns the percentile value of a column. NA Template Statistical
GetUserID This template returns the user’s ID from a Person or Group value. NA Template User
GetUserIDs This template returns the user IDs from a Person or Group column which allows multi-select. GetUserID Template User
GetUserName This template returns the user’s name from a Person or Group value. NA Template User
GetUserEmail This template returns the user’s Email from a Person or Group value. NA Template User
MailtoUser This template returns a mailto: link for the user’s Email from a Person or Group value. NA Template User
MailtoUsers This template returns mailto: links for the user Emails from a Person or Group column which allows multi-select. MailtoUser Template User
MultiSelectDisplay This template lets you display the values in a multiselect column “nicely”, using a separator of your choosing. NA Template Multi-Select
MultiSelectValueCheck This template checks to see if a specific value is present in a multi-value column. NA Template Multi-Select
StripHTML Strips the HTML tags out of a section of content. NA Template HTML
ToLower Converts a string to lower case. NA Template String
ToUpper Converts a string to upper case. NA Template String

Displaying the First N Words of Announcement Bodies with XSL in a DVWP

I got a ping yesterday from someone who had come across one of my old posts about Displaying the First N Words of a Long Rich Text Column with XSL. While the bits and pieces are there in the post, without a decent knowledge of XSL, it wasn’t obvious to them how you’d actually using the XSL templates. 

In this case, the list in question was an Announcements list.  I whipped up the XSL below for a DVWP pretty quickly using the StripHTML and FirstNWords templates which I’ve made available in the SPXSLT Codeplex Project.  If you drop this into your XSL section, you should have something pretty close to what you want. I’ve got the number of words per announcement body set to 10 in line 36; you can change that to whatever you’d like.

If you have useful XSL templates which you’d like to share, post them to the Discussions over at the  SPXSLT Codeplex Project.

<xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" version="1.0" exclude-result-prefixes="xsl msxsl ddwrt" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:SharePoint="Microsoft.SharePoint.WebControls" xmlns:ddwrt2="urn:frontpage:internal">
	<xsl:output method="html" indent="no"/>

	<xsl:template match="/">
		<xsl:call-template name="dvt_1"/>
	</xsl:template>

	<xsl:template name="dvt_1">
		<xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row"/>
		<table border="0" width="100%" cellpadding="2" cellspacing="0">
			<xsl:for-each select="$Rows">
				<xsl:call-template name="dvt_1.rowview"/>
			</xsl:for-each>
		</table>
	</xsl:template>

	<xsl:template name="dvt_1.rowview">
		<xsl:variable name="BodyText">
			<xsl:call-template name="StripHTML">
				<xsl:with-param name="HTMLText" select="@Body"/>
			</xsl:call-template>
		</xsl:variable>
		<tr>
			<td class="ms-vb">
				<a href="{@FileRef}"><span class="ms-announcementtitle"><xsl:value-of select="@Title"/></span></a><br/>
				by <xsl:value-of select="@Author" disable-output-escaping="yes"/>
			</td>
			<td class="ms-vb">
				<xsl:value-of select="ddwrt:FormatDate(string(@Created), 1033, 5)"/>
			</td>
		</tr>
		<tr>
			<td class="ms-vb">
				<xsl:call-template name="FirstNWords">
					<xsl:with-param name="TextData" select="$BodyText"/>
					<xsl:with-param name="WordCount" select="10"/>
					<xsl:with-param name="MoreText" select="'...'"/>
				</xsl:call-template>
			</td>
		</tr>
	</xsl:template>

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

	<xsl:template name="FirstNWords">
		<xsl:param name="TextData"/>
		<xsl:param name="WordCount"/>
		<xsl:param name="MoreText"/>
		<xsl:choose>
			<xsl:when test="$WordCount &gt; 1 and (string-length(substring-before($TextData, ' ')) &gt; 0 or string-length(substring-before($TextData, ' ')) &gt; 0)">
				<xsl:value-of select="concat(substring-before($TextData, ' '), ' ')" disable-output-escaping="yes"/>
				<xsl:call-template name="FirstNWords">
					<xsl:with-param name="TextData" select="substring-after($TextData, ' ')"/>
					<xsl:with-param name="WordCount" select="$WordCount - 1"/>
					<xsl:with-param name="MoreText" select="$MoreText"/>
				</xsl:call-template>
			</xsl:when>
			<xsl:when test="(string-length(substring-before($TextData, ' ')) &gt; 0 or string-length(substring-before($TextData, ' ')) &gt; 0)">
				<xsl:value-of select="concat(substring-before($TextData, ' '), $MoreText)" disable-output-escaping="yes"/>
			</xsl:when>
			<xsl:otherwise>
				<xsl:value-of select="$TextData" disable-output-escaping="yes"/>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>

</xsl:stylesheet>

The SPXSLT Codeplex Project – New XSL Templates

Cross-posted from EndUserSharePoint.com

About a month ago, at the suggestion of @iwkid, I created a new Codeplex project called SPXSLT.  My goal was to start providing a library of useful XSL templates for people to use in Data View Web Parts (DVWPs) or Content Query Web Parts (CQWPs) in SharePoint.  It’s a bit different from most Codeplex projects in that (at least so far), I’m not building releases. I’m simply using the Documentation section of the project to contain the XSL templates and their descriptions.

With all the work I do with DVWPs, I often find myself copying and pasting utility templates that I’ve built over time from old projects into new ones.  I’ve had my own messy store of these templates across my hard disks and VMs, and it seemed to make good sense to start sharing them for wider use.  There’s zero point in any of us writing these things over and over (unless we really just want to work too hard).

I would suggest that you create a file (I usually call mine Utilities.XSL) and store it centrally for use in DVWPs and CQWPs across your sites.  In WSS, I create a Document Library called XSL in the root site of the Site Collection and put the file there, along with any other commonly used XSL files.  In MOSS, I store these XSL files in ‘/Style Library/XSL Style Sheets’.

You can then add any of the templates from SPXSLT that you want to use in the Utilities.xsl file and include these utility templates in your DVWPs.  Take a look at my article Unlocking the Mysteries of Data View Web Part XSL Tags – Part 20: xsl:import to see how this process works.

The SPXSLT project has been languishing a bit, so today I added a set of new templates to get things moving again.  The new templates are GetUserIDs, MailtoUser, and MailtoUsers.

The full inventory of templates which I currently have available is listed below.

Name Short Description Requires Type Categories
FirstNWords Displays the first N words from a string of text. (Use StripHTML first if your content includes markup.) NA Template String
GetPercentileValue Given a nodeset and a percentile (expressed as a number from 0-100), returns the percentile value of a column. NA Template Statistical
GetUserID This template returns the user’s ID from a Person or Group value. NA Template User
GetUserIDs This template returns the user IDs from a Person or Group column which allows multi-select. GetUserID Template User
GetUserName This template returns the user’s name from a Person or Group value. NA Template User
GetUserEmail This template returns the user’s Email from a Person or Group value. NA Template User
MailtoUser This template returns a mailto: link for the user’s Email from a Person or Group value. NA Template User
MailtoUsers This template returns mailto: links for the user Emails from a Person or Group column which allows multi-select. MailtoUser Template User
StripHTML Strips the HTML tags out of a section of content. NA Template HTML

As with my other Codeplex project, SPServices*, I’m always looking for ideas and submissions to help expand the capabilities for SPXSLT.  Let me hear from you!

* A jQuery library which abstracts SharePoint’s Web Services and makes them easier to use. It also includes functions which use the various Web Service operations to provide more useful (and cool) capabilities. It works entirely client side and requires no server install.