Как реализовать циклический пересчет топиков без превью? [решено]

Бьюсь уже пол дня и не могу сообразить как реализовать следующее: в списке топиков выводятся топики с превьюшками, для тех топиков, у которых нет превью, вместо него выводится изображение. Для разнообразия решил выводить 4-е картинки поочереди. Т.е. для первого топика без превью загружается первое изображение, для второго (но не второго по счету!) — второе и т.д. После четвертого отсчет опять начинается с первого.

Вот для наглядности кусок кода:

{foreach from=$aTopics item=oTopic name=foo}
    <article class="topic topic-lg-preview topic-type-{$oTopic->getType()} js-topic">
        {if $oTopic->getPreviewImageWebPath()}
            <a href="{$oTopic->getUrl()}"><img class="topic_preview" src="{$oTopic->getPreviewImageWebPath({cfg name='topic.lg_preview.img_size'})}"></a>
        {else}
            <a href="{$oTopic->getUrl()}"><img class="topic_preview" src="{cfg name="path.static.skin"}/images/thumb-bg/bg-sm-counter.png"></a>
        {/if}
    </article>
{/foreach}


Необходимо чтобы вместо counter было 1, 2, 3, 4, 1, 2, 3…

Пробовал и счетчики всовывать и foreach задействовать, но чет не выходит.

PS: Решение в комменте.

17 комментариев

avatar
{$counter=0}
{foreach from=$aTopics item=oTopic name=foo}
    <article class="topic topic-lg-preview topic-type-{$oTopic->getType()} js-topic">
        {if $oTopic->getPreviewImageWebPath()}
            <a href="{$oTopic->getUrl()}"><img class="topic_preview" src="{$oTopic->getPreviewImageWebPath({cfg name='topic.lg_preview.img_size'})}"></a>
        {else}
            {$counter=$counter+1}
            {if $counter>4}
                {$counter=1}
            {/if}
            <a href="{$oTopic->getUrl()}"><img class="topic_preview" src="{cfg name="path.static.skin"}/images/thumb-bg/bg-sm-{$counter}.png"></a>
        {/if}
    </article>
{/foreach}
  • ort
  • +5
avatar
Короткий вариант
{foreach from=$aTopics item=oTopic}
    <article class="topic topic-lg-preview topic-type-{$oTopic->getType()} js-topic">
        {if $oTopic->getPreviewImageWebPath()}
            <a href="{$oTopic->getUrl()}"><img class="topic_preview" src="{$oTopic->getPreviewImageWebPath({cfg name='topic.lg_preview.img_size'})}"></a>
        {else}
            {$counter=$oTopic@index%4+1}
            <a href="{$oTopic->getUrl()}"><img class="topic_preview" src="{cfg name="path.static.skin"}/images/thumb-bg/bg-sm-{$counter}.png"></a>
        {/if}
    </article>
{/foreach}
  • ort
  • +5
avatar
Красиво! Вот понять бы что это и как работает $oTopic@index%4+1
avatar
$oTopic@index — индекс элемента из цикла по $aTopics, начинается с 0, кроме того есть ещё, например, iteration, он начинается с 1, first — первый ли элемент в цикле, last — последний ли.

%4 — остаток от деления на 4

+1 — добавление чтобы начиналось от 1 до 4.
avatar
Не срабатывают оба варианта, $counter для каждого топика без превью равен 1. Может быть из-за того, что вышеприведенный код разнесен по двум разным файлам (в топик-листе foreach и в нем инклуд вывода топика)? Как в таком случае поступить?
avatar
Может быть из-за того, что вышеприведенный код разнесен по двум разным файлам (в топик-листе foreach и в нем инклуд вывода топика)?
Именно по этой причине.
Как в таком случае поступить?
формировать переменную $counter там, где цикл, и передавать её значение в инклуд.
avatar
имею ввиду использовать конструкии вида $oTopic@index только рядом с циклом (в том же файле).
avatar
О, кажись уловил суть, сейчас попробую…
avatar
Всем спасибо, все получилось: в topic_list.tpl прописал

