<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xsl:stylesheet SYSTEM "http://commons.omniupdate.com/dtd/standard.dtd">

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:fn="http://omniupdate.com/XSL/Functions"
    xmlns:ou="http://omniupdate.com/XSL/Variables"
    xmlns:ouc="http://omniupdate.com/XSL/Variables"
    exclude-result-prefixes="xsl xs fn ou ouc">
    
    <!-- 
        The purpose of the following two templates is to make page properties (PCF params), directory 
        variables, and system parameters (such as ou:site) available to JS and PHP scripts running in a page.
        
        Each template reads two parameters, named "globalProps" and "pageProps", which are defined at the 
        bottom of this file. These parameters contain <property> nodes that essentially mirror the parameters 
        we want to expose to scripts.
        
        For each <property> child node of <xsl:param name="globalProps">, the first template ("params_to_js") 
        will add an equivalent property to an OUC.globalProps JavaScript object (which is created if it 
        doesn't already exist). Similarly, for each <property> child node of <xsl:param name="pageProps">, 
        this template will add an equivalent property to an OUC.pageProps object. These properties are now 
        available to any JS scripts running in the page.
        
        The OUC.props object is created by combining all the properties of OUC.globalProps and OUC.pageProps. 
        If a property with the same name exists in both objects, the value of the one from pageProps 
        overwrites the value of the one from globalProps.
        
        The second template ("params_to_php") does the equivalent for PHP, creating arrays 
        $OUC['globalProps'], $OUC['pageProps'], and $OUC['props'].
    -->
    
    <xsl:template name="params_to_js">
        <script type="text/javascript">
            var OUC = OUC || {};
            OUC.globalProps = OUC.globalProps || {};
            OUC.pageProps = OUC.pageProps || {};
            OUC.props = OUC.props || {};
            
        <xsl:for-each select="$globalProps/property[not(@private)]">
            OUC.globalProps['<xsl:value-of select="./@name"/>'] = "<xsl:value-of select="."/>";</xsl:for-each>
        <xsl:for-each select="$pageProps/property">
            OUC.pageProps['<xsl:value-of select="./@name"/>'] = "<xsl:value-of select="."/>";</xsl:for-each>
            
            var key;
            for (key in OUC.globalProps) {
                OUC.props[key] = OUC.globalProps[key];
            }
            for (key in OUC.pageProps) {
                OUC.props[key] = OUC.pageProps[key];
            }
        </script>
    </xsl:template>
    
    <!-- 
        NOTE: You should call the following "params_to_php" template only on publish. If it is called on 
        preview, everything after the first ">" character in the PHP script will appear on the page as text.
        If you can figure out a good, clean way to avoid this problem, go for it and let everyone know how.
    -->
    
    <xsl:template name="params_to_php">
        <xsl:text disable-output-escaping="yes">
            &lt;?php
            if (!$OUC)                $OUC = array();
            if (!$OUC['globalProps']) $OUC['globalProps'] = array();
            if (!$OUC['pageProps'])   $OUC['pageProps'] = array();
            if (!$OUC['props'])       $OUC['props'] = array();
        </xsl:text>
        <xsl:for-each select="$globalProps/property[not(@private)]">
            $OUC['globalProps']['<xsl:value-of select="./@name"/>'] = "<xsl:value-of select="."/>";</xsl:for-each>
        <xsl:for-each select="$pageProps/property">
            $OUC['pageProps']['<xsl:value-of select="./@name"/>'] = "<xsl:value-of select="."/>";</xsl:for-each>
        <xsl:text disable-output-escaping="yes">
            
            foreach ($OUC['globalProps'] as $key => $val) $OUC['props'][$key] = $val;
            foreach ($OUC['pageProps']   as $key => $val) $OUC['props'][$key] = $val;
        ?></xsl:text>
    </xsl:template>

    <!--
        The <xsl:param> element below contains, for every system parameter, an equivalent <property> node 
        whose name is the same but without the "ou:" prefix.
        
        Any directory variables that you want to expose to page scripts must also have <property> entries
        within this <xsl:param> element.
    -->
    <xsl:param name="globalProps">
        <property name="action" private="true"><xsl:value-of select="$ou:action"/></property>
        <property name="created"><xsl:value-of select="$ou:created"/></property>
        <property name="dirname"><xsl:value-of select="$ou:dirname"/></property>
        <property name="feed"><xsl:value-of select="$ou:feed"/></property>
        <property name="filename"><xsl:value-of select="$ou:filename"/></property>
        <property name="httproot"><xsl:value-of select="$ou:httproot"/></property>
        <property name="modified"><xsl:value-of select="$ou:modified"/></property>
        <property name="path"><xsl:value-of select="$ou:path"/></property>
        <property name="root" private="true"><xsl:value-of select="$ou:root"/></property>
        <property name="site"><xsl:value-of select="$ou:site"/></property>
        <property name="firstname" private="true"><xsl:value-of select="$ou:firstname"/></property>
        <property name="lastname" private="true"><xsl:value-of select="$ou:lastname"/></property>
        <property name="username" private="true"><xsl:value-of select="$ou:username"/></property>
        <property name="email" private="true"><xsl:value-of select="$ou:email"/></property>
		
    <!-- Add <property> nodes for directory variables below. Remove the two examples.
        <property name="favicon_src"><xsl:value-of select="$ou:favicon_src"/></property>
        <property name="title_img_src"><xsl:value-of select="$ou:title_img_src"/></property> -->
		
    </xsl:param>
    
    <!-- 
        The <xsl:param> element below is for page properties (PCF parameters). Since the matching
        <property> nodes are generated programmatically, there is no need to manually create them. 
        The code depends on the availability of the "ou:pcfparam" function, which must therefore 
        be available to this stylesheet. (The function is usually in pcf-params.xsl.)
    -->
    <xsl:param name="pageProps">
        <xsl:for-each select="//parameter">
            <property name="{./@name}"><xsl:value-of select="ou:pcfparam(./@name)"/></property>
        </xsl:for-each>
    </xsl:param>
    
</xsl:stylesheet>
