My previous blog post talked about how easy it was to insert flash in umbraco with my “Insert Flash” macro. In this post I will go into more depth and talk about the technology behind the module and provide an example of how the XSLT easily can be reused to insert Flash in your own XSLT macro.

The techinal part

To give a better understanding of what happens in the XSLT, I’ll devide the code up and explain each part of it.

The variables explained

trueFileURL: Finds a URL to the flash element, either via a media item from umbraco’s media section or via a typed URL
finalFileURL: Concats the “trueFileURL” variable with any enclosed url parameters
finalCssId: Uses the optional enclosed “cssId”, and if not present, the XSLT will use a C# helper method to generate an auto id – so there may be added an infinite number of flash elements on the same page, without having to specify a “cssId” to each of them

    <xsl:variable name="trueFileURL">
      <xsl:choose>
        <xsl:when test="$mediaFile != ''">
          <xsl:value-of select="$mediaFile/data[@alias = 'umbracoFile']"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$fileURL"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>

    <xsl:variable name="finalFileURL">
      <xsl:choose>
        <xsl:when test="$urlParameters != ''">
          <xsl:value-of select="concat($trueFileURL, $urlParameters)"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$trueFileURL"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>

    <xsl:variable name="finalCssId">
      <xsl:choose>
        <xsl:when test="string($cssId) != ''">
          <xsl:value-of select="$cssId"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="concat( 'ts-', randomTools:GetRandom() )"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>

Calling the template

We now have all the necessary information we need to insert a flash element through the “insertFlash” template.

    <xsl:call-template name="insertFlash">
      <xsl:with-param name="finalFileURL" select="$finalFileURL" />
      <xsl:with-param name="width" select="$width" />
      <xsl:with-param name="height" select="$height" />
      <xsl:with-param name="finalCssId" select="$finalCssId" />
    </xsl:call-template>

Where the true “magic” happens

We have reached the area where the flash element gets embedded. To embed the flash content i use swfobject, so i dont need to handle tart part – i just need to parse it the necessary parameters.

REMEMBER to remove the script reference to swfobject in the XSLT file and paste it instead into your HTML head section, so you don’t have a script reference for each flash element you insert through the macro

<xsl:template name="insertFlash">
  <xsl:param name="finalFileURL"/>
  <xsl:param name="width"/>
  <xsl:param name="height"/>
  <xsl:param name="finalCssId"/>

  <div id="{$finalCssId}">
    <xsl:text> </xsl:text>
  </div>

  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js">
    <xsl:text> </xsl:text>
  </script>

  <script type="text/javascript">
    <![CDATA[
    var flashvars = {};
    var params = {};
    var attributes = {};

    var path = "]]><xsl:value-of select="$finalFileURL" /><![CDATA[";
    var cssId = "]]><xsl:value-of select="$finalCssId" /><![CDATA[";
    var width = "]]><xsl:value-of select="$width" /><![CDATA[";
    var height = "]]><xsl:value-of select="$height" /><![CDATA[";

    swfobject.embedSWF( path, cssId, width, height, "9.0.0", false, flashvars, params, attributes);
    ]]>
  </script>

</xsl:template>

Reuse the XSLT to easy insert flash in you own XLST macro’s

It’s easy to reuse the “insertFlash” XSLT template in your own XSLT macro. The only thing you need to do is to import the insertFlash.xslt file in the top of your XSLT, and call the “insertFlash” template with your parameters. Below is an example:

<xsl:include href="insertFlash.xslt"/>

<xsl:template match="/">
  <div id="flashContent"></div>

  <xsl:call-template name="insertFlash">
    <xsl:with-param name="finalFileURL" select="$currentPage/data[@alias = 'flashFile']" />
    <xsl:with-param name="width" select="200" />
    <xsl:with-param name="height" select="100" />
    <xsl:with-param name="finalCssId" select="flashContent" />
  </xsl:call-template>
</xsl:template>

Next time

Stay tuned for my next blog post where I will explain how to enable your XSLT to support both the umbraco 4.0 and 4.5 xml schema

The complete XSLT

<xsl:template match="/">

  <xsl:variable name="mediaFile" select="/macro/mediaFile/*"/>
  <xsl:variable name="fileURL" select="/macro/fileURL"/>
  <xsl:variable name="width" select="/macro/flashWidth"/>
  <xsl:variable name="height" select="/macro/flashHeight"/>
  <xsl:variable name="cssId" select="/macro/cssId"/>
  <xsl:variable name="urlParameters" select="/macro/urlParameters"/>

  <xsl:if test="$mediaFile != '' or $fileURL != ''">
    <xsl:variable name="trueFileURL">
      <xsl:choose>
        <xsl:when test="$mediaFile != ''">
          <xsl:value-of select="$mediaFile/data[@alias = 'umbracoFile']"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$fileURL"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>

    <xsl:variable name="finalFileURL">
      <xsl:choose>
        <xsl:when test="$urlParameters != ''">
          <xsl:value-of select="concat($trueFileURL, $urlParameters)"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$trueFileURL"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>

    <xsl:variable name="finalCssId">
      <xsl:choose>
        <xsl:when test="string($cssId) != ''">
          <xsl:value-of select="$cssId"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="concat( 'ts-', randomTools:GetRandom() )"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>

    <xsl:call-template name="insertFlash">
      <xsl:with-param name="finalFileURL" select="$finalFileURL" />
      <xsl:with-param name="width" select="$width" />
      <xsl:with-param name="height" select="$height" />
      <xsl:with-param name="finalCssId" select="$finalCssId" />
    </xsl:call-template>

  </xsl:if>

</xsl:template>

<xsl:template name="insertFlash">
  <xsl:param name="finalFileURL"/>
  <xsl:param name="width"/>
  <xsl:param name="height"/>
  <xsl:param name="finalCssId"/>

  <div id="{$finalCssId}">
    <xsl:text> </xsl:text>
  </div>

  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js">
    <xsl:text> </xsl:text>
  </script>

  <script type="text/javascript">
    <![CDATA[
    var flashvars = {};
    var params = {};
    var attributes = {};

    var path = "]]><xsl:value-of select="$finalFileURL" /><![CDATA[";
    var cssId = "]]><xsl:value-of select="$finalCssId" /><![CDATA[";
    var width = "]]><xsl:value-of select="$width" /><![CDATA[";
    var height = "]]><xsl:value-of select="$height" /><![CDATA[";

    swfobject.embedSWF( path, cssId, width, height, "9.0.0", false, flashvars, params, attributes);
    ]]>
  </script>

</xsl:template>

<msxml:script language="c#" implements-prefix="randomTools">
  <msxml:assembly href="../bin/umbraco.dll"/>
  <![CDATA[
    //Basic idea from http://our.umbraco.org/wiki/reference/xslt/snippets/getting-a-series-of-unique-random-numbers

    /// <summary>
    /// Gets a random integer that falls between the specified limits
    /// </summary>
    /// <returns>A random integer</returns>
    public static int GetRandom() {
      Random r = umbraco.library.GetRandom();
      int returnedNumber = 0;
      lock (r) {
        returnedNumber = r.Next();
      }
      return returnedNumber;
    }
  ]]>
</msxml:script>