Monday, October 20, 2008

Revisiting ddwrt and FormatDate

I have had some feedback on the my posting in May 2007 about the ddwrt FormatDate function, including a request to see additional formats.

Therefore I had a play with some reflection code, and have created a little command line application that can be used to see the available date formats output by the ddwrt utility.

Note that this code could be used to experiment with the output of some of the other ddwrt functions in the Microsoft.SharePoint.WebPartPages.DdwRuntime library - to see a list of the other functions, open up the Microsoft.SharePoint dll in Reflector.

One other tip - a list of the LCID values is available in this post on my blog


using System;

using System.Collections.Generic;

using System.Globalization;

using System.Linq;

using System.Reflection;

using System.Text;

 

namespace DDWRT.FormatDate

{

    class Program

    {

        static void Main(string[] args)

        {

            try

            {

                CultureInfo ci = new CultureInfo(1031);

                Console.WriteLine(RunDDWRT("05-09-2007 11:00", ci));

            }

            catch (Exception ex)

            {

                Console.WriteLine(ex.ToString());

            }

            Console.ReadLine();

        }

 

        public static string RunDDWRT(string szDate, CultureInfo ci)

        {

            string fullName = "Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c";

 

            StringBuilder sb = new StringBuilder();

 

            //Load the SharePoint Assembly

            Assembly assem = Assembly.Load(fullName);

 

            // Reference the DDWRT namespace

            Type type = assem.GetType("Microsoft.SharePoint.WebPartPages.DdwRuntime", true, true);

 

            //Find the sought method in DDWRT (the "FormatDateTime" method)

            MethodInfo methodInfo = null;

            MethodInfo[] methods = type.GetMethods();

            foreach (MethodInfo method in methods)

            {

                //Uncomment the next line to see a list of all the methods available in the ddwrt class

                //sb.AppendLine(string.Format("  {0}", method.Name));

 

                if (method.Name == "FormatDate")

                    methodInfo = method;

            }

 

            if (methodInfo != null)

            {

                object objectInstance = Activator.CreateInstance(type);

 

                sb.AppendLine("ddwrt.FormatDate Test");

                sb.AppendFormat("\r\n");

                sb.Append("Locale LCID:");

                sb.AppendFormat("\t");

                sb.Append(string.Format("{0} ({1})", ci.LCID.ToString(), ci.Name));

                sb.AppendFormat("\r\n");

                sb.Append("Date to format:");

                sb.AppendFormat("\t");

                sb.Append(szDate);

                sb.AppendFormat("\r\n");

                sb.AppendFormat("\r\n");

 

                sb.Append("FormatFlag");

                sb.AppendFormat("\t");

                sb.Append("Formatted Date");

                sb.AppendFormat("\r\n");

                sb.AppendFormat("\r\n");

                for (long formatFlag = 1; formatFlag < 16; formatFlag++)

                {

                    try

                    {

                        string formattedDateTime = (string)methodInfo.Invoke(objectInstance, new Object[] { szDate, ci.LCID, formatFlag });

                        sb.Append(formatFlag);

                        sb.AppendFormat("\t\t");

                        sb.Append(formattedDateTime);

                        sb.AppendFormat("\r\n");

                    }

                    catch

                    {

                        sb.Append(formatFlag);

                        sb.AppendFormat("\t\t");

                        sb.Append("--------");

                        sb.AppendFormat("\r\n");

                    }

                }

            }

            return sb.ToString();

        }

 

    }

}

Wednesday, October 1, 2008

Displaying the Raw Search Results

Here's a little tidbit I usually end up searching for when manipulating search results - so it must be time to link to it here:
How to: View Search Results XML Data
(Also see Customize the People Search Results)

This gives a rundown on the XSL to use to show the raw XML that is returned to a search results web part (such as the "CoreResultsWebPart").

Basically, use the following:
<xsl:stylesheet version="1.0" xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes">
<xsl:template match="/">
<xmp><xsl:copy-of select="*"></xmp>
</xsl:template>
</xsl:stylesheet>

Custom Web Part Pages Template Woes

Seems to have been plenty of people that have tried to extend the list Web Part Page templates made available on the spcf.aspx page. And it seems that the approach outlined in the Microsoft article "Creating Custom Web Part Page Templates for Microsoft SharePoint Products and Technologies" just doesn't work with SharePoint v3.

The approach of adding an additional option to the list of templates in a custom custspcf.aspx page seems to fail (with the "Invalid URL Parameter" message) for the following reason: according to the WSS SDK, the NewWebPage RPC method accepts a value for the WebPartPageTemplate of between 1 and 8.

That must explain why adding a ninth template to the list fails - the call to the NewWebPage method OWSSVR.DLL doesn't expect a number above 8. For the background, here is a discussion on OWSSVR by Joel Oleson.

So I guess the options if different Web Part Page templates are required are to either
  • Replace the standard ones that are located in 12\TEMPLATE\1033\STS\DOCTEMP\SMARTPGS, or to
  • Create a completely custom template selection page - but I am finding that there are some real oddities in the names of pages that appear in search results when web part pages are created in a custom manner.

Another area that needs attention in vNext!