Author: chabotc
Date: Sun Aug  2 11:02:30 2009
New Revision: 800028

URL: http://svn.apache.org/viewvc?rev=800028&view=rev
Log:
Implemented os:Render and parsing dom structures as params in template library 
calls

Modified:
    incubator/shindig/trunk/php/src/gadgets/templates/TemplateParser.php

Modified: incubator/shindig/trunk/php/src/gadgets/templates/TemplateParser.php
URL: 
http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/templates/TemplateParser.php?rev=800028&r1=800027&r2=800028&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/templates/TemplateParser.php 
(original)
+++ incubator/shindig/trunk/php/src/gadgets/templates/TemplateParser.php Sun 
Aug  2 11:02:30 2009
@@ -19,7 +19,6 @@
  */
 
 //TODO support repeat tags on OSML tags, ie this should work: <os:Html 
repeat="${Bar}" />
-//TODO support os:render
 //TODO remove the os-templates javascript if all the templates are rendered on 
the server (saves many Kb's in gadget size)
 
 require_once 'ExpressionParser.php';
@@ -127,12 +126,26 @@
    * @param DOMNode $node
    */
   private function parseLibrary($tagName, DOMNode &$node) {
+    // Set the My context based on the node's attributes
     $myContext = $this->nodeAttributesToScope($node);
+    
+    // Template call has child nodes, those are params that can be used in a 
os:Render call, store them
+    $oldNodeContext = isset($this->dataContext['_os_render_nodes']) ? 
$this->dataContext['_os_render_nodes'] : array();
+    $this->dataContext['_os_render_nodes'] = array();
+    if ($node->childNodes->length) {
+      foreach ($node->childNodes as $childNode) {
+        if (isset($childNode->tagName) && ! empty($childNode->tagName)) {
+          $nodeParam = ($pos = strpos($childNode->tagName, ':')) ? 
trim(substr($childNode->tagName, $pos + 1)) : trim($childNode->tagName);
+          $this->dataContext['_os_render_nodes'][$nodeParam] = $childNode;
+        }
+      }
+    }
     // Parse the template library (store the My scope since this could be a 
nested call)
     $previousMy = $this->dataContext['My'];
     $this->dataContext['My'] = $myContext;
     $ret = $this->templateLibrary->parseTemplate($tagName, $this);
     $this->dataContext['My'] = $previousMy;
+    $this->dataContext['_os_render_nodes'] = $oldNodeContext;
     if ($ret) {
       // And replace the node with the parsed output
       $ownerDocument = $node->ownerDocument;
@@ -171,7 +184,7 @@
             $expression = $expressions[2][$i];
             $expressionResult = ExpressionParser::evaluate($expression, 
$this->dataContext);
             switch (strtolower($attr->name)) {
-
+              
               case 'repeat':
                 // Can only loop if the result of the expression was an array
                 if (! is_array($expressionResult)) {
@@ -215,7 +228,7 @@
                 }
                 return $node;
                 break;
-
+              
               case 'if':
                 if (! $expressionResult) {
                   return $node;
@@ -223,7 +236,7 @@
                   $node->removeAttribute('if');
                 }
                 break;
-
+              
               // These special cases that only apply for certain tag types
               case 'selected':
                 if ($node->tagName == 'option') {
@@ -236,7 +249,7 @@
                   throw new ExpressionException("Can only use selected on an 
option tag");
                 }
                 break;
-
+              
               case 'checked':
                 if ($node->tagName == 'input') {
                   if ($expressionResult) {
@@ -248,9 +261,9 @@
                   throw new ExpressionException("Can only use checked on an 
input tag");
                 }
                 break;
-
+              
               case 'disabled':
-                $disabledTags = array('input', 'button',
+                $disabledTags = array('input', 'button', 
                     'select', 'textarea');
                 if (in_array($node->tagName, $disabledTags)) {
                   if ($expressionResult) {
@@ -262,7 +275,7 @@
                   throw new ExpressionException("Can only use disabled on 
input, button, select and textarea tags");
                 }
                 break;
-
+              
               default:
                 // On non os-template spec attributes, do a simple str_replace 
with the evaluated value
                 $stringVal = 
htmlentities(ExpressionParser::stringValue($expressionResult), ENT_QUOTES, 
'UTF-8');
@@ -288,7 +301,6 @@
           $removeNode->parentNode->removeChild($removeNode);
         }
       }
-
     }
     return false;
   }
@@ -300,16 +312,15 @@
    */
   private function parseOsmlNode(DOMNode &$node) {
     $tagName = strtolower($node->tagName);
-    if (!$this->checkIf($node)) {
-       // If the OSML tag contains an if attribute and the expression 
evaluates to false
-       // flag it for removal and don't process it
-       return $node;
+    if (! $this->checkIf($node)) {
+      // If the OSML tag contains an if attribute and the expression evaluates 
to false
+      // flag it for removal and don't process it
+      return $node;
     }
-
     switch ($tagName) {
-
+      
       /****** Control statements ******/
-
+      
       case 'os:repeat':
         if (! $node->getAttribute('expression')) {
           throw new ExpressionException("Invalid os:Repeat tag, missing 
expression attribute");
@@ -356,7 +367,7 @@
         }
         return $node;
         break;
-
+      
       case 'os:if':
         $expressions = array();
         if (! $node->getAttribute('condition')) {
@@ -377,21 +388,21 @@
         }
         return $node;
         break;
-
+      
       /****** OSML tags (os: name space) ******/
-
+      
       case 'os:name':
         $this->parseLibrary('os:Name', $node);
         break;
-
+      
       case 'os:badge':
         $this->parseLibrary('os:Badge', $node);
         break;
-
+      
       case 'os:peopleselector':
         $this->parseLibrary('os:PeopleSelector', $node);
         break;
-
+      
       case 'os:html':
         if (! $node->getAttribute('code')) {
           throw new ExpressionException("Invalid os:Html tag, missing code 
attribute");
@@ -407,18 +418,34 @@
         
         return $node;
         break;
-
+      
       case 'os:render':
+        if (! ($content = $node->getAttribute('content'))) {
+          throw new ExpressionException("os:Render missing attribute: 
content");
+        }
+        $content = $node->getAttribute('content');
+        if (! isset($this->dataContext['_os_render_nodes'][$content])) {
+          throw new ExpressionException("os:Render, Unknown entry: " . 
htmlentities($content));
+        }
+        $nodes = $this->dataContext['_os_render_nodes'][$content];
+        $ownerDocument = $node->ownerDocument;
+        // Only parse the child nodes of the dom tree and not the (myapp:foo) 
top level element
+        foreach ($nodes->childNodes as $childNode) {
+          $importedNode = $ownerDocument->importNode($childNode, true);
+          $importedNode = $node->parentNode->insertBefore($importedNode, 
$node);
+          $this->parseNode($importedNode);
+        }
+        return $node;
         break;
-
+      
       /****** Extension - Tags ******/
-
+      
       case 'osx:flash':
         break;
-
+      
       case 'osx:navigatetoapp':
         break;
-
+      
       case 'osx:navigatetoperson':
         break;
     }


Reply via email to