{$counter=0}
{foreach from=$aTopics item=oTopic name=foo}
	{if !$oTopic->getPreviewImageWebPath()}
		{$counter=$counter+1}
	{/if}
	
	{if $counter>4}
		{$counter=1}
	{/if}
	
	<article class="topic topic-lg-preview topic-type-{$oTopic->getType()} js-topic">
		{include file='topic_views/topic_lg-preview.tpl'}
	</article>
{/foreach}


topic_thumb.tpl оставил:

...
<header class="topic-header">
	{if $oTopic->getPreviewImageWebPath()}
		<a href="{$oTopic->getUrl()}"><img class="topic_preview" src="{$oTopic->getPreviewImageWebPath({cfg name='topic.lg_preview.img_size'})}"></a>
	{else}
		<a href="{$oTopic->getUrl()}"><img class="topic_preview" src="{cfg name="path.static.skin"}/images/thumb-bg/bg-sm-{$counter}.png"></a>
	{/if}
...


… К похожему решению шел с утра, но про разные файлы как-то не подумал. :(
avatar
Более подробно:
В topic_list.tpl у мненя следующее:

{foreach from=$aTopics item=oTopic name=foo}
	<article class="topic topic-lg-preview topic-type-{$oTopic->getType()} js-topic">
		{include file='topic_views/topic_thumb.tpl'}
	</article>
{/foreach}

и в topic_thumb.tpl реализуется вывод превью:

...
<header class="topic-header">
	{if $oTopic->getPreviewImageWebPath()}
		<a href="{$oTopic->getUrl()}"><img class="topic_preview" src="{$oTopic->getPreviewImageWebPath({cfg name='topic.lg_preview.img_size'})}"></a>
	{else}
		<a href="{$oTopic->getUrl()}"><img class="topic_preview" src="{cfg name="path.static.skin"}/images/thumb-bg/bg-sm-{$counter}.png"></a>
	{/if}
...

Если прописываю

{$counter=$oTopic@index%4+1}

как указали, $counter постоянно равен единице, если вынести код в topic_list.tp:

{foreach from=$aTopics item=oTopic name=foo}
	{$counter=$oTopic@index%4+1}
	
	<article class="topic topic-lg-preview topic-type-{$oTopic->getType()} js-topic">
		{include file='topic_views/topic_lg-preview.tpl'}
	</article>
{/foreach}

то, естественно, пересчитывает все топики, с превью и без. Отсюда делаю вывод, что дело все же в разных файлах. Как можно в таком случае выкрутится?
avatar
{foreach from=$aTopics item=oTopic name=foo}
        {if !$oTopic->getPreviewImageWebPath()}
	    {$counter=$oTopic@index%4+1}
        {/if}
	
	<article class="topic topic-lg-preview topic-type-{$oTopic->getType()} js-topic">
		{include file='topic_views/topic_lg-preview.tpl'}
	</article>
{/foreach}
avatar
Пробовал. В таком случае все равно пересчитывает все топики, с превью и без, т.е. учитывает все топики (в принципе с $oTopic только все и может забрать), а выводит только для тех, у кого превью отсутствует.

А вот вариант с простым счетчиком работает. Спасибо за помощь!
avatar
$oTopic@index
При каждой итерации он увеличивается даже если есть превью, а Вовка хочет чтобы последовательно от 1 до 4 был счет, а не случайно как получается при использовании счетчика.
avatar
Можно рандомно еще.

{assign var=x value= 1|rand:4 } 
{if $x == 1}
url
{elseif $x == 2} 
url
{elseif $x == 3}
url
{else}
url
{/if}
avatar
Можно, но тогда не исключено следование подряд одинаковых чисел (в моем случае картинок).
avatar
Да, это как вариант. На одном из шаблонов классы так меняю, крайне редко подряд следует.
avatar
В моем случае так можно было бы и возможностями foreach сделать, но хотелось чтобы все-таки без повторений, даже если такая вероятность невысокая.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.