XaminProject / handlebars.php

Handlebars processor for php
331 stars 134 forks source link

php-52 branch needs support for special variables: @last, @first #110

Closed bcole808 closed 9 years ago

bcole808 commented 9 years ago

I see that in the current master branch there is support for the EachHelper variables @last, @first, etc.

From EachHelper.php:

$specialVariables = array(
    '@index' => $index,
    '@first' => ($index === 0),
    '@last' => ($index === $lastIndex),
);
if (!$isList) {
    $specialVariables['@key'] = $key;
}

But those are missing from the php-52 branch. It would be really great to have those in the php-52 version of this script!

I have been trying to add support by modifying the Helpers.php file in php-52 and adding similar code in the _helper_each() function, but I am having trouble figuring out how to get it to work.

fzerorubigd commented 9 years ago

Personally, I have no time for PHP 5.2 (and even 5.3), but if someone could take care of that branch, I love to help.

bcole808 commented 9 years ago

Can you point me in the right direction on how to add support for @last and @first in the each loops?

I was able to get it to work by adding some code (example below), but for some reason that was only affecting a top level loop. A second each loop nested within another each loop was not receiving the @last and @first variables. Is there a different piece of code that affects an each loop nested instead of an each loop?

Here is the gist of what I tried to do:

public static function _helper_each($template, $context, $args, $source) {
    $tmp = $context->get($args);
    $buffer = '';
    if (is_array($tmp) || $tmp instanceof Traversable) {
        $islist = ( array_keys($tmp) == range(0, count($tmp) - 1) );

        // MY CODE
        $i = 0;
        // END MY CODE
        foreach ($tmp as $key => $var) {
            if( $islist ) {
                $context->pushIndex($key);
            } else {
                $context->pushKey($key);
            }

            // MY CODE
            $var['@first'] = ($i === 0);
            $var['@last'] = ($i === count($tmp)-1);
            $i++;
            // END MY CODE

            $context->push($var);
            $buffer .= $template->render($context);
            $context->pop();
            if( $islist ) {
                $context->popIndex();
            } else {
                $context->popKey();
            }
        }
    }
    return $buffer;
}

I would also prefer to use newer versions of PHP, but I am writing a WordPress plugin and many site owners are (unfortunately) still running versions of php all the way down to 5.2!

fzerorubigd commented 9 years ago

Its not something that you can handle inside helper function. See Template class : https://github.com/XaminProject/handlebars.php/blob/master/src/Handlebars/Template.php#L398

bcole808 commented 9 years ago

I was able to get it to work in the helper function. The problem I was having the other day was that I was not actually using the {{#each}} helper in my handlebars templates to do the loop, and so that's why it wasn't working with my nested loops. The code does indeed work when using the each helper correctly.

Pull request is open if you want to merge this to php-52. I can work on adding more documentation sometime as well if that is helpful.