Smarty Forum Index Smarty
WARNING: All discussion is moving to https://reddit.com/r/smarty, please go there! This forum will be closing soon.

ADVANCED: Recursion with Smarty
Goto page Previous  1, 2, 3, 4, 5 ... 9, 10, 11  Next
 
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Smarty Forum Index -> Tips and Tricks
View previous topic :: View next topic  
Author Message
Doublehead
Smarty n00b


Joined: 29 Jan 2004
Posts: 2

PostPosted: Fri Jan 30, 2004 4:54 pm    Post subject: Reply with quote

messju wrote:
Doublehead: it seems you are using php5. compiler.defun.php doesn't work with php5.


OK, so I'll just downgrade to PHP4.
But when PHP5 is released, will you make compiler.defun compatible for PHP5?
Back to top
View user's profile Send private message Visit poster's website
messju
Administrator


Joined: 16 Apr 2003
Posts: 3336
Location: Oldenburg, Germany

PostPosted: Fri Jan 30, 2004 6:52 pm    Post subject: Reply with quote

Doublehead wrote:
But when PHP5 is released, will you make compiler.defun compatible for PHP5?


hmm, maybe i should. it would be half of the way to a working solution for non-cacheable plugins (they suffer from the same incompatibility as compiler.defun does)
Back to top
View user's profile Send private message Send e-mail Visit poster's website
messju
Administrator


Joined: 16 Apr 2003
Posts: 3336
Location: Oldenburg, Germany

PostPosted: Sat Jan 31, 2004 8:41 pm    Post subject: Reply with quote

Here is a version that should work with php-5.0.0b3 and cvs-HEAD (but also with php-4 down to 4.0.6). Feedback and suggestions are welcome :)

[php:1:9cfd031f87]<?php

/* create code for a function call */
function smarty_compiler_fun($tag_args, &$compiler) {
$_attrs = $compiler->_parse_attrs($tag_args);

if (!isset($_attrs['name'])) $compiler->_syntax_error("fun: missing name parameter");
$_func_name = $compiler->_dequote($_attrs['name']);
$_func = 'smarty_fun_'.$_func_name;
$_params = 'array(';
$_sep = '';
unset($_attrs['name']);
foreach ($_attrs as $_key=>$_value) {
$_params .= "$_sep'$_key'=>$_value";
$_sep = ',';
}
$_params .= ')';
return "$_func(\$this, $_params); ";

}
$this->register_compiler_function('fun', 'smarty_compiler_fun');


/* create code for a function declaration */
function smarty_compiler_defun($tag_args, &$compiler) {
$attrs = $compiler->_parse_attrs($tag_args);
$func_key = '"' . md5('php-5') . '[[' . md5(uniqid('sucks')) . '";';
array_push($compiler->_tag_stack, array('defun', $attrs, $tag_args, $func_key));
if (!isset($attrs['name'])) $compiler->_syntax_error("defun: missing name parameter");

$func_name = $compiler->_dequote($attrs['name']);
$func = 'smarty_fun_'.$func_name;
return $func_key . "if (!function_exists('$func')) { function $func(&\$this, \$params) { \$_fun_tpl_vars = \$this->_tpl_vars; \$this->assign(\$params); ";

}


/* create code for closing a function definition and calling said function */
function smarty_compiler_defun_close($tag_args, &$compiler) {
list($name, $attrs, $open_tag_args, $func_key) = array_pop($compiler->_tag_stack);
if ($name!='defun') $compiler->_syntax_error("unexpected {/defun}");
return " \$this->_tpl_vars = \$_fun_tpl_vars; }} " . $func_key . smarty_compiler_fun($open_tag_args, $compiler);
}
$this->register_compiler_function('/defun', 'smarty_compiler_defun_close');


/* callback: replace all $this with $smarty */
function smarty_replace_fun($match) {
$tokens = token_get_all('<?php ' . $match[2]);
array_shift($tokens);
for ($i=0, $count=count($tokens); $i<$count; $i++) {
if (is_array($tokens[$i])) {
if ($tokens[$i][0] == T_VARIABLE && $tokens[$i][1] == '$this') {
$tokens[$i] = '$smarty';
} else {
$tokens[$i] = $tokens[$i][1];
}
}
}
return implode('', $tokens);
}


/* postfilter to squeeze the code to make php5 happy */
function smarty_postfilter_defun($source, &$compiler) {
$search = '("' . md5('php-5') . '\[\[[0-9a-f]{32}";)';
if ((double)phpversion()>=5.0) {
/* filter sourcecode. look for func_keys and replace all $this
in-between with $smarty */
while (1) {
$new_source = preg_replace_callback('/' . $search . '(.*)\\1/Us', 'smarty_replace_fun', $source);
if (strcmp($new_source, $source)==0) break;
$source = $new_source;
}
} else {
/* remove func_keys */
$source = preg_replace('/' . $search . '/', '', $source);
}
return $source;
}
$this->register_postfilter('smarty_postfilter_defun');


?>
[/php:1:9cfd031f87]
Back to top
View user's profile Send private message Send e-mail Visit poster's website
boots
Administrator


