The Problem: You have a list of X items of information that you want to lay out in rows. Each row must contain X columns. It's easy to lay-out things in two columns, but when you want to use a large or indeterminate number of columns in your layout you need to write some more flexible smarty code. This is my solution.
Line 2: Causes this entire block to be ignored if the source variable is not present.
Lines 5-25: Loop through the input variable.
Line 6: We capture the value which indicates the column number.
Line 26-29: We need to make sure that the table is properly closed otherwise this will cause a bug in the HTML.
<!-- lc_horizontalIcons.html -->
{if $horizontal_icons != null}
{include file="lc/lc_sausage.html" sausage_heading="Activities" sausage_anchor="Activities"}
{foreach from=$horizontal_icons item=datum key=key}
{capture name="column"}{math equation="x % 3" x=$key}{/capture}
{if $smarty.capture.column == "0"}
<table border="0" cellpadding="0" cellspacing="0" class="sectionTable">
<tr>
<td width="33%" align="center" valign="middle">
{include file="lc/lc_linked_img.html}
</td>
{elseif $smarty.capture.column == "1"}
<td width="33%" align="center" valign="middle">
{include file="lc/lc_linked_img.html}
</td>
{elseif $smarty.capture.column == "2"}
<td width="33%" align="center" valign="middle">
{include file="lc/lc_linked_img.html}
</td>
</tr>
</table>
{/if}
{/foreach}
{if $smarty.capture.column != 2}
<!-- Close the table! -->
</tr></table>
{/if}
{/if}
<!-- end lc_centreAbout.html -->
If you want to see an example of this effect in use, take a look at the home page of the new [Leisure Connection] website when it launches in March 2003.
Here's another one:
{* columnsExample.tpl *}
{* ----------------------------------------- *}
{* Example for using column layout in Smarty *}
{* First we check if there are some entries to display *}
{if count($entries) > 0}
{* begin of table *}
<table>
{* $lastcol will be needed to check if we are outputting the last column *}
{math assign="lastcol" equation="x-1" x=$columns}
{* $width is the column width *}
{math assign="width" equation="100 / x" x=$columns}
{* now loop through all entries *}
{section name="idx" loop=$entries}
{* $col is the current column *}
{math assign="col" equation="x % y" x=$smarty.section.idx.rownum y=$columns}
{if $col == 0}<tr>{/if} {* begin of new row *}
<td width="{$width}%">
{* Output cell content here *}
{$entries[idx]}
</td>
{if $col == $lastcol || $smarty.section.idx.index_last == true }</tr>{/if} {* end of row *}
{/section}
{* close table *}
</table>
{/if}
/**
* columnsExample.php
*
* Example for using column layout in Smarty
*/
$entries = array("a","b","c","d","e","f","g","h","i","j","k","l","m","n");
$columns = 7;
$smarty = new Smarty();
$smarty->assign("entries", $entries); // Assign the table entries
$smarty->assign("columns", $columns); // Assign the number of columns we want to display
$smarty->display("columnsExample.tpl");
This is for any number of columns, and its short and painless:
{* Monte Möhrt March 4, 2002 *}
{* $cols is the number of columns you want *}
<TABLE border=1>
<TR>
{section name=numloop loop=$data}
<TD>{$data[numloop]}</TD>
{* see if we should go to the next row *}
{if not ($smarty.section.numloop.rownum mod $cols)}
{if not $smarty.section.numloop.last}
</TR><TR>
{/if}
{/if}
{if $smarty.section.numloop.last}
{* pad the cells not yet created *}
{math equation = "n - a % n" n=$cols a=$data|@count assign="cells"}
{if $cells ne $cols}
{section name=pad loop=$cells}
<TD> </TD>
{/section}
{/if}
</TR>
{/if}
{/section}
</TABLE>
http://smarty.php.net/contribs/examples/dynamic_table_columns/table.tpl.txt
FYI, Smarty 2.5.0 will have an html_table function that will help automate this process.
This is also for any number of columns, but made easier by using a new feature of Smarty version 2.6.0: using math expressions directly in templates.
{* Requires Smarty 2.6.0 or later *}
{* $data is the array you want to display *}
{* $numCols is the number of columns *}
<table>
<tr>
{assign var="col" value="0"}
{section name=element loop=$data}
{if $col == $numCols}
</tr><tr>{assign var="col" value="0"}
{/if}
<td>{$data[element]}</td>
{assign var="col" value="`$col+1`"}
{/section}
{assign var="remainder" value="`$numCols-$col`"}
{section name=emptyElement loop=$remainder}
<td> </td>
{/section}
</tr>
</table>
Because I saw that Embedded Math can be hard to deal because it uses php function eval()
I tried another solution. I created a plugin that can jump next record in a section so
I can print as many itens as I want in 1 loop thru the {section} I will post it at the
website www.phpbrasil.com in the scripts section. Here you will have the source of the plugin
and two example files.
save this as function.section_next.php in your smarty/plugins folder
<?php
/**
* Smarty plugin
* @package Smarty
* @subpackage plugins
*/
/**
* Smarty {section_next} function plugin
*
* Type: function<br>
* Name: section_next<br>
* Author: Tadeu Ferreira Oliveira
* Contact: tadeu_fo@yahoo.com.br
* Purpose: jump to the next element in a section
* @param array parameters
* @param Smarty
* @return null
*/
function smarty_function_section_next($params, &$smarty)
{
if (!isset($smarty->_sections[$params["name"]])){
$smarty->trigger_error("section_next: section '".$params["name"]."' not found");
return;
}
$smarty->_sections[$params["name"]]['index'] += $smarty->_sections[$params["name"]]['step'];
$smarty->_sections[$params["name"]]['iteration']++;
$smarty->_sections[$params["name"]]['rownum'] = $smarty->_sections[$params["name"]]['iteration'];
$smarty->_sections[$params["name"]]['index_prev'] = $smarty->_sections[$params["name"]]['index'] - $smarty->_sections[$params["name"]]['step'];
$smarty->_sections[$params["name"]]['index_next'] = $smarty->_sections[$params["name"]]['index'] + $smarty->_sections[$params["name"]]['step'];
$smarty->_sections[$params["name"]]['first'] = ($smarty->_sections[$params["name"]]['iteration'] == 1);
$smarty->_sections[$params["name"]]['last'] = ($smarty->_sections[$params["name"]]['iteration'] == $smarty->_sections[$params["name"]]['total']);
}
?>
///////////////////////////////////////////////////////
teste.tpl
<html>
(* Mais de uma coluna por linha agora facinho facinho*)
<table border="1">
{section name=cont loop=$teste}
<tr>
<td>{$teste[cont]}</td> (* Uma Coluna*)
{section_next name=cont}
<td>{$teste[cont]}</td> (* Duas Colunas*)
</tr>
{/section}
</table>
</html>
///////////////////////////////////////////////////////
teste.php
<?php
require("Smarty.class.php");
$teste[0] = "Zero";
$teste[1] = "Um";
$teste[2] = "Dois";
$teste[3] = "Tres";
$teste[4] = "Quatro";
$teste[5] = "Cinco";
$teste[6] = "Seis";
$teste[7] = "Sete";
$smarty = new Smarty();
$smarty->assign("teste",$teste);
$smarty->display("teste2.tpl");
?>