Automatic set of state on Oxygen sidebar portlets should work now; reimplemented parts of the template parser (again) to workaround some PHP/PCRE issues and add support for parser plugins
authorDan
Wed, 17 Oct 2007 21:54:11 -0400
changeset 178 fd0e9c7a7b28
parent 177 b4aaca42c8a4
child 179 e858bacb5cfa
Automatic set of state on Oxygen sidebar portlets should work now; reimplemented parts of the template parser (again) to workaround some PHP/PCRE issues and add support for parser plugins
includes/clientside/static/loader.js
includes/render.php
includes/template.php
--- a/includes/clientside/static/loader.js	Mon Oct 15 00:11:51 2007 -0400
+++ b/includes/clientside/static/loader.js	Wed Oct 17 21:54:11 2007 -0400
@@ -1,27 +1,8 @@
 // Some final stuff - loader routines, etc.
 
-var __tmpEnanoStartup9843275;
-  
-function enanoStartup(e) {
-  if ( !e )
-  {
-    // Delay initting sliders until images are loaded
-    if ( typeof(window.onload) == 'function' )
-      __tmpEnanoStartup9843275 = window.onload;
-    else
-      __tmpEnanoStartup9843275 = function(){};
-    window.onload = function(e){__tmpEnanoStartup9843275(e);initSliders();};
-  }
-  else
-  {
-    initSliders();
-  }
-}
-
 function mdgInnerLoader(e)
 {
   jws.startup();
-  enanoStartup(e);
   if(window.location.hash == '#comments') ajaxComments();
   window.onkeydown=isKeyPressed;
   window.onkeyup=function(e) { isKeyPressed(e); };
@@ -34,6 +15,7 @@
   {
     dbx_set_key();
   }
+  initSliders();
   runOnloadHooks(e);
 }
 if(window.onload) var ld = window.onload;
--- a/includes/render.php	Mon Oct 15 00:11:51 2007 -0400
+++ b/includes/render.php	Wed Oct 17 21:54:11 2007 -0400
@@ -708,6 +708,7 @@
       ':-/'     => 'face-plain.png',
       ':joke:'  => 'face-plain.png',
       ']:->' => 'face-devil-grin.png',
+      ']:->'    => 'face-devil-grin.png',
       ':kiss:'  => 'face-kiss.png',
       ':-P'     => 'face-tongue-out.png',
       ':P'      => 'face-tongue-out.png',
