MisterN 22 декабря 2014 2 6
Мелким и недостойным специальной темы вопросам по smarty быть здесь!
Иногда хочется написать короткий код на php в шаблоне, чтобы раскидать например составить условие where для процессора. И как-то не хочется особо париться с расширением процессора-сниппета и т.д. В смарти раньше было {php}, но теперь оно деприкейтид.
Делать это через assign, foreach и if если и возможно, то совершенно неудобно. Если возможно.
Хочется массив с id разбросать по шаблонам: если шаблон Товар — в 'id:IN', если Категория — в 'OR:parent:IN'
Раньше можно было значит что-то типа

{php}
$a = array(164,185,280,282); // массив еще надо explode из списка в тв
foreach($a as $v){
    if($doc = $modx->getObject('modResource',$v) AND $doc->get('template') == 3)
        $docs[]=$v;
    else
        $folder[]=$v;
}

$where = array(
    'id:IN'=> $docs,
    'OR:parent:IN'=>$folder,
    'template'=>3
    );
{/php}

или же типа того и потом отправить это условие в стандартный процессор… Ну как-то так.
То, что я не умею работать со смарти — неоспоримо. Может кто умный подскажет?
6 комментариев
proxyfabio1
proxyfabio 22 декабря 2014г в 20:59 #
Fi1osof1
Fi1osof 22 декабря 2014г в 20:59 #
раньше было {php}, но теперь оно деприкейтид.
В контроллере или в плагине пропиши $modx->smarty->allow_php_tag = true; и будет тебе счастье.

{php}
$a = array(164,185,280,282); // массив еще надо explode из списка в тв
foreach($a as $v){
    if($doc = $modx->getObject('modResource',$v) AND $doc->get('template') == 3)
        $docs[]=$v;
    else
        $folder[]=$v;
}

$where = array(
    'id:IN'=> $docs,
    'OR:parent:IN'=>$folder,
    'template'=>3
    );
{/php}

На Смарти:

{$a = array(164,185,280,282)} 
{* массив еще надо explode из списка в тв 
    Делается так: {$a = explode(',', $tv_value)}
*}
{foreach($a as $v)}
    {if $modx->getObject('modResource',$v)->template == 3}
        $docs[]=$v;
    {else}
        $folder[]=$v;
    {/if}
{/foreach}

{$where = array(
    'id:IN'=> $docs,
    'OR:parent:IN'=>$folder,
    'template'=>3
)}
Чем не устраивает?
Tramp13571
Tramp1357 22 декабря 2014г в 21:09 #
Вариантов несколько:
1. в параматры шаблона добавить параметр «allow_php_tag» (да/нет). Но этот способ не рекомендуется c точки зрения безопасности.

2. (сам таким пользуюсь) Можно написать плагин для smarty. примеры можно посмотреть в папке core/components/modxsmarty/smarty_plugins/

3. необходимый код php разместить в контроллере (вместо base.php). там можно назначить smarty переменные, и их использовать при выводе.
Tramp13571
Tramp1357 22 декабря 2014г в 21:11 #
Если затем последует вызов процессора, то можно переопределить его, передать необходимые данные, и в самом процессоре все и сделать
Fi1osof1
Fi1osof 22 декабря 2014г в 21:16 #
Резюме: учи Смарти :) Решений, как видишь, куча.
Tramp13571
Tramp1357 22 декабря 2014г в 21:19 #
Товар — в 'id:IN', если Категория — в 'OR:parent:IN'
в этом конкретном случае, мне кажется, правильнее в tv хранить эти id либо двумя списками, либо хранить пары {id,isfolder} — тогда при выводе гораздо меньше ресурсов потратится.
M
MisterN 22 декабря 2014г в 21:19 #
$docs[]=$v;

Прям так можно, не надо оборачивать в {}?
{$docs[]=$v;}

и еще вот такой код
{if $doc = $modx->getObject('modResource',$v) AND $doc->get('template') == 3}

в шаблоне вызывает ошибку. Но в этом случаи, если в цикле не будет получен один из документов по id ($v) ничего не случиться. Можно ли в условии как-то записать все-таки так, положить объект в переменную, а потом через энд вызвать у него гет?
Я вот так делаю, вроде работает, но может можно лучше-проще?

{foreach from=$myArray key=k item=v}
    {if $doc = $modx->getObject('modResource',$v)}
       {if  $doc->get('template') == 3}
           {$docs[]= $v}
        {else}
            {$folder[] = $v}
       {/if}
   {/if}
{/foreach}
Fi1osof1
Fi1osof 22 декабря 2014г в 21:27 #
$docs[]=$v;

Прям так можно, не надо оборачивать в {}?
Нет, это моя ошибка, надо оборачивать, то есть
{$docs[]=$v;}

и еще вот такой код
{if $doc = $modx->getObject('modResource',$v) AND $doc->get('template') == 3}

в шаблоне вызывает ошибку. Но в этом случаи, если в цикле не будет получен один из документов по id ($v) ничего не случиться. Можно ли в условии как-то записать все-таки так, положить объект в переменную, а потом через энд вызвать у него гет?
Нет, AND Smarty не понимает, как и не понимает типа {if $key != $value}. Но конкретно для этого случая я написал корректный пример:
{if $modx->getObject('modResource',$v)->template == 3}

Здесь истина будет только в том случае, если будет получен документ и у него шаблон 3.
M
MisterN 22 декабря 2014г в 21:22 #
2. (сам таким пользуюсь) Можно написать плагин для smarty. примеры можно посмотреть в папке core/components/modxsmarty/smarty_plugins/

На самом деле вопрос в том, как делать это быстрее и проще. А так понятно, что можно свой процессор, где рулить всем или сниппет там написать.
Tramp13571
Tramp1357 22 декабря 2014г в 21:31 #
тогда лучше всего просто переделай формирование списка id, примерно так:

[id=>isfolder]
[234=>0, 223=>0, 32->1 ...]

или
[docs][folders]<br />
[234,223][32]
Авторизуйтесь или зарегистрируйтесь (можно через соцсети ), чтобы оставлять комментарии.