Skip to content

Instantly share code, notes, and snippets.

@keif
Forked from larscwallin/README.txt
Created January 16, 2012 15:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save keif/1621510 to your computer and use it in GitHub Desktop.
Save keif/1621510 to your computer and use it in GitHub Desktop.
SIMPLX Widgeteer 0.8.4
SIMPLX Widgeteer 0.8.4.kb
UPDATE 120116 10:59
Made a nested foreach loop to handle placeholders with the same parent reference.
UPDATE 120115 16:59
Changed so that the default chunkMatchingSelector is "", which is more likely to be the case.
UPDATE 120114 02:57
Updated the reset concept again as i had not considered the problem
enough. Now the reference should be correctly set to the root of the
traversal history stack for every new placeholder in the iteration.
UPDATE 120113 00:04
Found that i didn't reset the array iterator when going through namespaced placeholders. Fixed but untested.
UPDATE 111120 13:26
NEW FEATURES:
Added event more debug info to make it easy to see the parsing progress.
UPDATE 111119 15:41
NEW FEATURES:
Added plenty of debug info to make it easy to see the parsing progress.
UPDATE 111117 16:56
NEW FEATURES:
Added Chunks and Snippet call :)
1 Dataset
3 Templates
1 Snippet call
Added Chunk caching by using a static class variable.
I have added simple support for peeking and grabbing values which are located in the nested structure INSIDE the current object.
Example:
Lets say that we are parsing this contact object,
---------------------------------------------------------------
{
"objecttypename":"contact",
"firstname":"Lisa",
"lastname":"Johnson",
"phone":"+46 555 131415",
"email":"lisa@internet.com",
"address":[
{
"objecttypename":"address",
"type":"home",
"name":"My Little House",
"street":"That Way 123",
"geodata":{
"longitude":"-70.044636",
"latitude":"+42.689060"
}
}
]
}
---------------------------------------------------------------------
You can now do this to get the "longitude" while at the root level of the object,
[[+address.geodata.longitude]]
:D
UPCOMING
Conditional peek and grab using the same method as the Controller. This will give you regexp support etc.
<html>
<head>
<title>[[++site_name]] - [[*pagetitle]]</title>
<base href="[[++site_url]]" />
</head>
<body>
<h2>Something should show up down there</h2>
[[!simplx_widgeteer?
&dataSetUrl=`http://modxclub.com/rss-feed`
&preprocessor=`widgeteer_preprocessor_xml2json`
&useChunkMatching=`true`
&chunkPrefix=`modx.feed.tpl_`
]]
</body>
</html>
<b>[[+title]]</b>
<p>[[+item]]</p>
<p> - [[+title]]</p>
[[+channel]]
<hr/>
<?php
/*
Used to load an external class definition.
Ditched this approach to make it simple to package the snippet using the PacMan addon.
Below the class definition you find the actual snippet code...
*/
//require_once($modx->config['base_path']."assets/snippets/simplx/simplx_widgeteer.php");
if(!class_exists('simplx_widgeteer')){
class simplx_widgeteer{
public $debugmode = true;
public $dataSet;
public $dataSetUrl;
public $dataSetArray;
public $dataSetRoot;
public $useChunkMatching = true;
public $chunkMatchingSelector = '';
public $staticChunkName = '';
public $chunkPrefix = '';
public $chunkMatchRoot = false;
public $preprocessor = '';
private $iterator = 0;
private $traversalStack = array();
private $traversalObjectStack = array();
private $traversalContext = '';
// Only one instance per request.
private static $chunkCache = array();
public function preprocess($dSet){
global $modx;
if ($this->preprocessor) {
//if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: preprocess(), Processing "'.$dSet.'" using Snippet "'.$this->preprocessor.'".');
$dSet = $modx->runSnippet($this->preprocessor,array('dataSet'=>$dSet));
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: preprocess(), Done processing. Dataset now contains "'.$dSet.'".');
}
return $dSet;
}
public function loadDataSet($dSet){
global $modx;
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: loadDataSet(), Dataset contains "'.$dSet.'".');
$dSet = $this->preprocess($dSet);
$this->dataSet = $dSet;
//if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: loadDataSet(), Dataset after preprocessing "'.$dSet.'".');
$this->dataSetArray = $this->decode($dSet);
if(is_array($this->dataSetArray)){
//if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: loadDataSet(), Dataset after preprocessing "'.$dSet.'".');
return true;
}else{
$modx->log(modX::LOG_LEVEL_ERROR, 'Widgeteer: loadDataSet(): Exception, Unable to decode the dataset.');
return false;
}
//$this->cacheDataSet($dSet);
}
public function loadCachedDataSet($dataSetKey){
global $modx;
$dSet = $modx->cacheManager->get($dataSetKey);
if ($dSet) {
return $dSet;
}else{
return '';
}
}
public function cacheDataSet($dSet){
global $modx;
// For now we just cache remote dataSets...
if ($this->dataSetUrl != '') {
$dataSetLocator = urlencode($this->dataSetUrl);
$modx->cacheManager->set(('dataSet.'.$dataSetLocator),$this->dataSetArray);
}
}
public function loadDataSource($dSourceURL){
global $modx;
$result = false;
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: loadDataSource(), Fetching from URL "'.$dSourceURL.'".');
if ($dSourceURL != "") {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $dSourceURL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
$this->dataSetUrl = $dSourceURL;
if ($output != "") {
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: loadDataSource(), Got the following output "'.$output.'".<br/><br/>');
$result = $this->loadDataSet($output);
if($result){
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: loadDataSource(), loadDataSet() returned "true".');
}else{
$modx->log(modX::LOG_LEVEL_ERROR, 'Widgeteer: loadDataSource(): Exception, loadDataSet() returned "false". Aborting.');
}
}else{
$modx->log(modX::LOG_LEVEL_ERROR, 'Widgeteer: loadDataSource(): Exception, no valid output from "'.$dSourceURL.'".');
}
}
}
public function setDataRoot($elName){
$this->dataSetRoot = $elName;
$this->dataSetArray = $this->dataSetArray[$this->dataSetRoot];
}
public function decode($json){
return json_decode($json,true);
}
public function encode($object){
return json_encode($object);
}
function parse(&$obj=null){
global $modx;
$result = '';
if(!isset($obj)){
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: parse() Got no initial argument.');
if($this->dataSetArray){
$obj = &$this->dataSetArray;
}else{
$modx->log(modX::LOG_LEVEL_ERROR, 'Widgeteer: parse(): Exception, Missing valid dataset. Aborting.');
return false;
}
}else{
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: parse() starting with argument "'.json_encode($obj).'".');
}
if($this->dataSetRoot != ''){
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: parse(), Checking existance of dataSetRoot "'.$this->dataSetRoot.'".');
/*
if(array_key_exists($this->dataSetRoot,$this->dataSetArray)){
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: parse(), dataSetRoot "'.$this->dataSetRoot.'" was found in the dataset.');
}else{
$modx->log(modX::LOG_LEVEL_ERROR, 'Widgeteer: parse(): Exception, dataSetRoot "'.$this->dataSetRoot.'" was NOT found in the dataset. Aborting.');
return false;
}
*/
$context = $this->dataSetRoot;
}
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG,'');
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: parse(), Starting recursive parse.');
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: parse(), -------------------------------------');
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG,'');
foreach ($obj as $key => &$val) {
switch($this->typeCheck($val)){
case "list":
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: parse(), This item ("'.$key.'") is a list ([]). Calling parseList().');
$result = $this->parseList($val,$key);
break;
case "object":
if(!$this->dataSetRoot){
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: parse(), This item ("'.$key.'") is an object ({}). Calling parseObject().');
$result = $this->parseObject($val,$key);
}
break;
case "simple":
if(!$this->dataSetRoot){
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: parse(), This item ("'.$key.'") is a simple type (string or number). Calling parseSimpleType().');
$result = $this->parseSimpleType($val,$key);
}
break;
default :
break;
}
$obj[$key] = $result;
}
$result = implode(' ',$obj);
// If this is the last render call we have the option to wrap the result in the
// rootChunk.
if($this->chunkMatchRoot == 'true'){
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: parse(), Chunk matching root element.');
$rootChunk = $modx->getChunk(($this->chunkPrefix.$this->dataSetRoot));
if($rootChunk != ''){
$result = str_replace('[[+content]]',$result,$rootChunk);
}else{
}
}
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: parse(), Done parsing. Returning "'.$result.'".');
return $result;
}
function parseObject(&$obj,$context){
global $modx;
$result = '';
/*
FIX
Add a reference to the actual, untemplated, object.
Now the stack contains templated data
*/
// Add the object to the stack
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG,
'
Widgeteer: parseobject() adding object "'.$context.'" to stack "'.json_encode($obj).'".
');
$this->traversalObjectStack[$context] = $obj;
foreach ($obj as $key => &$val) {
switch($this->typeCheck($val)){
case 'list':
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: parseObject(), This item ("'.$key.'") is a list ([]). Calling parseList().');
$result = $this->parseList($val,$key);
break;
case 'object':
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: parseObject(), This item ("'.$key.'") is an object ({}). Calling parseObject().');
$result = $this->parseObject($val,$key);
break;
case 'simple':
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: parseObject(), This item ("'.$key.'") is a simple type (string or number). Calling parseSimpleType().');
$result = $this->parseSimpleType($val,$key);
break;
default:
break;
}
$obj[$key] = $result;
}
$result = $this->template($obj,$context);
//if($debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: parseobject() popping object "'.$context.'" from stack.');
// Pop it from the stack
//array_pop($this->traversalObjectStack);
return $result;
}
function parseList(&$list,&$context){
global $modx;
$result = '';
$iterator = 0;
foreach ($list as &$index) {
switch($this->typeCheck($index)){
case 'list':
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: parseList(), This item ("'.$context.'") is a list ([]). Calling parseList().');
$result = $this->parseList($index,$iterator);
break;
case 'object':
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: parseList(), This item ("'.$context.'") is an object ({}). Calling parseObject().');
$result = $this->parseObject($index,$context);
break;
case 'simple':
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: parseList(), This item ("'.$context.'") is a simple type (string or number). Calling parseSimpleType().');
$result = $this->parseSimpleType($index,$context);
break;
default:
break;
}
$list[$iterator] = $result;
$iterator++;
}
$result = implode(' ',$list);
return $result;
}
function parseSimpleType(&$value,&$context){
global $modx;
$prefContext = ($this->chunkPrefix.$context);
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: parseSimpleType(), This item ("'.$context.'") contains value "'.$value.'".');
if(!array_key_exists($prefContext,self::$chunkCache)){
self::$chunkCache[$prefContext] = $modx->getChunk($prefContext);
$chunk = self::$chunkCache[$prefContext];
}else{
$chunk = self::$chunkCache[$prefContext];
}
if($chunk){
$result = str_replace('[[+value]]',$value,$chunk);
return $result;
}else{
return $value;
}
}
function parseFieldPointer(&$type,&$context){
global $modx;
$chunk = $modx->getChunk(($this->chunkPrefix.$context));
if($chunk != ''){
$result = str_replace('[[+value]]',$type,$chunk);
return $result;
}else{
return $type;
}
}
function typeCheck(&$var){
$val = '';
if(is_array($var)){
if ($this->is_assoc($var)) {
$val = 'object';
}else{
$val = 'list';
}
}else{
$val = 'simple';
}
return $val;
}
function template(&$collection,$tmplName) {
global $modx;
$res = null;
$tempVar;
if ($this->useChunkMatching) {
// Get the current chunkMatchingSelector key from the $collection list.
// This is used later to choose which Chunk to use as template.
if(array_key_exists($this->chunkMatchingSelector,$collection)){
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: template(), chunkMatchingSelector "'.$this->chunkMatchingSelector.'" was found in collection "'.$tmplName.'".');
$chunkName = $collection[$this->chunkMatchingSelector];
}else{
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: template(), chunkMatchingSelector "'.$this->chunkMatchingSelector.'" was NOT found in collection "'.$tmplName.'".');
$chunkName = '';
}
if ($chunkName === '') {
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: template(), Chunk name is "".');
/*
If nothing was returned from the assignment above we have found no selector. We have to
use another way to match the current collection in the $collection list.
The way that json is structured it is very likely that the parent key is the name of the
object type in the collection.
Example
{
"contact":[
{
"name":"Mini Me",
"shoesize":{"eu":"23"}
},
{
"name":"Big Dude",
"shoesize":{"eu":"49"}
}
]
}
In the example above its implied that each item in the "contact" collection is of typ... contact :)
Similarly the "shoesize" property is a complex value that would be best matched to the key "shoesize".
*/
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: template(), It is very likely that the parent key is the name of the object type. Setting $chunkName to "'.$tmplName.'"');
$chunkName = $tmplName;
}else{
}
if($chunkName != ''){
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: template(), parsing Chunk "'.$chunkName.'".');
//$tempVar = $modx->parseChunk(($this->chunkPrefix.''.$chunkName), $collection, '[[+', ']]');
$tempVar = $this->parseChunk(($this->chunkPrefix.''.$chunkName), $collection, '[[+', ']]');
$res .= $tempVar;
}else{
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: template(), $chunkName is still empty.');
}
}else{
//$tempVar .= $modx->parseChunk($this->staticChunkName, $collection, '[[+', ']]');
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: template(), Chunk matching is turned off. Using static Chunk "'.$this->staticChunkName.'".');
$tempVar .= $this->parseChunk($this->staticChunkName, $collection, '[[+', ']]');
$res .= $tempVar;
}
if(!$res){
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: template(), parseChunk() returned an invalid result. Setting the template result to "".');
$res = '';
}else{
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: template(), parseChunk() returned a valid result. Calling templateNSPlaceholders() to find and template namespaced tags.');
$res = $this->templateNSPlaceholders($res);
}
return $res;
}
function parseChunk($chunkName, $chunkArr, $prefix='[[+', $suffix=']]'){
global $modx;
$chunk='';
if(!array_key_exists($chunkName,self::$chunkCache)){
self::$chunkCache[$chunkName] = $modx->getChunk($chunkName);
$chunk = self::$chunkCache[$chunkName];
}else{
$chunk = self::$chunkCache[$chunkName];
}
if (!empty($chunk) || $chunk === '0') {
if(is_array($chunkArr)) {
reset($chunkArr);
while (list($key, $value)= each($chunkArr)) {
$chunk= str_replace($prefix.$key.$suffix, $value, $chunk);
}
}
}
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: parseChunk(), Done parsing, returning "'.$chunk.'".');
return $chunk;
}
// Utility function to check type of Array
function is_assoc (&$arr) {
try{
return (is_array($arr) && (!count($arr) || count(array_filter(array_keys($arr),'is_string')) == count($arr)));
}catch(Exception $e){
return false;
}
}
// Templates namespaced placeholders
function templateNSPlaceholders($chunk){
global $modx;
$collection = null;
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: Starting templateNSPlaceholders(). Checking "'.$chunk.'"');
// Find any unparsed placeholders
$nsSeparator = '.';
$forwardSeparator = '-';
$backSeparator = '+';
$patternSeparator = '?';
$placeholders;
$pattern = "/\[\[\+[^\]]*\]\]/";
preg_match_all($pattern, $chunk, $placeholders);
if(!is_array($placeholders) || count($placeholders[0])<=0){
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: templateNSPlaceholders(), there where no placeholders in this chunk. Returning what we got.');
return $chunk;
}
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: templateNSPlaceholders(), we got placeholders "'.json_encode($placeholders).'"');
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG,' ');
// Set local references to the traversal stack (history stack). Local refs should speed up access.
$stackRootPointer = &$this->traversalObjectStack;
$pointer = &$stackRootPointer;
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: templatePlaceholders() The traversal stack has the following items: "'.json_encode($pointer).'"');
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG,' ');
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: templatePlaceholders() Going into the placeholders foreach.');
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG,' ');
foreach($placeholders as $placeholder){
foreach ($placeholder as $ph) {
$value = '';
// Make a local copy for performance impr.
$current = $ph;
// Only parse the placeholder if it has a separator
if(!strpos($current,$nsSeparator)===false){
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: templatePlaceholders() the current placeholder is: "'.$current.'"');
// Remove the tags
$path = str_replace(array('[[+',']]'), '', $current);
// Explode the current placeholder using the namespace separator
$parts = explode($nsSeparator,$path);
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: templatePlaceholders() After the cleanup the placeholder looks like this: "'.json_encode($parts).'" .');
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: templatePlaceholders() Looping through the parts of the current placeholder.');
// Iteration counter
$i = 1;
// Lets loop through all parts in the namespace array.
foreach($parts as $part){
switch($part){
case '<':
break;
case '>':
break;
case '?':
break;
default:
/*
Ok, lets look in the current array position if we have a match for the namespace part.
Right now we only support cronological paths so if the part is not found, its no
use iterating on, so we simply return the chunk we got.
*/
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: templatePlaceholders() Rotation nr "'.$i.'".');
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG,' ');
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: templatePlaceholders() The current part is "'.$part.'".');
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG,' ');
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: templatePlaceholders() Lets start looking in the stack at our present position.');
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG,' ');
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: templatePlaceholders() The current pointer in the stack contains: "'.json_encode($pointer).'".');
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG,' ');
// Get a pointer to the current value
$value = &$pointer[$part];
if(!isset($value)){
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: templatePlaceholders() The current position in the stack had no "'.$part.'" reference. This means that the path is invalid and we can set value to "".');
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG,' ');
unset($value);
$value = '';
}
/*
Got something! Lets see if its a string/num/bool, or an array...
*/
// If we still have an array, we havent reached the target
if(is_array($value)){
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: templatePlaceholders() We got an array back from the current stack position "'.json_encode($value).'".');
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG,' ');
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: templatePlaceholders() We got an array back from the current stack position "'.json_encode($value).'".');
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG,' ');
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: templatePlaceholders() Backing up to the previous item in the stack position.');
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG,' ');
$i++;
// unset the pointer so that we dont screw with the history stack
unset($pointer);
// Redirect the pointer ref to the new, current position in the traversal history stack
$pointer = &$value;
// unset the value ref so that we dont screw with the history stack
unset($value);
}else{
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: templatePlaceholders() The current position returned the string "'.$value.'". Lets keep it for templating.');
// Else we can parse and return.
// Replace the original placeholder with the retrieved value.
//$chunk = str_replace(('[[+'.$currentMatch.']]'),$value,$chunk);
}
}
}
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: templatePlaceholders() done with parsing this placeholder. Lets replace the it with this value "'.$value.'"');
// Replace the original placeholder with the retrieved value.
$chunk = str_replace(('[[+'.$path.']]'),$value,$chunk);
// unset the pointer so that we dont screw with the history stack
unset($pointer);
// Backup to the beginning of the stack so that the next placeholder can reference the complete history.
$pointer = $stackRootPointer;
}
}
}
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: templatePlaceholders() done with parsing all placeholders.');
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG,' ');
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG, 'Widgeteer: templatePlaceholders() returning "'.$chunk.'"');
if($this->debugmode) $modx->log(modX::LOG_LEVEL_DEBUG,' ');
return $chunk;
}
// Facilitates Chunk caching
function getChunkTemplate($templateName){
if(array_key_exists($templateName,self::$chunkCache)){
return self::$chunkCache[$templateName];
}else{
self::$chunkCache[$templateName] &= $modx->getChunk($templateName);
return self::$chunkCache[$templateName];
}
}
// Facilitates Chunk processing using cached objects
function parseChunkTemplate($templateName,&$collection){
if(array_key_exists($templateName,self::$chunkCache)){
return $modx->parseChunk(($this->chunkPrefix.''.$chunkName), $collection, '[[+', ']]');
}else{
return $modx->getChunk($templateName);
}
}
}
}else{
}
/*
----------------------------------------------------------------------------------------------
Below is the actual snippet code which sets defaults, validates the input, instatiates the
Widgeteer object and runs the logic...
*/
$dataSourceUrl = isset($dataSourceUrl) ? $dataSourceUrl : 'null';
$dataSourceUrl = isset($dataSetUrl) ? $dataSetUrl : $dataSourceUrl; //New interface parameter to mend naming consistency issue.
$staticChunkName = isset($staticChunkName) ? $staticChunkName : 'null';
$dataSet = isset($dataSet) ? ($dataSet) : 'null';
$useChunkMatching = isset($useChunkMatching) ? $useChunkMatching : true;
$chunkMatchingSelector = isset($chunkMatchingSelector) ? $chunkMatchingSelector : '';
$dataSetRoot = isset($dataSetRoot) ? $dataSetRoot : 'null';
$chunkMatchRoot = isset($chunkMatchRoot) ? $chunkMatchRoot : false;
$chunkPrefix = isset($chunkPrefix) ? $chunkPrefix : '';
$dataSet = str_replace(array('|xq|','|xe|','|xa|'),array('?','=','&') , $dataSet);
$preprocessor = isset($preprocessor) ? $preprocessor : '';
$debugmode = isset($debugmode) ? $debugmode : true;
if($debugmode){
$modx->setLogLevel(modX::LOG_LEVEL_DEBUG);
}
if($dataSourceUrl == 'null' && $dataSet == 'null'){
print '{"result":[{"objecttypename":"exception","errorcode"="0","message":"The dataSet parameter is empty."}]}';
}else{
$w = new simplx_widgeteer();
$w->debugmode = $debugmode;
/*
PHP bug perhaps? $useChunkMatching evaluates as true even if its false!?
I have to "switch poles" in order to get the right effect...
*/
if($useChunkMatching && $staticChunkName != 'null'){
$w->useChunkMatching = false;
$w->staticChunkName = $staticChunkName;
}else{
$w->useChunkMatching = true;
$w->chunkMatchingSelector = $chunkMatchingSelector;
}
$w->chunkMatchRoot = $chunkMatchRoot;
$w->chunkPrefix = $chunkPrefix;
$w->preprocessor = $preprocessor;
if($dataSourceUrl != 'null'){
$dataSourceUrl = urldecode($dataSourceUrl);
$w->loadDataSource($dataSourceUrl);
}else{
$w->loadDataSet(utf8_encode($dataSet));
}
if($dataSetRoot != 'null'){
$w->setDataRoot($dataSetRoot);
}
return $w->parse();
}
{"list":{
"contacts":[
{
"objecttypename":"contact",
"firstname":"Lars",
"lastname":"Wallin",
"phone":"+46 555 155555",
"email":"lars@internet.com",
"address":[
{
"type":"home",
"name":"My Home",
"street":"My Way 7",
"geodata":{
"longitude":"-74.044636",
"latitude":"+40.689060",
"sealevel":{"m":"1000"}
},
"geodata2":{
"longitude":"-72.044636",
"latitude":"+41.689060"
}
},
{
"type":"away",
"name":"My Summer House",
"street":"Back wood 45"
}
]
},
{
"objecttypename":"contact",
"firstname":"Lisa",
"lastname":"Johnson",
"phone":"+46 555 131415",
"email":"lisa@internet.com",
"address":[
{
"objecttypename":"address",
"type":"home",
"name":"My Little House",
"street":"That Way 123",
"geodata":{
"longitude":"-70.044636",
"latitude":"+42.689060"
},
"geodata2":{
"longitude":"-71.044636",
"latitude":"+12.689060"
}
}
]
},
{
"objecttypename":"contact",
"firstname":"Peter",
"lastname":"Swift",
"phone":"+46 555 757677",
"email":"peter@internet.com",
"address":[
{
"objecttypename":"address",
"type":"home",
"name":"Any Bench",
"street":"Central Park",
"geodata":{
"longitude":"-71.044636",
"latitude":"+43.689060"
}
}
]
}
]
}}
[[!simplx_widgeteer?
&dataSet=`[[$widgeteer_dataset_contactlist]]`
&dataSetRoot=`list`
&useChunkMatching=`true`
&chunkPrefix=`widgeteer_template_`
&chunkMatchingSelector=`objecttypename`
]]
<ul>
<li>
Name:<br/>
[[+name]]
</li>
<li>
Street:<br/>
[[+street]]
<br/>Geo tag:<br/>
<!-- Examples of "peek and grab" below -->
lat:[[+geodata.latitude]]
</br>
long:[[+geodata.latitude]]
</br>
sea level:[[+geodata.sealevel.m]] m
</li>
</ul>
<li>
<b>
[[+firstname]], [[+lastname]]
</b>
<br/>
[[+phone]]
<br/>
[[+email]]
<br/>
Address:<br/>
[[+address]]
<br/>
</li>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment