块函数的形式是这样的:{func} .. {/func}。换句话说,它们被封闭在一个模板区域内,然后对该区域的内容进行操作。默认地,你的函数实现会被Smarty调用两次:一次是在开始标签,另一次是在闭合标签。块函数在模板中使用和函数还是有一些区别的,但自定义添加的方式差距不大,也可以使用两种方式进行添加。使用Smarty对象中的addPluginsDir()方法动态注册时,将第一个参数改为“block”。如果以特定文件的方式扩充块函数,文件的命名规则是“block.块函数名.php”的结构,函数命令规则是“smarty_block_块函数名($params, $content, $smarty,&$repeat)”。只有块函数的开始标签具有属性,所有属性包含在作为关联数组的$params变量中,经由模板传递给模板函数。当处理闭合标签时,函数同样可访问开始标签的属性。$content变量值取决于你的函数是被开始标签调用还是被闭合标签调用。假如是开始标签,则变量值将为NULL,如果是闭合标签,则$content变量值为模板块的内容。请注意这时模板块已经被Smarty处理过,因此你所接收到的是模板的输出而不是模板资源。&$repeat参数通过引用传递给函数执行,并为其提供控制块显示多少次的可能性。在默认情况下,在首次调用块函数(块开始标签)时&$repeat变量为true,在随后的所有块函数(闭合标签)调用中其值始终为false。函数每次执行返回的&$repeat值为true时,{func} .. {/func}之间的内容会被求值,同时参数$content里的新块内容会再次调用执行函数(运行方法有点类似于递归函数)。如果你嵌套了块函数,可以通过$smarty->_tag_stack变量访问找出父块函数。
//函数中的$params代表标签中传入的参数的数组;变量 $content 的值取决于是否因开始标记或结束标
//记或结束标记调用你的函数。假如是开始标记,它会是空的,如果是结束标记,它会是模板块的内容。
//参数 &$repeat 通过参考引用传递给函数执行过程并为其提供一个可能值来控制显示块多少遍。默认情况下
//首次调用块函数(块开始标记)时变量 $repeat 是真,在随后的所有块函数调用中其始终是假。每当函数执行
//返回的 &$repeat 是真时,在{func} .. {/func}之间的内容再次求值,函数执行接收一个新块参数 $content
//内容值被再次调用。
function smarty_block_products($params, $content, &$smarty, &$repeat) {
global $db, $config;
//仅仅是获取一个和当前block相对应的值而已
$l = count($smarty->_tag_stack);
//指派变量名
if(empty($params['name'])) $params['name'] = "products";
//判断是否是第一次运行(前半部标签),如果这个变量存在了,那么说明数据已经被注册进$smarty->blocvars[$l]里面了
//其中$smarty->blockvars是自定义的变量,smarty本身没有该属性,在smarty上面注册该变量的好处是, smarty每次都会默认以引用的方式进行传递,当然,如果你乐意,也可以使用$GLOBALS['blockvars'][$l]
//
if(empty($smarty->blockvars[$l])) {
/*
sql process
*/
$smarty->blockvars[$l] = $db->get_results($sql);
//如果没有数据,那就不用再执行了(repeat)
if(!$smarty->blockvars[$l]) return $repeat = false;
if(!empty($params['pager'])) $smarty->assign($params['pager'], $pager);
}
//利用each的特点,逐一遍历$smarty->blockvars[$l]子元素
if(list($key, $item) = each($smarty->blockvars[$l])) {
$repeat = true;
//重要的,指派变量,以供结束标签显示(下一次调用)
$smarty->assign($params['name'], $item);
}
else {
$repeat = false;
//清除each产生的指针记录,不解
reset($smarty->blockvars[$l]);
}
//print 这里的$content其实是在上一次的运行中解析过(已经插入数据的最终结果)的$content,直接打印即可
if(!is_null($content)) print $content;
//循环结束时,清理变量
if(!$repeat) $smarty->blockvars[$l] = array();
}