Friday, November 22, 2013

Use Server Variables In XSLT To Find The Root Site

There’s no way to tell what the site’s Root Web URL will be, nor the protocol used on any given site, so here’s a quick rundown of how to get the Root Web URL using XSLT:

Variable Setup

This example requires these two server variables.
  • SERVER_NAME
  • HTTPS

ServerVariable - SERVER_NAME
Here’s a screenshot of what it looks like in SPD.  With these in place we'll be able to determine the Root Web URL dynamically, so this could be used on any site and the code will know exactly what the URL of the root web is.





XSLT Code

I've commented the key parts to this simple example, so if you want to just take those pieces you can.  Doing this through the GUI, it adds two <ParameterBinding />’s to your code.  Later in the code, you’ll see two variables that are used:
  • httpProtocol
  • sitePath
These variables are put together to form the URL of the Root Web.

<WebPartPages:DataFormWebPart runat="server" Description="" PartOrder="2" HelpLink="" AllowRemove="True" IsVisible="True" AllowHide="True" UseSQLDataSourcePaging="True" ExportControlledProperties="True" DataSourceID="" Title="" ViewFlag="8" NoDefaultStyle="TRUE" AllowConnect="True" FrameState="Normal" PageSize="-1" PartImageLarge="" AsyncRefresh="True" ExportMode="All" Dir="Default" DetailLink="" ShowWithSampleData="True" ListId="" ListName="" FrameType="None" PartImageSmall="" IsIncluded="True" SuppressWebPartChrome="False" AllowEdit="True" ManualRefresh="False" ChromeType="None" AutoRefresh="False" AutoRefreshInterval="60" AllowMinimize="True" ViewContentTypeId="" InitialAsyncDataFetch="False" MissingAssembly="Cannot import this Web Part." HelpMode="Modeless" ID="" ConnectionID="00000000-0000-0000-0000-000000000000" AllowZoneChange="True" IsIncludedFilter="" __MarkupType="vsattributemarkup" __WebPartId="" __AllowXSLTEditing="true" WebPart="true" Height="" Width=""><ParameterBindings>
                        <ParameterBinding Name="dvt_apos" Location="Postback;Connection"/>
                        <ParameterBinding Name="ManualRefresh" Location="WPProperty[ManualRefresh]"/>
                        <ParameterBinding Name="UserID" Location="CAMLVariable" DefaultValue="CurrentUserName"/>
                        <ParameterBinding Name="Today" Location="CAMLVariable" DefaultValue="CurrentDate"/>
                       
                        <!-- Set these two variables up within your DVWP/XLV Web Part -->
                        <ParameterBinding Name="HTTPS" Location="ServerVariable(HTTPS)" DefaultValue=""/>
                        <ParameterBinding Name="SERVER_NAME" Location="ServerVariable(SERVER_NAME)" DefaultValue=""/>
                    </ParameterBindings>
<DataFields>
@myField,myField;</DataFields>
<Xsl>
    <xsl:stylesheet xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" 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:decimal-format NaN=""/>
        <xsl:param name="dvt_apos">&apos;</xsl:param>
        <xsl:param name="ManualRefresh"></xsl:param>
        <xsl:param name="webUrl" />
        <xsl:param name="HTTPS" />
        <xsl:param name="SERVER_NAME" />
        <xsl:variable name="dvt_1_automode">0</xsl:variable>
        <xsl:template match="/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:SharePoint="Microsoft.SharePoint.WebControls">
            <xsl:call-template name="dvt_1"/>
        </xsl:template>
        <xsl:template name="dvt_1">                       <xsl:variable name="Rows" select="/dsQueryResponse/Rows/Row"/>
            <xsl:variable name="dvt_RowCount" select="count($Rows)"/>
            <xsl:variable name="IsEmpty" select="$dvt_RowCount = 0" />
            <xsl:variable name="dvt_IsEmpty" select="$dvt_RowCount = 0"/>
            <!-- Use this variable to determine the protocol used by the site -->
            <xsl:variable name="httpProtocol">
                <xsl:choose>
                    <xsl:when test="normalize-space($HTTPS) = 'on'">https://</xsl:when>
                    <xsl:otherwise>http://</xsl:otherwise>
                </xsl:choose>
            </xsl:variable>
            <!-- This variable concats all of these variables together -->
            <!-- Example sitePath output: http://iOnline247.me/ -->
            <xsl:variable name="sitePath">
                <xsl:value-of select="string(normalize-space(concat(concat(normalize-space($httpProtocol), normalize-space($SERVER_NAME)), '/')))" />
            </xsl:variable>   
                   
                    <!-- {...SNIP...} -->
        </xsl:template>
    </xsl:stylesheet>
</Xsl>

The end result is a nice URL.  Here’s a sample output: http://iOnline247.me/
I'm not sure why the protocol isn't straightforward to get.  I may have missed something obvious, but I didn't see any other way of determining the protocol.  If there's an easier way, feel free to let me know.

No comments: