Thursday 21 February 2008

Extract the Month from a DateTime Field in Sitecore

Using sc:formatdate(), it is a fairly trivial matter to format a date in a Sitecore Xslt rendering. Eg:
sc:formatdate(sc:fld('MyDateField', .),
'd MMM yyyy @ h:mm')

However, extracting just the month as a number without padding is less obvious. Using the format string 'MMM' gives three-letter month names, 'MM' gives months padded with zeros (eg. 02 for Feb), while 'M' curiously gives full month name and date padded with zeros.

A workaround is to use substring-after in conjunction with the format '/M'. Example:
substring-after(sc:formatdate(
sc:fld('MyDateField', .), '/M'), '/')

Friday 15 February 2008

Get the Path of a Sitecore File Field Given a Media Path

A file field in Sitecore uses a media path. If you want to get the actual URL to the uploaded file, you need to append the file’s media path to the media library path and use this to reference the item in the media library. You can then extract the value of the path field. Example:

<a href="{sc:fld('Path', sc:item(concat('/sitecore/media library', sc:fld('filefieldname', .)), .))}">Download file</a>

How to Determine Sitecore System Field Names

If you want to find out the name of system fields in Sitecore, you need to open the Standard Template in the Template Manager.

Here are some of the available fields (obtained from version 5.2):

Workflow:
__Workflow
__Workflow state
__Lock
__Default workflow

Help:
__Short description
__Long description
__Help link

Publishing:
__Publish
__Unpublish
__Publishing groups
__Never publish

Tasks:
__Archive date
__Reminder date
__Reminder recipients
__Reminder text

Lifetime:
__Valid from
__Valid to

Statistics:
__Created
__Created by
__Revision
__Updated
__Updated by

Might be obvious, but I couldn’t find a list on SDN.

Monday 11 February 2008

Setting Query String Parameters in Xslt

In Xslt, adding a new parameter to a query string presents a problem as, without writing your own extension function, you cannot determine whether you should prefix your parameter with ‘?’ or ‘&’. In Sitecore, the Xslt function sc:qs('parametername') can be used to obtain the value of a named parameter parametername. Unfortunately, there is no function provided that obtains the entire query string.

Here’s a workaround. Let’s say you want to add a parameter called ‘page’.

First, build up the rest of the query string. The following template checks the existence in the query string of parameter names passed to it. You need to know the names of the possible parameters. If they exist, they are written out.

<xsl:template name="SetQueryParameter">
<xsl:param name="name" />
<xsl:if test="sc:qs($name)">
<xsl:text>&amp;</xsl:text>
<xsl:value-of select="$name" />
<xsl:text>=</xsl:text>
<xsl:value-of select="sc:qs($name)" />
</xsl:if>
</xsl:template>

This template would typically be called from within a variable definition, therefore saving the created query string. In the following example, we are checking parameters type and orderby and saving them if they exist so we can add them back in later:

<xsl:variable name="RestOfQueryString">
<xsl:call-template name="SetQueryParameter">
<xsl:with-param name="name">type</xsl:with-param>
</xsl:call-template>
<xsl:call-template name="SetQueryParameter">
<xsl:with-param name="name">orderby</xsl:with-param>
</xsl:call-template>
</xsl:variable>

You are then able to append this query string to your newly-added parameter, which you add using a ‘?’:

<a>
<xsl:attribute name="href">
<xsl:text>?page=10</xsl:text>
<xsl:value-of select="$RestOfQueryString" />
</xsl:attribute>
<xsl:text>Page 10</xsl:text>
</a>

Sunday 10 February 2008

ASP.NET Custom Validator of ISBN Numbers

International Standard Book Numbers (ISBNs), like other important numbers, such as credit card numbers, lend themselves to self-validation. The last digit of an ISBN is a check digit. A value found by applying a mathematical formula to other digits of the ISBN can be compared to this check digit. If the values relate to each other in a certain way, the ISBN is taken to be of a valid format.

To use an ASP.NET custom validator to apply the validation logic, proceed as follows. (The code validates ten-digit ISBN numbers.)

First, drag a CustomValidator control to the design surface of Visual Studio. Set its ControlToValidate to the ID of the control that is to be validated (eg. a TextBox). Set the ErrorMessage and Text properties as required. Double-click the CustomValidator control and add the following code to the ServerValidate event handler (this is example starter code: you will need to check its suitability against your particular requirements):

protected void cvISBN_ServerValidate( object source,
ServerValidateEventArgs args )
{
string strInput = args.Value;

if( strInput.Length != 10 )
{
args.IsValid = false;
}
else
{
int checksum;

if( strInput[9] == 'X' )
{
checksum = 10;
}
else
{
checksum = (int)strInput[9] - 48;
}

int total = 0;

for( int i = 0; i < 9; i++ )
{
total += ( i + 1 ) * ( (int)strInput[i] - 48 );
}

args.IsValid = ( total % 11 == checksum );
}
}

To perform client-side validation too, you can write a similar function in JavaScript and attach it to the CustomValidator’s ClientValidationFunction property. The function should have the following signature:

function myvalidationfunction(source, args)

Friday 1 February 2008

Posting back to a page without aspx extension

A project I am working on has the requirement for URLs not to have .aspx extensions. Requests are handled by IIS using ISAPI_Rewrite, which effectively adds on the extension behind the scenes. Generating the URLs is a fairly simple affair in XSLT using substring-before($url, '.aspx'). However, when using a ASP.NET form, the submit button by default adds an extension. I tried specifying the action attribute explicitly of the form, but this had no effect. The solution is to add a PostBackUrl attribute to the button control. Give it the name of the current page, without the extension. Example:

<asp:Button ID="btnSubmit" PostBackUrl="mypage"
runat="server" Text="Submit" OnClick="btnSubmit_Click" />

The located assembly's manifest definition does not match the assembly reference

I got this message this morning. It occurred in a solution comprising a web site and several class library projects. Both the web site and one the class libraries had a reference to the same assembly name. To resolve the problem, I removed the reference from the web site.