Joined: 16 Apr 2003
Posts: 5611
Location: Toronto, Canada

PostPosted: Mon Mar 22, 2004 11:06 pm    Post subject: Reply with quote

If anyone cut-and-pasted the code from messju's last post and was having troubles it is likely due to smiley's that the forum put in in the end of the $search regex expression in smarty_postfilter_defun(). I turned smiley's off for that post so cut-and-pasting should work now. Smile

The code appears to work fine (tested on 5RC1 and 4.3.4).

As always, thanks messju and great work!
Back to top
View user's profile Send private message
appel
Smarty Rookie


Joined: 27 May 2003
Posts: 29

PostPosted: Tue Apr 20, 2004 10:57 am    Post subject: Reply with quote

I'm using the defun plugin and I was wondering about one thing.

I have a array of pages, and some pages contain array of pages, childrens.

Now, I have a select box, dropdown, where I list all my pages recursively, but they all come in one list without any nesting.

Code:
<select name="fPage[page_parent_id]" style="width:400px;">
<option value="0">Engum flokki</option>
   {defun name="PageRecursion" list=$Pages}
   {foreach from=$list item=element}
      <option value="{$element.page_id}">&&{$element.page_name}</option>
      {if sizeof($element.Childrens) > 0}
         {fun name="PageRecursion" list=$element.Childrens}</ul>
      {/if}
   {/foreach}
   {/defun}
</select>



How can I add a "none breakable space" (&) for each level?
Back to top
View user's profile Send private message
boots
Administrator


Joined: 16 Apr 2003
Posts: 5611
Location: Toronto, Canada

PostPosted: Tue Apr 20, 2004 3:33 pm    Post subject: Reply with quote

I typically track depth (as a parameter the fun) and then based on depth, add an appropriate amount of whitespace. Don't forget to pass the depth on to your fun call and to have an appropriate way for the function to exit.

eg (note, I use the name "macro" instead of "fun"):
Code:
{macro name="menu" data=$BLOCK->data level=0}
    {assign var=level value=$level+1}
....
{* use $level in some clever way, eg:
<span style="padding-left:{$level*2};">your data</span>
*}
....

    {macro_call name="menu" data=$i level=$level}
....
{/macro}
Back to top
View user's profile Send private message
kills
Smarty Elite


Joined: 28 May 2004
Posts: 493

PostPosted: Fri Jun 04, 2004 2:07 pm    Post subject: Reply with quote

I have to paste the plugin-functions into 3 files?

Is this correct?

compiler.fun.php
[php:1:d5a4e8cf42]
<?php

/* create code for a function call */
function smarty_compiler_fun($tag_args, &$compiler) {
$_attrs = $compiler->_parse_attrs($tag_args);

if (!isset($_attrs['name'])) $compiler->_syntax_error("fun: missing name parameter");
$_func_name = $compiler->_dequote($_attrs['name']);
$_func = 'smarty_fun_'.$_func_name;
$_params = 'array(';
$_sep = '';
unset($_attrs['name']);
foreach ($_attrs as $_key=>$_value) {
$_params .= "$_sep'$_key'=>$_value";
$_sep = ',';
}
$_params .= ')';
return "$_func(\$this, $_params); ";

}
$this->register_compiler_function('fun', 'smarty_compiler_fun');


/* create code for a function declaration */
function smarty_compiler_defun($tag_args, &$compiler) {
$attrs = $compiler->_parse_attrs($tag_args);
$func_key = '"' . md5('php-5') . '[[' . md5(uniqid('sucks')) . '";';
array_push($compiler->_tag_stack, array('defun', $attrs, $tag_args, $func_key));
if (!isset($attrs['name'])) $compiler->_syntax_error("defun: missing name parameter");

$func_name = $compiler->_dequote($attrs['name']);
$func = 'smarty_fun_'.$func_name;
return $func_key . "if (!function_exists('$func')) { function $func(&\$this, \$params) { \$_fun_tpl_vars = \$this->_tpl_vars; \$this->assign(\$params); ";

}


/* create code for closing a function definition and calling said function */
function smarty_compiler_defun_close($tag_args, &$compiler) {
list($name, $attrs, $open_tag_args, $func_key) = array_pop($compiler->_tag_stack);
if ($name!='defun') $compiler->_syntax_error("unexpected {/defun}");
return " \$this->_tpl_vars = \$_fun_tpl_vars; }} " . $func_key . smarty_compiler_fun($open_tag_args, $compiler);
}
$this->register_compiler_function('/defun', 'smarty_compiler_defun_close');
[/php:1:d5a4e8cf42]

replace.fun.php
[php:1:d5a4e8cf42]
/* callback: replace all $this with $smarty */
function smarty_replace_fun($match) {
$tokens = token_get_all('<?php ' . $match[2]);
array_shift($tokens);
for ($i=0, $count=count($tokens); $i<$count; $i++) {
if (is_array($tokens[$i])) {
if ($tokens[$i][0] == T_VARIABLE && $tokens[$i][1] == '$this') {
$tokens[$i] = '$smarty';
} else {
$tokens[$i] = $tokens[$i][1];
}
}
}
return implode('', $tokens);
}
[/php:1:d5a4e8cf42]

