for block not accepting functions

1 view
Skip to first unread message

strahil

unread,
Sep 4, 2008, 7:55:19 AM9/4/08
to php-outline
{for $i from date('Y') to date('Y')-60}

{set $fy = date('Y')}
{set $ly = date('Y')-60}
{for $i from $fy to $ly}

Neither piece of code works. Please, help!:)

Exception output:

exception 'OutlineException' with message 'syntax error in for-
statement' in /usr/local/www/beta/server/outline/system.php:159
#0 /usr/local/www/beta/server/outline/compiler.php(245): OutlineSystem-
>for_block('$i from date('Y...')
#1 /usr/local/www/beta/server/outline/compiler.php(145):
OutlineCompiler->parse('for $i from dat...')
#2 /usr/local/www/beta/server/outline/engine.php(70): OutlineCompiler-
>compile('{include frames...')
#3 /usr/local/www/beta/server/outline/engine.php(121): OutlineEngine-
>build('/usr/local/www/...', '/usr/local/www/...', true)

mindplay.dk

unread,
Sep 4, 2008, 10:38:38 AM9/4/08
to php-outline
The {for} block currently only works with real numbers, it does not
support variables. The implementation of this function is very old,
from before Outline, when I was merely experimenting - it needs to
be rewritten to support variables and expressions ...

What I have so far, is a replacement for OutlineSystem::for_block

public function for_block($args) {

preg_match(
'/(\$[\w\d_]*)\s+from\s+(.*)\sto\s(.*(?=\sby\s)|.*)(\sby\s(.+))?/',
$args,
$exp
);

$var = $from = $to = null; $by = 1; $c = count($exp);

if ($c==4 || $c==6) {
list($var, $from, $to, $by) = array($exp[1], $exp[2], $exp[3],
isset($exp[5]) ? $exp[5] : 1);
} else {
throw new OutlineException("syntax error in for-statement", $this-
>compiler);
}

if (in_array($var, $this->for_stack)) throw new
OutlineException("use of same iterator '$var' in nested {for}
statements", $this->compiler);

$this->for_stack[] = $var;

$this->compiler->code("{$var} = new OutlineIterator({$from}, {$to},
{$by});");
$this->compiler->code("while ({$var}->next()) {");

}

And at the end of engine.php, add the following new class:

class OutlineIterator {

public $index, $start, $end, $step;

public function __construct($start, $end, $step) {
$this->start = $start;
$this->end = $end;
$this->step = ($end<$start && $step>0 ? -$step : $step);
$this->index = $start - $this->step;
}

public function next() {
$more = ($this->step>0 ? $this->index<$this->end : $this->index>
$this->end);
$this->index += $this->step;
return $more;
}

public function __toString() { return strval($this->index); }

}

This is not very elegant (or fast) yet, so I don't want to commit
this.

__toString() unfortunately is not good enough, as you might rely on
using the index value of the iterator for other things than just
printing it out - if you try to use it as an array index, for example,
you will have problems ... for the time being, you would have to use
something like $myarray[$var->index] instead of $myarray[$var] as
before ...

it's not convenient. I'm thinking about simpler solutions...

mindplay.dk

unread,
Sep 4, 2008, 2:14:52 PM9/4/08
to php-outline
I have posted an update - the {for} implementation now creates one of
two implementations as applicable ... simple numeric {for} loops will
use for (a;b;c) as previously, while {for} loops with expressions or
variables will use the new OutlineIterator object, which is created
separately from your iteration variable now.

In other words, it should now works as you expected! :-)

I also updated the test-template to demonstrate dynamic loops.

Let me know how this works for you!

strahil

unread,
Sep 5, 2008, 7:54:43 AM9/5/08
to php-outline
Thanks, I'll give it a try and report back :)

strahil

unread,
Sep 7, 2008, 6:30:22 AM9/7/08
to php-outline
Either I'm doing something wrong either it's not working and I'm
almost sure it's the first thing.

Which files exactly have you updated?

I'm trying with this code:

{set $fy = date('Y')}
{set $ly = date('Y')-60}
{for $i from $fy to $ly}
<option>$i</option>
{/for}
Reply all
Reply to author
Forward
0 new messages