--- a/includes/template.php	Mon Oct 15 00:11:51 2007 -0400
+++ b/includes/template.php	Wed Oct 17 21:54:11 2007 -0400
@@ -958,6 +958,7 @@
   
   function compile_tpl_code($text)
   {
+    global $db, $session, $paths, $template, $plugins; // Common objects
     // A random seed used to salt tags
     $seed = md5 ( microtime() . mt_rand() );
     
@@ -986,29 +987,88 @@
     // Conditionals
     //
     
-    // If-else-end
-    $text = preg_replace('/<!-- BEGIN ([A-z0-9_-]+?) -->(.*?)<!-- BEGINELSE \\1 -->(.*?)<!-- END \\1 -->/is', '\'; if ( $this->tpl_bool[\'\\1\'] ) { echo \'\\2\'; } else { echo \'\\3\'; } echo \'', $text);
-    
-    // If-end
-    $text = preg_replace('/<!-- BEGIN ([A-z0-9_-]+?) -->(.*?)<!-- END \\1 -->/is', '\'; if ( $this->tpl_bool[\'\\1\'] ) { echo \'\\2\'; } echo \'', $text);
+    $keywords = array('BEGIN', 'BEGINNOT', 'IFSET', 'IFPLUGIN');
+    $code = $plugins->setHook('template_compile_logic_keyword');
+    foreach ( $code as $cmd )
+    {
+      eval($cmd);
+    }
     
-    // If not-else-end
-    $text = preg_replace('/<!-- BEGINNOT ([A-z0-9_-]+?) -->(.*?)<!-- BEGINELSE \\1 -->(.*?)<!-- END \\1 -->/is', '\'; if ( !$this->tpl_bool[\'\\1\'] ) { echo \'\\2\'; } else { echo \'\\3\'; } echo \'', $text);
+    $keywords = implode('|', $keywords);
     
-    // If not-end
-    $text = preg_replace('/<!-- BEGINNOT ([A-z0-9_-]+?) -->(.*?)<!-- END \\1 -->/is', '\'; if ( !$this->tpl_bool[\'\\1\'] ) { echo \'\\2\'; } echo \'', $text);
+    // Matches
+    //          1     2                               3                 4   56                       7     8
+    $regexp = '/(<!-- ('. $keywords .') ([A-z0-9_-]+) -->)(.*)((<!-- BEGINELSE \\3 -->)(.*))?(<!-- END \\3 -->)/isU';
+    
+    /*
+    The way this works is: match all blocks using the standard form with a different keyword in the block each time,
+    and replace them with appropriate PHP logic. Plugin-extensible now. :-)
     
-    // If set-else-end
-    $text = preg_replace('/<!-- IFSET ([A-z0-9_-]+?) -->(.*?)<!-- BEGINELSE \\1 -->(.*?)<!-- END \\1 -->/is', '\'; if ( isset($this->tpl_strings[\'\\1\']) ) { echo \'\\2\'; } else { echo \'\\3\'; } echo \'', $text);
-    
-    // If set-end
-    $text = preg_replace('/<!-- IFSET ([A-z0-9_-]+?) -->(.*?)<!-- END \\1 -->/is', '\'; if ( isset($this->tpl_strings[\'\\1\']) ) { echo \'\\2\'; } echo \'', $text);
+    The while-loop is to bypass what is apparently a PCRE bug. It's hackish but it works. Properly written plugins should only need
+    to compile templates (using this method) once for each time the template file is changed.
+    */
+    while ( preg_match($regexp, $text) )
+    {
+      preg_match_all($regexp, $text, $matches);
+      for ( $i = 0; $i < count($matches[0]); $i++ )
+      {
+        $start_tag =& $matches[1][$i];
+        $type =& $matches[2][$i];
+        $test =& $matches[3][$i];
+        $particle_true  =& $matches[4][$i];
+        $else_tag =& $matches[6][$i];
+        $particle_else =& $matches[7][$i];
+        $end_tag =& $matches[8][$i];
+        
+        switch($type)
+        {
+          case 'BEGIN':
+            $cond = "isset(\$this->tpl_bool['$test']) && \$this->tpl_bool['$test']";
+            break;
+          case 'BEGINNOT':
+            $cond = "!isset(\$this->tpl_bool['$test']) || ( isset(\$this->tpl_bool['$test']) && !\$this->tpl_bool['$test'] )";
+            break;
+          case 'IFPLUGIN':
+            $cond = "getConfig('plugin_$test') == '1'";
+            break;
+          case 'IFSET':
+            $cond = "isset(\$this->tpl_strings['$test'])";
+            break;
+          default:
+            $code = $plugins->setHook('template_compile_logic_cond');
+            foreach ( $code as $cmd )
+            {
+              eval($cmd);
+            }
+            break;
+        }
+        
+        if ( !isset($cond) || ( isset($cond) && !is_string($cond) ) )
+          continue;
+        
+        $tag_complete = <<<TPLCODE
+        ';
+        /* START OF CONDITION: $type ($test) */
+        if ( $cond )
+        {
+          echo '$particle_true';
+        /* ELSE OF CONDITION: $type ($test) */
+        }
+        else
+        {
+          echo '$particle_else';
+        /* END OF CONDITION: $type ($test) */
+        }
+        echo '
+TPLCODE;
+        
+        $text = str_replace_once($matches[0][$i], $tag_complete, $text);
+        
+      }
+    }
     
-    // If plugin loaded-else-end
-    $text = preg_replace('/<!-- IFPLUGIN ([A-z0-9_\.-]+?) -->(.*?)<!-- BEGINELSE \\1 -->(.*?)<!-- END \\1 -->/is', '\'; if ( getConfig(\'plugin_\\1\') == \'1\' ) { echo \'\\2\'; } else { echo \'\\3\'; } echo \'', $text);
-    
-    // If plugin loaded-end
-    $text = preg_replace('/<!-- IFPLUGIN ([A-z0-9_\.-]+?) -->(.*?)<!-- END \\1 -->/is', '\'; if ( getConfig(\'plugin_\\1\') == \'1\' ) { echo \'\\2\'; } echo \'', $text);
+    // For debugging ;-)
+    // die("<pre>&lt;?php\n" . htmlspecialchars($text."\n\n".print_r($matches,true)) . "\n\n?&gt;</pre>");
     
     //
     // Data substitution/variables
@@ -1029,6 +1089,8 @@
       $text = str_replace_once($tag, "'; $match echo '", $text);
     }
     
+    // echo('<pre>' . htmlspecialchars($text) . '</pre>');
+    
     return $text;  
     
   }