postfiler.defun.php
[php:1:d5a4e8cf42]
/* postfilter to squeeze the code to make php5 happy */
function smarty_postfilter_defun($source, &$compiler) {
$search = '("' . md5('php-5') . '\[\[[0-9a-f]{32}";)';
if ((double)phpversion()>=5.0) {
/* filter sourcecode. look for func_keys and replace all $this
in-between with $smarty */
while (1) {
$new_source = preg_replace_callback('/' . $search . '(.*)\\1/Us', 'smarty_replace_fun', $source);
if (strcmp($new_source, $source)==0) break;
$source = $new_source;
}
} else {
/* remove func_keys */
$source = preg_replace('/' . $search . '/', '', $source);
}
return $source;
}
$this->register_postfilter('smarty_postfilter_defun');
[/php:1:d5a4e8cf42]
Back to top
View user's profile Send private message
messju
Administrator


Joined: 16 Apr 2003
Posts: 3336
Location: Oldenburg, Germany

PostPosted: Fri Jun 04, 2004 2:14 pm    Post subject: Reply with quote

@kills: no, you can put alled functions in compiler.defun.php
Back to top
View user's profile Send private message Send e-mail Visit poster's website
kills
Smarty Elite


Joined: 28 May 2004
Posts: 493

PostPosted: Fri Jun 04, 2004 2:19 pm    Post subject: Reply with quote

can you help me?
http://www.phpinsider.com/smarty-forum/viewtopic.php?p=10496#10496
Back to top
View user's profile Send private message
kills
Smarty Elite


Joined: 28 May 2004
Posts: 493

PostPosted: Sun Jun 13, 2004 3:37 pm    Post subject: Reply with quote

only for a better understanding:

are these statements are correct?

Code:

{defun name="PageRecursion" list=$Pages}

This line defines a function which expects the parameter "list"

Code:

{/defun}

The end of a function

Code:

{fun name="PageRecursion" list=$element.Childrens}

A function call with "$element.Childrens" as value for the parameter "list".

When this line appears between the "{defun}{/defun}" Tags, the function will be called recursivly.
Back to top
View user's profile Send private message
boots
Administrator


Joined: 16 Apr 2003
Posts: 5611
Location: Toronto, Canada

PostPosted: Sun Jun 13, 2004 5:04 pm    Post subject: Reply with quote

@Kills: precisely.
Back to top
View user's profile Send private message
pt2002
Smarty Regular


Joined: 05 May 2003
Posts: 89
Location: Porto, Portugal

PostPosted: Fri Aug 06, 2004 11:10 am    Post subject: Reply with quote

It's a little off-topic

I have a table with this structure: id pid name
With this I can build a simple tree.

I can read all records and show the tree with this function
Code:

function getTree($pid = 0, $prefix = "-") {     
   static $out;
   
   $query = "SELECT id, pid, name FROM table WHERE pid= '$pid'";
   $result = mysql_query($query);
   while ($row = mysql_fetch_assoc($result)) {
      $out .= $prefix.$row['name']."<br>";           
      getTree($row['id'], $prefix."---");
   }
   
   return $out;
}


I would like to build an array and output the tree with compiler.defun.php plugin and that is my problem.

TIA

Greetings
pt2002
Back to top
View user's profile Send private message
deadcat
Smarty Rookie


Joined: 20 Sep 2003
Posts: 10

PostPosted: Wed Sep 29, 2004 5:48 pm    Post subject: Reply with quote

very good!~ Razz
Back to top
View user's profile Send private message
stalker
Smarty Rookie


Joined: 28 Aug 2003
Posts: 15

PostPosted: Fri Oct 08, 2004 10:13 am    Post subject: Reply with quote

Hello smarty-lovers ;o)

I was using the old "defun" plugin with smarty and php4 successfully.
After a server change I have to cope with PHP5 and problems resulting from the change. One of these problems is that defun doesn't seem to work, I found the new plugin code from messju here and pasted it into compiler.defun.php but now i get this error:

Code:

Fatal error: Call to undefined function token_get_all() in /var/www/argos/relaunch/htdocs/lib/plugins/compiler.defun.php on line 49


Which means PHP doesn't know the function although it should.. (according to the php manual).
Any ideas on how to solve this?

Thank you,
Bora
Back to top
View user's profile Send private message
stalker
Smarty Rookie


Joined: 28 Aug 2003
Posts: 15

PostPosted: Fri Oct 08, 2004 12:30 pm    Post subject: Reply with quote

Never mind, it was my mistake the necessary tokenize use flag was not set when compiling php.

It seems to work fine now.
Back to top
View user's profile Send private message
Display posts from previous:   
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Smarty Forum Index -> Tips and Tricks All times are GMT
Goto page Previous  1, 2, 3, 4, 5 ... 9, 10, 11  Next
Page 4 of 11

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group
Protected by Anti-Spam ACP