You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by ch...@apache.org on 2009/07/24 00:22:17 UTC
svn commit: r797247 - in /incubator/shindig/trunk/php/src/gadgets:
render/GadgetBaseRenderer.php templates/ExpressionParser.php
templates/TemplateLibrary.php templates/TemplateParser.php
Author: chabotc
Date: Thu Jul 23 22:22:17 2009
New Revision: 797247
URL: http://svn.apache.org/viewvc?rev=797247&view=rev
Log:
Implemented support for the OSML library and the os:Badge, os:Name and os:PeopleSelector tags, remote template libraries is still todo but minor to implement now
Modified:
incubator/shindig/trunk/php/src/gadgets/render/GadgetBaseRenderer.php
incubator/shindig/trunk/php/src/gadgets/templates/ExpressionParser.php
incubator/shindig/trunk/php/src/gadgets/templates/TemplateLibrary.php
incubator/shindig/trunk/php/src/gadgets/templates/TemplateParser.php
Modified: incubator/shindig/trunk/php/src/gadgets/render/GadgetBaseRenderer.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/render/GadgetBaseRenderer.php?rev=797247&r1=797246&r2=797247&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/render/GadgetBaseRenderer.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/render/GadgetBaseRenderer.php Thu Jul 23 22:22:17 2009
@@ -36,7 +36,6 @@
public $dataContext = array();
public $unparsedTemplates = array();
public $dataInserts = array();
- public $templateLibraries = array();
/**
* Sets the $this->gadget property, and populates Msg, UserPref and ViewParams dataContext
@@ -109,7 +108,7 @@
// only load the template parser if there's any templates in the gadget content
require_once 'src/gadgets/templates/TemplateParser.php';
require_once 'src/gadgets/templates/TemplateLibrary.php';
- $templateLibrary = new TemplateLibrary();
+ $templateLibrary = new TemplateLibrary($this->gadget->gadgetContext);
}
foreach ($osTemplates[0] as $match) {
if (($renderedTemplate = $this->renderTemplate($match, $templateLibrary)) !== false) {
Modified: incubator/shindig/trunk/php/src/gadgets/templates/ExpressionParser.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/templates/ExpressionParser.php?rev=797247&r1=797246&r2=797247&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/templates/ExpressionParser.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/templates/ExpressionParser.php Thu Jul 23 22:22:17 2009
@@ -456,9 +456,6 @@
static private function compute($var1, $var2, $sym) {
$returnVal = 0;
// JSP EL doesn't allow $A = 'foo'; $b = 1; $C = $A + $B, so make sure that both variables are numberic when doing arithmatic or boolean operations
- if ($sym != 'empty' && (! is_numeric($var1) || ! is_numeric($var2))) {
- throw new ExpressionException("Can't perform arithmatic or boolean operation (" . htmlentities($sym) . ") on non numeric values: " . htmlentities($var1) . ", " . htmlentities($var2) . ")");
- }
//TODO variable type coercion in JSP EL is different from PHP, it might be prudent to code out the same behavior
switch ($sym) {
// Unhandled operators
Modified: incubator/shindig/trunk/php/src/gadgets/templates/TemplateLibrary.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/templates/TemplateLibrary.php?rev=797247&r1=797246&r2=797247&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/templates/TemplateLibrary.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/templates/TemplateLibrary.php Thu Jul 23 22:22:17 2009
@@ -31,10 +31,14 @@
private $osmlTags = array('os:Name', 'os:PeopleSelector', 'os:badge');
private $templates = array();
private $osmlLoaded = false;
+ private $gadgetContext;
+
+ public function __construct($gadgetContext) {
+ $this->gadgetContext = $gadgetContext;
+ }
public function parseTemplate($tag, $caller) {
$template = $this->getTemplate($tag);
- $ret = '';
if ($template->dom instanceof DOMElement) {
$templateDomCopy = new DOMDocument(null, 'utf-8');
// If this template pulls in any new style and/or javascript, add those to the document
@@ -68,18 +72,98 @@
*
* @param DOMElement $node
*/
- public function addTemplateByNode(DOMElement &$node) {
+ public function addTemplateByNode(DOMElement &$node, $scripts = false, $styles = false) {
$tag = $node->getAttribute('tag');
- $this->templates[$tag] = new TemplateLibraryEntry($node);
+ $template = new TemplateLibraryEntry($node);
+ if ($scripts) {
+ foreach ($scripts as $script) {
+ $template->addScript($script);
+ }
+ }
+ if ($styles) {
+ foreach ($styles as $style) {
+ $template->addstyle($style);
+ }
+ }
+ $this->templates[$tag] = $template;
+ }
+
+ private function addTemplateDef(DOMElement &$node, $globalScript, $globalStyle) {
+ $tag = $node->getAttribute('tag');
+ if (empty($tag)) {
+ throw new ExpressionException("Missing tag attribute on TemplateDef element");
+ }
+ $templateNodes = array();
+ foreach ($node->childNodes as $childNode) {
+ if (isset($childNode->tagName)) {
+ switch ($childNode->tagName) {
+ case 'Template':
+ $templateNodes[] = $childNode;
+ break;
+ case 'JavaScript':
+ $globalScript[] = new TemplateLibraryContent($childNode->nodeValue);
+ break;
+ case 'Style':
+ $globalStyle[] = new TemplateLibraryContent($childNode->nodeValue);
+ break;
+ }
+ }
+ }
+ // Initialize the templates after scanning the entire structure so that all scripts and styles will be included with each template
+ foreach ($templateNodes as $templateNode) {
+ $templateNode->setAttribute('tag', $tag);
+ $this->addTemplateByNode($templateNode, $globalScript, $globalStyle);
+ }
}
/**
- * Add an external template library by URL
+ * Add a template library set, for details see:
+ * http://opensocial-resources.googlecode.com/svn/spec/0.9/OpenSocial-Templating.xml#rfc.section.13
*
- * @param string $libraryUrl (ie: 'http://www.example.com/templates.xml')
+ * @param string $library
*/
- public function addTemplateLibrary($libraryUrl) {// add library by external URL and addTemplate for each entry contained in it
-}
+ public function addTemplateLibrary($library) {
+ libxml_use_internal_errors(true);
+ $doc = new DOMDocument(null, 'utf-8');
+ $doc->preserveWhiteSpace = true;
+ $doc->formatOutput = false;
+ $doc->strictErrorChecking = false;
+ $doc->recover = false;
+ $doc->resolveExternals = false;
+ if (! $doc->loadXML($library)) {
+ throw new ExpressionException("Error parsing template library:\n" . XmlError::getErrors($library));
+ }
+ // Theoretically this could support multiple <Templates> root nodes, which isn't quite spec, but owell
+ foreach ($doc->childNodes as $rootNode) {
+ $templateNodes = array();
+ $globalScript = array();
+ $globalStyle = array();
+ if (isset($rootNode->tagName) && $rootNode->tagName == 'Templates') {
+ foreach ($rootNode->childNodes as $childNode) {
+ if (isset($childNode->tagName)) {
+ switch ($childNode->tagName) {
+ case 'TemplateDef':
+ $this->addTemplateDef($childNode, $globalScript, $globalStyle);
+ break;
+ case 'Template':
+ $templateNodes[] = $childNode;
+ break;
+ case 'JavaScript':
+ $globalScript[] = new TemplateLibraryContent($childNode->nodeValue);
+ break;
+ case 'Style':
+ $globalStyle[] = new TemplateLibraryContent($childNode->nodeValue);
+ break;
+ }
+ }
+ }
+ }
+ // Initialize the templates after scanning the entire structure so that all scripts and styles will be included with each template
+ foreach ($templateNodes as $templateNode) {
+ $this->addTemplateByNode($templateNode, $globalScript, $globalStyle);
+ }
+ }
+ }
/**
* Check to see if a template with name $tag exists
@@ -105,15 +189,20 @@
}
private function loadOsmlLibrary() {
+ $container = $this->gadgetContext->getContainer();
+ $containerConfig = $this->gadgetContext->getContainerConfig();
+ $gadgetsFeatures = $containerConfig->getConfig($container, 'gadgets.features');
+ if (! isset($gadgetsFeatures['osml'])) {
+ throw new ExpressionException("Missing OSML configuration key in config/config.js");
+ } elseif (! isset($gadgetsFeatures['osml']['library'])) {
+ throw new ExpressionException("Missing OSML.Library configuration key in config/config.js");
+ }
+ $osmlLibrary = Config::get('container_path') . str_replace('config/', '', $gadgetsFeatures['osml']['library']);
+ if (! File::exists($osmlLibrary)) {
+ throw new ExpressionException("Missing OSML Library ($osmlLibrary)");
+ }
+ $this->addTemplateLibrary(file_get_contents($osmlLibrary));
$this->osmlLoaded = true;
- // preload osml lib, see container config key for location (gadget context->container config->osml->library
- /*
- "osml": {
- // OSML library resource. Can be set to null or the empty string to disable OSML
- // for a container.
- "library": "config/OSML_library.xml"
- }
- */
}
}
@@ -138,8 +227,8 @@
*
* @param unknown_type $script
*/
- public function addScript($script) {
- $this->script[] = new TemplateLibraryContent($script);
+ public function addScript(TemplateLibraryContent $script) {
+ $this->script[] = $script;
}
/**
@@ -147,7 +236,7 @@
*
* @param unknown_type $style
*/
- public function addStyle($style) {
+ public function addStyle(TemplateLibraryContent $style) {
$this->style[] = new TemplateLibraryContent($style);
}
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=797247&r1=797246&r2=797247&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/templates/TemplateParser.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/templates/TemplateParser.php Thu Jul 23 22:22:17 2009
@@ -76,8 +76,14 @@
}
}
- private function parseLibrary($tagName, DOMNode &$node) {
- // loop through attributes and assign vars to the context
+ /**
+ * Misc function that maps the node's attributes to a key => value array
+ * and results any expressions to actual values
+ *
+ * @param DOMElement $node
+ * @return array
+ */
+ private function nodeAttributesToScope(DOMElement &$node) {
$myContext = array();
if ($node->hasAttributes()) {
foreach ($node->attributes as $attr) {
@@ -95,21 +101,32 @@
}
}
}
+ return $myContext;
+ }
- // Parse the template library
+ /**
+ * Parses the specified template library
+ *
+ * @param string $tagName
+ * @param DOMNode $node
+ */
+ private function parseLibrary($tagName, DOMNode &$node) {
+ $myContext = $this->nodeAttributesToScope($node);
+ // 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'] = array();
+ $this->dataContext['My'] = $previousMy;
if ($ret) {
- // And replace the node with the parsed output
- $ownerDocument = $node->ownerDocument;
- foreach ($ret->childNodes as $childNode) {
- if ($childNode instanceOf DOMElement) {
- $importedNode = $ownerDocument->importNode($childNode, true);
- $node->parentNode->insertBefore($importedNode, $node);
- }
- }
+ // And replace the node with the parsed output
+ $ownerDocument = $node->ownerDocument;
+ foreach ($ret->childNodes as $childNode) {
+ if ($childNode instanceof DOMElement) {
+ $importedNode = $ownerDocument->importNode($childNode, true);
+ $node->parentNode->insertBefore($importedNode, $node);
+ }
+ }
$node->parentNode->removeChild($node);
}
}
@@ -245,6 +262,7 @@
// Control statements
+
case 'os:repeat':
if (! $node->getAttribute('expression')) {
throw new ExpressionException("Invalid os:Repeat tag, missing expression attribute");
@@ -293,23 +311,32 @@
// OSML tags (os: name space)
+
case 'os:name':
+ $this->parseLibrary('os:Name', $node);
break;
- case 'os:peopleselector':
+ case 'os:badge':
+ $myContext = $this->nodeAttributesToScope();
+ $previousMy = $this->dataContext['My'];
+ $this->dataContext['My'] = $myContext;
+ $ret = $this->templateLibrary->parseTemplate('os:Badge', $this);
+ $this->dataContext['My'] = $previousMy;
break;
- case 'os:badge':
+ case 'os:peopleselector':
+ $myContext = $this->nodeAttributesToScope();
+ $previousMy = $this->dataContext['My'];
+ $this->dataContext['My'] = $myContext;
+ $ret = $this->templateLibrary->parseTemplate('os:PeopleSelector', $this);
+ $this->dataContext['My'] = $previousMy;
break;
case 'os:html':
if (! $node->getAttribute('code')) {
throw new ExpressionException("Invalid os:Html tag, missing code attribute");
}
- //FIXME this seems to not work out to well, probably need to use the original domdocument to $doc->createTextNode() to make this work
- $newNode = new DOMText();
- $newNode->nodeValue = $node->getAttribute('code');
- $node->parentNode->replaceChild($newNode, $node);
+ $node->parentNode->replaceChild($node->ownerDocument->createTextNode($node->getAttribute('code')), $node);
break;
case 'os:render':
@@ -317,6 +344,7 @@
// Extension - Tags
+
case 'osx:flash':
break;
@@ -328,6 +356,7 @@
// Extension - Functions
+
case 'osx:parsejson':
break;