现在我有一种需求:
<body>{{{EliteNews}}}</body>
这个“{{{}}}”里面的标签名(EliteNews)我是存入数据库的,与EliteNews对应的有SQL语句,模板内容。LabelName:EliteNews
Sql:select top 5 title from news where IsElite=1
Template:{loop}{{title}}<br />{/loop}我相信做过动态标签的,看到这里肯定明白我什么意思了。我要问的是smarty有处理动态标签的功能吗?

解决方案 »

  1.   

    相当于要smarty解析两次。
    但smarty只会解析一次。折中的办法,给smarty加一个db属性,并设置该属性为你的db类的对象。
    再加一个自定义的smarty\plugins函数。
    如:<?php
    function smarty_function_execsql($params, &$smarty) {
    $sql = rawurldecode($params["sql"]);//有需要的话,还可以有其他参数
    $name   = 'dbdata'; $query=$smarty->db->query($sql);
    $dbdata = array();
    while($rt = $smarty->db->fetch_array($query)){
    $dbdata[]=$rt;
    }
    $smarty->assign(array($name => $dbdata));
    }
    ?>再在Smarty.class.php里增加一个方法,例如:parseMyPlugins(&$_source_content,$myPlugins)
    更改Smarty.class.php里_compile_resource方法,读取到模板内容$_source_content后,
    使用正则匹配"\{\{\{([^\}]*)\}\}\}"的内容。如结果为$myPlugins
    $myPlugins中有结果才调用parseMyPlugins($_source_content,$myPlugins)
    继续执行parseMyPlugins大概如下:function parseMyPlugins(&$_source_content,$myPlugins) {
    //根据$myPlugins查出数据库里的对应的标签。得到结果数组$dbPlugins
    foreach($dbPlugins as $plugins){
    $parseString = "";
    //为了不让语句里的引号与模板的引号起冲突,用rawurlencode编码
    $parseString .= $this->left_delimiter.'execsql sql=\''.rawurlencode($plugins['Sql']).'\''.$this->right_delimiter;
    //这里你的内容没有遵循smarty的规范,那你就只有再把它格式化为规范的写法,用到的数据变量名为dbdata
    $plugins['Template'] = ********;
    $parseString .= $plugins['Template'];
    $_source_content = str_replace('{{{'.$plugins['LabelName'].'}}}',$parseString,$_source_content);//替换
    }
    }
    正好也有这类似的需求,稍微研究了下,没有测试的哈。
      

  2.   

    基本如是,或许可能可以在简单一点。
    但是 Smarty 是编译型的模板引擎,实现你的需求开销太大
    你的需求在解释型模板引擎较易实现
      

  3.   

    不知道了,针对smarty暂时只想到这个办法。
    想要提高效率的话,你就只有改smarty核心的东西了,不过改了过后估计就不是smarty了(改动很大,没弄它,太麻烦了,还不如象老大说的,另外找个适合的模板引擎来改)