Smarty 3 выводит текущую позицию внутри цикла foreach.

Вместо:

{foreach $rows as $row}
    <li class="item{if $row@first} item-first{elseif $row@last} item-last{/if}">{$row.title}</li>
{/foreach}

Есть ли способ сделать что-то подобное?

{foreach $rows as $row}
    <li class="item item-{$row@position}">{$row.title}</li>
{/foreach}

Это может вывести:

пункт-первый пункт-последний

Я предполагаю, что если есть только 1 строка, тогда нужно будет вывести оба вышеперечисленных?


person John Magnolia    schedule 14.11.2012    source источник
comment
В идеале я искал способ сделать это в smarty? Возможно, как пользовательский модификатор или плагин. Идея состоит в том, чтобы сделать шаблон немного чище для повторяющихся задач в качестве первого/последнего.   -  person John Magnolia    schedule 15.11.2012


Ответы (1)


Вы можете попытаться описать условие вне цикла и использовать @iteration свойство. Например:

Внутри вашего PHP-файла:

$lastIteration = count($rows);
$smarty->assign('classMapping', array(
    1 => 'item-first', // iteration always starts at one
    $lastIteration => 'item-last',
));

Внутри вашего шаблона:

{foreach $rows as $row}
    <li class="item {$classMapping[$row@iteration]}">{$row.title}</li>
{/foreach}

Но я думаю, что ваш код (с оператором if) не так уж и плох.


Обновить

Это исходный код функции Smarty 3 foreach: http://smarty-php.googlecode.com/svn/trunk/distribution/libs/sysplugins/smarty_internal_compile_foreach.php

Посмотрите на класс Smarty_Internal_Compile_Foreach и на метод complile() (вот "укороченная" версия этого метода, которая описывает, как он использует модификатор @first):

public function compile($args, $compiler, $parameter)
{                
    $ItemVarName = '$' . trim($item, '\'"') . '@';

    // evaluates which Smarty variables and properties have to be computed
    if ($has_name) {
        $usesSmartyFirst = strpos($tpl->source->content, $SmartyVarName . 'first') !== false;                        
    } else {
        $usesSmartyFirst = false;            
    }        

    $usesPropFirst = $usesSmartyFirst || strpos($tpl->source->content, $ItemVarName . 'first') !== false;

    return $output; // output - is a result of the compilation process
}

Таким образом, вы можете создать свой собственный внутренний модификатор foreach (например, @position) только после изменения основных классов Smarty.

person Vladimir Posvistelik    schedule 14.11.2012
comment
Это будет означать более 100 различных изменений. В идеале я искал способ сделать это в smarty? Возможно, как пользовательский модификатор или плагин. Идея состоит в том, чтобы сделать шаблон немного чище для повторяющихся задач в качестве первого/последнего. - person John Magnolia; 15.11.2012