开发者

Smarty - foreach loop 10 times and stop

开发者 https://www.devze.com 2023-01-11 22:32 出处:网络
Im using the following Smarty code: {foreach from=$entries key=i item=topic} {if $topic开发者_如何学运维.topic_style == question}

Im using the following Smarty code:

{foreach from=$entries key=i item=topic}
  {if $topic开发者_如何学运维.topic_style == question}
    <li>
      <a href="topic.php?id={$topic.id}">{$topic.title}</a>
    </li>
  {/if}
{/foreach}

How can i do the {foreach} a maximum of 10 times and then stop?


You can use index and break function:

{foreach from=$entries key=i item=topic name=foo}
  {if $smarty.foreach.foo.index == 10}
    {break}
  {/if}
  {if $topic.topic_style == question}
    <li>
      <a href="topic.php?id={$topic.id}">{$topic.title}</a>
    </li>
  {/if}
{/foreach}

Break function is described here:

Break in Smarty's / Dwoo's foreach


You could just use array_slice:

{foreach $entries|@array_slice:0:10 as $topic}
  ...
{/foreach}


Use index:

{foreach from=$entries key=i item=topic name=foo}
  {if $smarty.foreach.foo.index < 10}
    {if $topic.topic_style == question}
      <li>
        <a href="topic.php?id={$topic.id}">{$topic.title}</a>
      </li>
    {/if}
  {/if}
{/foreach}


This example uses index, you will get 11 results. See my notes

{foreach from=$entries key=i item=topic name=foo} // note (1)
    {if $smarty.foreach.foo.index == 10} // notes (2.1, 2.2 and 2.3)
       {php}break;{/php} // note (2.4) 
    {/if} 
    {if $topic.topic_style == question} // note (3)
        <li> 
            <a href="topic.php?id={$topic.id}">{$topic.title}</a> 
       </li> 
   {/if} 
{/foreach}

Notes

(1) If you are not using the key, there is no need to define it

(2.1) If you use index the start of the loop is 0, using iteration instead the counter starts at 1, for simple incremental counting use iteration not index.

(2.2) While its fine you use ==, !=, and so on in smarty code, for readability its better to use eq, neq, is, is not, and, or. the list goes on, see the smarty documentation for a full list.

(2.3) I noted above about the 11 results, using index. This would occur in the example above simply because the number is 10, to have a 10 result the print the break, you would have needed to use 9 as the value.

(2.4) Use the smarty break instead, you do not necessarily need to write a smarty plugin, there are plenty of plugins available to install.

(3) Just as in PHP, you do not need to use quotation on variables, integers, constants or boolean values, a string is none of these and should be enclosed in quotations.

The old Revision

{foreach from=$entries item=topic name=foo} 
        {if $smarty.foreach.foo.iteration eq 10} 
           {break}    
        {/if} 
        {if $topic.topic_style eq "question"} 
            <li> 
                <a href="topic.php?id={$topic.id}">{$topic.title}</a> 
           </li>
       {/if}
    {/foreach}

I have been rethinking this, and as a result I have figured out a way to skip out the need to break altogether, the loop will simply end at the last iteration. why i didnt think of this earlier i dont know but anyway here is the best way you can end a loop without breaking. lte and le both mean less than or equal too, just the same as PHP <=

You could also use neq (not equal to) and make the number 11 but if you have more results in the array it would simply skip iteration 11 and continue to the end of the array. If you only have 10 items in the array you can use any of the three ways, but for simplicity in this instance I would stick with the less than equal operators.

You will note now that this foreach loop is immensely cleaner to look at and understand

The Better Revision

{foreach from=$entries item=topic name=foo} 
    {if $smarty.foreach.foo.iteration lte 10 AND $topic.topic_style eq "question"} 
        <li> 
            <a href="topic.php?id={$topic.id}">{$topic.title}</a> 
       </li>
   {/if}
{/foreach}

Summary

In short, both ways will work, I noted an option above using the less than operator with index which would be the preferred way to evaluate.

However by switching over to iteration you allow for a more straight forward loop, you dont need to think about is that the right value, its simple, i want 10 results, so iteration eq 10.

Slight side track here: Another issue with index over iteration is index wont display a table correctly if you are using modulus, This is equally true in PHP programs. Using iteration with modulus will make your life easier. its the equivalent of setting a counter because the row index wont do what you need.

By using smarty operators rather than the PHP counterparts you can write a more readable template file. Remember that the templates are not meant for php logic, they are meant for the front end designers. To a PHP programmer operators become second nature but to a designer maybe be alien to their normal work.


If you don't want to write smarty plugin, you can do this too:

{foreach from=$entries key=i item=topic name=foo} 
  {if $smarty.foreach.foo.index == 10} 
       {php}break;{/php}    
  {/if} 
  {if $topic.topic_style == question} 
    <li> 
      <a href="topic.php?id={$topic.id}">{$topic.title}</a> 
    </li> 
  {/if} 
{/foreach} 


All the above worked to a certain degree, but not exactly what I wanted. Here's what worked for me. I basically used the index property of foreach

{foreach $products as $product}
{if $product@index eq 3}
    {break}
{/if}
<img src="..products/{$product.product_image}" alt="">

{/foreach}


Small extend in smarty to limit foreach.

On file : sysplugins/smarty_internal_compile_foreach.php

Add limit to original attributes :

public $optional_attributes = array('name', 'key','limit'); 

Add after $output = "<?php "; this >

if (isset($_attr['limit'])) {
    $limit = $_attr['limit'];
    $output .= "\n \$_limitCnt = 0; \n \$_limit = $limit; \n";
}

Add before $output .= "?>"; this >

if (isset($_attr['limit'])) {
     $output .= "\n if (\$_limitCnt == \$_limit) { break; }";
     $output .= "\n \$_limitCnt++;";
}

Use as usuall for each and add limit=# to limit your results.

Hope i helped.


Smarty 3 has another option, if at all possible then upgrading would be advisable. If you can't then speaking to the developer of your application.

{foreach $result_set as $result}
    {if $result@iteration lte 10}
        // just as in php both forms of access are available.
        {$result.assoc_key}
        {$result.0}
    {/if}
{/foreach}

Its also worth noting that Smarty 3 has {break} built in too. However, if you are breaking from the foreach loop before the end and essentially discarding the remaining data then you might want to consider if its possible to LIMIT your sql queries.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号