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;
}