+ -
当前位置:首页 → 问答吧 → Smarty 学习随记!

Smarty 学习随记!

时间:2005-09-15

来源:互联网

我的个人建议,下边的文字都是SMARTY里经常用到的一些基础概念的东西! 写的非常细致,而且接近中国人的思维了,都是工作中做的总结. 但是更全的资料到SMARTY的官方论坛上去看吧!!!!!
http://www.phpinsider.com/smarty-forum/ 我注册的ID是:phpcoder
虽然是全英文的,但是只要你能看个大概其,相信收益将会非常大,而且上边的管理员也是非常热情,可是因为是美国时间,所以一般他们活跃的时间是半夜3,4点!!



虽然很简单的东西,但是还是共享一下!!

什么是smarty及其安装

Smarty是一个php模板引擎,它分开了逻辑程序和外在的内容,提供了一种易于管理的方法.

Smarty要求web服务器运行php4.0.6和以上版本.

smarty安装需要smarty库文件。可以去官方网站http://smarty.php.net下载。

网上讲了很多安装的教程,但是我都没有成功,所以直接把整个目录名改为smarty直接复制到了网站所在的目录下,然后打开
http://网站路径/smarty/demo/index.php,显示正常,应该算是安装成功了。


基本语法

所有的smarty标签都被加上了定界符.在smarty里,所有定界符以外的内容都是静态的,当smarty遇到了模板标签,将尝试解释他们,然后再以恰当的方式输出.

默认情况下是 {和},但它们是可定制的.定制方法是:
$smarty->left_delimiter = '<!--{';
$smarty->right_delimiter = '}-->';

1.注释

模板注释被*号包围,例如 {* this is a comment *}
smarty注释将不被输出.它是模板内在的注释.

2.变量
模板变量以$开头,可以包含数字,字母和下划线。
config_file变量是例外要用#变量名#的方法引用

3.函数
smarty标签输出一个变量或者调用某种函数.
在定界符内函数和其属性将被处理和输出.例如:
{funcname attr1="val" attr2="val"}.
funcname为函数的名称比如:include等,attr1,attr2为属性名,val为属性相应的值。

在模板里无论是内建函数还是自定义函数都有相同的语法.
内建函数将在smarty内部工作,例如 {if}, {section} 和{strip}.他们不能被修改.
自定义函数通过插件机制起作用,它们是附加函数,可以随意修改,自行添加.
例如 {html_options} and {html_select_date}

4.属性
静态数值不需要加引号,布尔值(真或假)也不需要引号,可以是true,on,yes或者false,off,no. 但是字符串例外.变量同样被用到了,它们也不能加引号.

5.在字符串中插入变量
只能识别数字,字母,下划线和[]的组合,如果为复杂的形式需要用``将变量隔起来。比如{func var="test $foo.bar test"} 中只能识别变量$foo,要识别$foo.bar,需要写成{func var="test `$foo.bar` test"}的格式。

6.一些保留字的显示方法
在模板中如果要将smarty的一些保留字作为语言的内容显示出来,比如显示分隔符,默认为{}的方法是: {ldelim},{rdelim} 或者{$smarty.ldelim},{$smarty.rdelim} 或者可以把{}放在{literal} .. {/literal} 中间输出。

smarty的保留变量

{$smarty}保留变量可以被用于访问一些特殊的模板变量.
以下是全部.

页面请求变量
以下是访问页面请求变量诸如get,post,cookies,server,enviroment和session变量的例子. 例如{$smarty.server.SERVER_NAME}取得服务器变量,{$smarty.env.PATH}取得系统环境变量path, {$smarty.request.username}取得get/post/cookies/server/env的复合变量。

{$smarty.now}变量用于访问当前时间戳.
可以用 date_format调节器格式化输出. 例如{$smarty.now|date_format:"%Y-%m-%d %H:%M:%S"}

{$smarty.const}
你可以直接访问PHP常量. 例如{$smarty.const._MY_CONST_VAL}

{$smarty.capture}
可以通过 {capture}..{/capture}结构 截取的输出可以使用{$smarty} 变量访问.

{$smarty.config}
{$smarty}变量 可以访问已经加载的config变量.
例如 {$smarty.config.foo}就可以表示 {#foo#}.

{$smarty.section}, {$smarty.foreach}
{$smarty} 变量可以访问'section'和'foreach'循环的属性.

{$smarty.template}
显示当前被处理的模板的名字.

{$smarty.version}
显示smarty模板的版本

{$smarty.ldelim}
显示左分隔符

{$smarty.rdelim}
显示右分隔符

[ 本帖最后由 大白菜芯 于 2005-9-15 06:24 编辑 ]

作者: 大白菜芯   发布时间: 2005-09-15

变量调节器
变量调节器用于变量,自定义函数和字符串.
可以使用'|'符号和调节器名称应用调节器.
变量调节器由赋予的参数值决定其行为.
参数由':'符号分开.
如果你用变量调节器调节数组变量,结果是数组的每个值都被调节.如果你想要调节器调节整个数组,你必须在调节器名字前加上@符号.
例如: {$articleTitle|@count}(这将会在输出 $articleTitle 数组里的数目)

capitalize
将变量里的所有单词首字大写. 参数值boolean型决定带数字的词是否首字大写。默认不大写

count_characters
计算变量值里的字符数.参数值boolean型决定是否计算空格数。默认不计算空格

cat
将cat里的参数值连接到给定的变量后面.默认为空。

count_paragraphs
计算变量里的段落数量

count_sentences
计算变量里句子的数量

count_words
计算变量里的词数

date_format
日期格式

第一个参数控制日期格式.
如果传给date_format的数据是空的,将使用第二个参数作为默认时间

%a - 星期几的简写

%A - 星期几的全写

%b - 月份的简写

%B - 月份的全写

%c - 日期时间06/12/05 11:15:10

%C - 世纪时间

%d - 一个月的第几号(从 01 到 31)

%D - 同 %m/%d/%y

%e - 一个月的第几号,号为单数则前面加一空格 (从 1 到 31)

%g - 世纪

%G - 世纪 [0000,9999]

%h - 同%b

%H - 24小时形式的小时(从00到23)

%I - 12小时形式的小时(从01到 12)

%j - 一年中的第几天(从 001 到 366)

%k - 24小时形式的小时,单数字前面加空格. (从 0 到 23)

%l - 12小时形式的小时,单数字前面加空格.(range 1 to 12)

%m - 月份 (range 01 to 12)

%M - 分

%n - 换行符

%p - 显示早上还是下午`am' 或 `pm'

%r - a.m. 或 p.m.形式的时间

%R - 24小时形式的时间

%S - 秒

%t - tab符号

%T - 同%H:%M:%S

%u - 用 [1,7],表示星期几

%U - 计算是该年的第几个星期,从该年的第一个星期天开始计算

%V - 计算是该年的第几个星期, 从 01 到 53, 第一个星期必须至少有4天在这一年, 星期天作为这个星期的第一天

%w - 用数字的形式表示是星期的第几天, 星期天 为 0

%W - 用数字的形式是该年的第几个星期,从该年的第一个星期一开始计算

%x - 显示日期:月/日/年

%X - 显示时间:小时:分钟:秒

%y - 不包括世纪的年份

%Y - 包括世纪的年份

%Z - 时区

%% - 输出%

其中有些有时不能正常输出。

default
默认
为空变量设置一个默认值.
当变量为空或者未分配的时候,将由给定的默认值替代输出.

escape
转码
参数值为html,htmlall,url,quotes,hex,hexentity,javascript。默认是html转码

indent
缩进
在每行缩进字符串,第一个参数指定缩进多少个字符,默认是4个字符.第二个参数,指定缩进用什么字符代替。

lower
小写
This is used to lowercase a variable.
将变量字符串小写

nl2br
换行符替换成<br />

regex_replace
正则替换
寻找和替换正则表达式.必须有两个参数,参数1是替换正则表达式. 参数2使用什么文本字串来替换

replace
替换
简单的搜索和替换字符串必须有两个参数,参数1是将被替换的字符串. 参数2是用来替换的文本

spacify
spacify是在字符串的每个字符之间插入空格或者其他的字符串. 参数表示将在两个字符之间插入的字符串,默认为一个空格。

string_format 字符串格式化
是一种格式化浮点数的方法.例如十进制数.使用sprintf语法格式化。参数是必须的,规定使用的格式化方式。%d表示显示整数,%.2f表示截取两个浮点数。

strip 去除(多余空格)
替换所有重复的空格,换行和tab为单个或者指定的字符串. 如果有参数则是指定的字符串。

strip_tags 去除所有html标签

truncate 截取
参数1,规定截取的字符数.默认是80个.
第二个参数指定在截取的那段字符串后加上什么字符.默认为...
第三个参数决定是否精确截取,默认情况下为false,则smarty不会分割单词。

upper 将变量改为大写

wordwrap 行宽约束
第一个参数指定段落的宽度(也就是多少个字符一行,超过这个字符数换行).默认80.
第二个参数指定在约束点使用什么字符(默认是换行符\n).
第三个参数决定是否精确截取字符,默认情况下是不精确截取,就是截取时不能分开单词。

作者: 大白菜芯   发布时间: 2005-09-15

内建函数
内建函数不能擅自修改。
capture
capture函数的作用是收集模板输出的数据到一个变量里,而不是把它们输出到页面.例如任何在 {capture name="foo"}和{/capture}之间的数据都被收到了由函数的名称属性指定的变量{$foo}里,或者{$smarty.capture.foo}里。如果函数没有名字属性,将使用"default".每个{capture}都必须对应{/capture},也不能嵌套使用capture函数。

config_load
引用配置文件
file是必须的,说明要包含进来的配置文件名称,section说明要加载的部分的名称,scope被处理的变量的作用域.必须是local,parent或者global.
local的意思是变量将在本模板里被加载.
parent 的意思是变量将在本模板和上级模板被加载.
global的意思是变量将应用到所有的模板.默认为local。变量是否在上级模板可视,默认为no。如果scope属性已经有了,这个值将被忽略.

foreach,foreachelse
foreach循环是选择性的section循环.用于遍历关联数组.foreach的语法比section简单的多,但是作为一个折中它只能用于简单数组.
foreach必须的参数是from和item. from变量表示需要循环的数组的名称,item表示当前元素的变量名,key表示当前关键字的变量名,name表示访问foreach属性的foreach循环名。循环可以互相嵌套,被嵌套的循环之间的名字必须是独立的.foreachelse 在from变量没有值的时候被执行

include
用来引用其他的模板。
file属性是必须的用来表示所引用模板的名字,assign表示include文件将要分配的输出的变量。你可以自行用属性名="属性值"的方式定义任意个局部变量。

include_php
用来在模板中引入php脚本。file是必须的用来表示php脚本的路径,once确定如果在模板中引用了php脚本多次,是否只装载一次。默认为true。

insert
用来包含php脚本中的函数,name是必须的,表示所插入的脚本的名称,注意如果名称是name,则包含的函数则是insert_name(),所以所有要插入的函数要有前缀insert_ 。如果用了assign属性,则insert的输出将会分配给模板变量而不会显示。 script表示要引用的脚本路径。这个程序产生的内容将不会被缓存,在每次调用该页时重新执行,适用于广告,投票,查询结果等互动的地方。

if,elseif,else
if语句和和条件同php差不多,但每个词之间必须用空格分割开。也有一些新的条件语句,列举如下:eq相等,ne、neq不相等,gt大于,lt小于,gte、ge大于等于,lte、le 小于等于,not非,mod求模。is [not] div by是否能被某数整除,is [not] even是否为偶数,$a is [not] even by $b即($a / $b) % 2 == 0,is [not] odd是否为奇,$a is not odd by $b即($a / $b) % 2 != 0

php
php标记可以让模板中能直接使用php语言。

section,sectionelse
section用来循环显示数组的数据,name和loop是必须的参数。name表示嵌套名. section 可以嵌套使用,但是名字必须各不相同。loop表示循环的次数. sectionelse在loop参数为空的输出。start用来规定循环开始的指针,如果值为负则从数组尾部计算开始的指针,默认为0.step表示循环的步数,为负则反向循环,默认为1.max设定循环的最大步数.show决定是否显示section.
section也有自己的变量处理section属性,用{$smarty.section.sectionname.varname} 来显示.

index
index用来显示当前循环的指针,从0开始.

index_prev
用来显示前一次循环的指针,从-1开始

index_next
用来显示后一次循环的指针.

iteration
显示当前循环的次数,从1开始.

first
如果当前循环为第一个循环,则值为true.

last
如果当前循环为最后一个循环,则值为true.

rownum
同iteration.

loop
显示最后一次循环的指针,可以用在section中间的任何地方,也可以用在section之后.

show
show 决定是否显示section.

total
显示总共循环的次数,可以用在section中间的任何地方,也可以用在section之后.

strip
去掉多余的空格

作者: 大白菜芯   发布时间: 2005-09-15

常规函数
assign
assign用来在执行模板时分配变量值.var,value是必须的参数.var为要分配值的变量名,value为分配的值.

counter
counter用来输出一个计数. 可以用多个计数,但是名字必须各不相同.name表示计数器名,默认为default.start表示计数的初始值,默认为1.skip计数的间隔,默认为1.direction表示计数方向,up或down,默认为up.print表示是否打印该值,默认为true.assign定义模板变量,计数器的输出将被分配到assign定义的变量中.

cycle
Cycle用来循环显示一组数值.name表示cycle名,values("值1","值2",...)表示循环显示的一组数值.print表示是否显示.advance决定是否显示下一个数值. delimiter决定value的分隔符,默认为逗号. assign定义模板变量,cycle的输出将被分配到assign定义的变量中.

debug
debug可以显示所有分配了值的变量,但是不显示模板内容,output属性决定显示的格式html或javascript,默认是html.

eval
eval用来在变量里插入变量。var是插入的变量名,assign把输出分配给一个变量。

fetch
用来取得文件内容,并输出文件内容,可以取得本地文件,http文件和ftp文件,file是取得文件的路径, assign把输出分配给一个变量。

html_checkboxes
html_checkbox用来用给定的数据创建checkbox。name表示checkbox的名称,values表示checkbox的值,output表示checkbox的显示,selected表示被选选项的值,options表示一组checkbox的值和显示,separator表示分割每个checkbox的符号,labels表示给输出添加标签,默认为true。

html_image
html_image用来为一个图片创建html标签,如果height和width不分配值将会自动生成。file是图片的路径,height,width,alt同html标签,basedir是图片相对路径开始的目录的路径,默认为服务器根目录。href定义图片的链接。

html_options
输出下拉列表,参数有name,values,output,selected,options。

html_radios
输出单选框,参数同复选框。

html_select_date
prefix定义各个下拉列表名字的前缀,默认为Date_。time决定使用的时间,默认是当前时间。start_year决定下拉列表开始的年份,可以用年份表示,也可以用与当前年份的相对年数来表示。默认是当前年份。end_year决定下拉列表结束的年份,可以用年份表示,也可以用与当前年份的相对年数来表示。默认是当前年份。display_days决定是否显示日期。display_months决定是否显示月份。display_years决定是否显示年份。month_format决定显示月份的格式,默认为%B。day_format决定显示日期的格式,默认为%02d。day_value_format决定日期值的格式,默认为%d。month_value_format决定月份值的格式,默认为%m。year_as_text决定是否将年份按文本格式输出。reverse_years决定是否反向输出各年份。field_array用来取得一组变量,可以用name[Day],name[Month],name[Year]的方式从form取得获得的值。day_size,month_size,year_size添加大小标签。all_extra,day_extra,month_extra,year_extra添加额外的属性到select或input标签。field_order决定年月日下拉列表的顺序,默认为MDY。field_separator不同下拉列表之间的分隔符,默认是\n。year_empty,month_empty,day_empty是在各下拉列表第一栏显示的内容。

html_select_time
prefix定义各个下拉列表名字的前缀,默认为Time_。time决定使用的时间,默认是当前时间。display_hours决定是否显示小时。display_minutes决定是否显示分钟。display_seconds决定是否显示秒数。display_meridian 决定是否显示上午或下午,即显示am/pm。use_24_hours 决定是否24小时制。minute_interval 决定分钟之间的间隔。second_interval 决定秒数之间的间隔。field_array用来取得一组变量,可以用name[Hour],name[Minute],name[Second]的方式从form取得获得的值。all_extra,hour_extra,minute_extra,second_extra ,meridian_extra添加额外的属性到select或input标签。

html_table
loop定义用于循环的一组数据。cols决定列的数目,rows决定行的数目,如果其中一个为空,另一个有值,则根据元素个数和有值的属性来计算另一个的值,两者的默认值为3。inner决定元素的列举方向cols则列跟着列排列,rows则行跟着行排列,默认为cols。table_attr,tr_attr,td_attr分别为table,tr,td增加标签,如果tr_attr,td_attr是数组,将会循环增加标签。trailpad用来填充最后一行没有值的单元格,默认是&nbsp;。hdir决定每行元素的排列方向,从左到右right或从右到左left,默认为right。vdir决定每列的排列方向,从上到下down或从下到上up,默认为down。

math
进行数字运算操作。equation和var是必须的。equation定义运算式,可以使用的运算符有+, -, /, *, abs, ceil, cos, exp, floor, log, log10, max, min, pi, pow, rand, round, sin, sqrt, srans and tan。var给运算变量赋值。format确定结果的格式。assign将输出赋给一个参数。

mailto
使用mailto函数能使网络蜘蛛很难获取你的email地址,但是能在网页上正常显示,因为他把email地址进行了加密处理。address是必须的,定义email地址。text是显示在页面上的文本内容,默认是email地址。encode是加密email地址的方式,可以是none,hex或javascript,默认是none。如果要把邮件发给其他的邮箱,可以用cc抄送,email地址之间用,分割。bcc则为密件抄送。subject是邮件主题。newsgroups是发表内容的新闻组,新闻组之间用,隔开。extra添加附加标签。followupto意思不知。

textformat
textformat用来格式化文本,他会去掉空格和特殊字符,和规定行宽和缩进。style规定当前的格式,indent规定缩进的位数。indent_first规定第一行的缩进。indent_char用来缩进的字符,默认是一个空格。wrap规定行宽,即一行的字符数,默认是80。wrap_char规定每行的分隔符,默认是\n。wrap_cut决定是否分割单词。assign将输出分配给变量。

作者: 大白菜芯   发布时间: 2005-09-15

常量
SMARTY_DIR
是到smarty类目录的完全路径,必须以/结束。如果没有定义,将会自动决定路径.

SMARTY_CORE_DIR
是到smarty类core文件目录的完全路径,必须以/结束。如果没有定义,将会自动定义为smarty_dir路径下面的子目录.


变量

$template_dir
默认的模板目录名,默认为"./templates".
$compile_dir
默认的编译模板目录名,默认为"./templates_c"
$config_dir
默认的config文件目录名,默认为"./configs".
$plugins_dir
默认的插件目录名,默认为"plugins".
$debugging
debugging控制台。即一个显示变量的窗口.
$debug_tpl
debug窗口的模板
$debugging_ctrl
另一种控制debugging的方法。
$autoload_filters
对所有的模板使用过滤程序,这个变量是一个数组,其中关键字是过滤的类型,值是过滤的名字。
$compile_check
每次php执行将是否查看模板的内容是否改变。

$caching
决定是否缓存文件执行生成的文件。
$cache_dir
默认的模板缓存目录名,默认为"./cache".
$cache_lifetime
缓存的模板的过期时间,以秒计算. $caching值为-1则缓存的模板永不过期.

作者: 大白菜芯   发布时间: 2005-09-15

最后我放个我用的例子.大家仅做一个参考吧!!!

  1. <?php
  2. error_reporting(7);

  3. $TurnDot  =  substr(PHP_OS, 0, 3) == 'WIN'  ?  ";"  :  ":"  ;

  4. $doc_root=$_SERVER['DOCUMENT_ROOT'];   //默认获取根路径
  5. //$doc_root="E:/Myweb/an-cool.com/Web" ; //这里是指定路径


  6. $lib_root=".".$TurnDot.$doc_root."/shopadmin".$TurnDot.$doc_root."/shopadmin/inc".$TurnDot.$doc_root."/".$TurnDot.$doc_root."/jpgraph/src/".$TurnDot.$doc_root."/Smarty/libs/".$TurnDot.$doc_root."/Smarty";

  7. ini_set("include_path",$lib_root);

  8. include("conf.global.php");  //这里是装载一个全局配置文件.

  9. $Templates_root = $doc_root."/templates";  //定义摸版根目录
  10. define("Templates",$Templates_root);


  11. $templates  = isset($INFO['templates'])  ?  $INFO['templates']  :  'default'  ;

  12. include_once('Smarty.class.php');

  13. $tpl = new Smarty();                                                                   //建立smarty实例对象$tpl
  14. $tpl->debugging = false;
  15. $tpl->template_dir   = Templates."/".$templates  ;                             //设置模板目录
  16. $tpl->compile_dir    = Templates."/".$templates  ."/templates_c";     //设置编译目录
  17. $tpl->cache_dir      = $doc_root."/cache";                                //设置缓存目录
  18. $tpl->cache_lifetime = 60 * 60 * 24;                                         //设置缓存时间
  19. $tpl->cache_lifetime = 0;                                                          //设置缓存时间
  20. $tpl->caching        = false;                                                        //这里是调试时设为false,发布时请使用true
  21. $tpl->left_delimiter = '<{';
  22. $tpl->right_delimiter= '}>';

  23. $tpl->assign("template_dir",  $INFO['site_url']."/templates/".$templates ); //摸板路径
  24. $tpl->assign("Site_Url",      $INFO['site_url']); //主站URL
  25. $tpl->assign("LanguageIs",    $INFO['IS']); //语言包类型
  26. $tpl->assign("HtmlTitle", $INFO['site_title']);     //TITLE内容
  27. $tpl->assign("HtmlMeta",  $INFO['meta_keyword']);  //META内容
  28. ?>
复制代码

[ 本帖最后由 大白菜芯 于 2005-9-15 06:36 编辑 ]

作者: 大白菜芯   发布时间: 2005-09-15

很棒。很棒。

作者: 刀客羽朋   发布时间: 2005-09-15

原创还是翻译,还是抄袭?
还是说明一下比较厚道

还有我自始至终觉得smarty是没前途的,设计师只会用数位板和ps之类的,难道模板还要我来改?为了编程的时候稍微方便一点,而浪费更多的人力物理?

[ 本帖最后由 halley 于 2005-9-15 13:37 编辑 ]

作者: halley   发布时间: 2005-09-15

to halley
你如果遇到一个项目,需求是这样的!!!
  1. ------------------------------------------------------------------------------------------------
  2.       XXX多用户商店开发需求手册
  3. .....
  4. X ) 必须实现多摸版样式, 用户可以随时随意更换主题外观!!!!
  5.   .......
  6. ------------------------------------------------------------------------------------------------
复制代码


你必须使用模板 这个是无须置疑的.

然后:
你说设计师只会用数位板和ps之类 ,没有错,可是你知道国内,包括世界上有多少依靠给Discuz! 做摸版,或者改Discuz! 摸版的美工 而生活的吗!!  他们不仅仅会用数位板和ps之类 而且还能更改摸板,以及完成一些摸板内的循环和判断的简单语句的操作. 比如我在退伍者认识的破狐狸,哪个哥们就是做Discuz! 及其他论坛活的。回头我给你找找他做的和改的. 很漂亮的!! 甚至有些对于图形细致的东西,就是不熟悉的程序员做起来,都很难. 所以说他现在SOHO在家,一个月能有6,7000的收入.甚至更多.而那些只会用数位板和ps之类的,只能做班,每个月2,3千的收入,这就是区别.

在然后说编程方面:
程序与HTML混合写,是非常快!! 但是我依然坚持要求,逻辑层和界面必须分离.
比如我做的SHOP, 为了前台能做出来任意想要的效果,我把变量都提前抛了出来!!
比如产品我抛出来20个,有相关的ID,NAME,INTRO,PIC,ATTRIB 等 .分别标号是 Product_ID_1,Product_Name_1, Product_ID_2,Product_Name_2............. 等等这个样式,前台部分,页面可以不考虑逻辑关系,他愿意放几行几列就放几行几列,愿意怎么摆弄就怎么摆弄.
我现在做的商店这个,美工需要1天多出一张风格图,然后美工1天就能完成所有的切图和程序嵌套,因为前台变量名基本都是一样的,美工第一套做起来相当慢,但是一单完成后,以后就是CTRL+C ,CTRL+V的机械操作了. 1天就能出一个完全不同风格的主站. 我现在的SHOP就是想做100套摸版. 之需要3个人,4个多月时间. 而且我写了套手册,大家随意可以写,并且放心,程序不会出错误的,因为程序部分他们都动不了,前台 也没有逻辑关系,非常方便.
以上是我自己的经验.当然好不好,对不对,仁者见仁了. 我不是推捧SMARTY这套摸板,它确实很好,虽然说不是很小,但是机制性能,以及后续的开发,很不错. 有了技术问题,也可以去官方的论坛随时提问,而且能尽快得到回答.作为开源产品,做到这个程度,确实非常不错了!!!

作者: 大白菜芯   发布时间: 2005-09-15

smarty中文手册

作者: bugii   发布时间: 2005-09-15

楼主高见!

作者: zerode   发布时间: 2005-09-15

我一般也是使用SMARTY,不过我的前台对这些完全不懂,所以,一般前台的模板我使用SMARTY将数据流导入,这些数据与页面逻辑方面的工作我来完成,他只需要控制页面风格即可,虽然我的工作量比较大一些,不过这样比起混合HTML和PHP代码要轻松很多。

作者: zerode   发布时间: 2005-09-15

看需求喽
smarty 是对这一功能的补充 如果从效率上看 当然混写快 但如果要求多模版 不用smarty 维护成本岂不是太高 也可以考虑xslt+xml

作者: duketang   发布时间: 2005-09-15

反对楼主一下,模板化并不是sm的专利。

我一直在用phplib的template类库,原因是我只需要它帮我完成一个模板的功能就行了。其它的应该由我自已来按照项目的需求来完成。为什么phplib的很多类库几年了都不更新,个人认为,已经没什么可更新的了,完全够用了。

而我拒绝sm的原因是,功能看起来很强大,几乎把常用的PHP函数都封装了。然后还提供缓冲,编译(假),调试等种种功能。但是我认为这正好和PHP简单够用好用的原则特点背道而驰了。

作者: seraph   发布时间: 2005-09-15

所以说仁者见仁了!! PHP 本身是入门容易,面对基础应用更简单 !! 可是只要你深入的做一些东西就会发现,PHP面对底层的一些东西还是不错的,尤其SMS 应用方面.可是资料太少了.

学习一件东西,掌握应用并不难,可是全而通是太难了,如果把PHP的所有函数都能很好的掌握,也是需要一定时间的. 无所谓SMARTY或者是PHPLIB 都是帮助我们加深理解, 满足用户需求的东西.

我开这个帖子,就是分享及讨论一下.哈,并没有争执哪个好或哪个不好的意思:)!!

作者: 大白菜芯   发布时间: 2005-09-15

拜一下楼主,这么说偶就木有话了,哈哈。

作者: seraph   发布时间: 2005-09-15

3年前我就做过测试,当时还在im286混,做多数据量的模板测试,结果smarty的效率是令人满意的,只是他晦涩的语法是在让人难以恭维,所以前台模板类还是一直用从codecharge搬来的类

作者: halley   发布时间: 2005-09-16

这儿有没人跟我一样用phplib的template类,问下对于显示列表时,块的嵌套是怎么处理的。

我是用了一个笨办法,觉得很笨,不好意思说~~~想找聪明一点的。

作者: seraph   发布时间: 2005-09-16

只是他晦涩的语法是在让人难以恭维,

哈。同意!!   
确实写的太庞杂了。感觉很多地方反尔是画蛇添足了!! 但是精华部分也强的可以!!!!

我最欣赏smarty开发人员的执着与研发的精神. 如果你去他们论坛和他们管理员谈谈就知道了。太热情了,让人感觉你都不好意思不用SMARTY:)  哈, 人是第一位的. 尤其我们做程序开发,多听听他们的思想,总是好的.毕竟英语是他们的母语,最主要国外的开源环境比国内好太多了, 国内做开源的竟然都拿不到钱,老外听到这些,都直摇头:(  国内的环境啊!! 哎!!!!!!!!!! 我们努力啊!!!!

作者: 大白菜芯   发布时间: 2005-09-18

还是支持使用smarty等类库的。
模板分离让程序员摆脱繁琐的编码。
更注重于业务和逻辑的体现。

作者: 刀客羽朋   发布时间: 2005-09-18

原帖由 seraph 于 2005-9-16 11:44 发表
这儿有没人跟我一样用phplib的template类,问下对于显示列表时,块的嵌套是怎么处理的。

我是用了一个笨办法,觉得很笨,不好意思说~~~想找聪明一点的。



...俺就用PHPLIB啊
偶觉得模板类只要做到能让页面和程序分离就好..不用弄得那么复杂

对块的嵌套不就是不断的set_block下去么?注意变量位置就行了

作者: Phzzy   发布时间: 2005-09-18

受益非浅啊..~!smart和PHPLIB各有个的习惯,

SMART毕竟是PHP官方推荐的模板,对初学者来说,很值得信任的..

作者: runner   发布时间: 2005-09-18

原帖由 Phzzy 于 2005-9-18 10:21 发表



...俺就用PHPLIB啊
偶觉得模板类只要做到能让页面和程序分离就好..不用弄得那么复杂

对块的嵌套不就是不断的set_block下去么?注意变量位置就行了



你看,问题如下:

  1. 模板里这样。

  2. <!-- BEGIN row -->
  3. 这儿是主列表{master_list}

  4. <!-- BEGIN s_row -->
  5. 这儿是子列表{sub_list}
  6. <!-- END s_row -->

  7. <!-- END row -->
复制代码


要显示以上的模板方式,代码里如何写?

直接在两层循环里两次set_block不行。

作者: seraph   发布时间: 2005-09-18

1.php代码
  1. <?
  2. include("template.php");

  3. $t=new template(".");
  4. $t->set_file("index", "1.htm");

  5. //第一层开始
  6. $t -> set_block("index", "row", "a");//设置第一层的block

  7. for($i=1;$i<4;$i++){

  8.         $t->set_var(array("master_list"=> $i));//设置第一层的变量
  9. //第二层开始
  10.         $t->set_block("row", "s_row", "b");//设置第二层的block
  11.        
  12.         for($j=1;$j<4;$j++){       
  13.                 $t->set_var(array("sub_list"=> $j));//设置第二层的变量
  14.                 $t->parse("b","s_row",true);
  15.         }
  16. //第二层结束
  17.         $t->parse("a","row",true);
  18. }
  19. //第一层结束

  20. $t->parse("indexout","index");
  21. $t->p("indexout");
  22. ?>
复制代码


1.htm代码
  1. <style>
  2. #row{
  3. margin:20px 0 0 0;
  4. }
  5. </style>

  6. <!-- BEGIN row -->
  7. <div id="row">{master_list}</div>

  8. <!-- BEGIN s_row -->
  9. <div id="s_row">这儿是子列表{sub_list}</div>
  10. <!-- END s_row -->

  11. <!-- END row -->
复制代码



输出后的样子

1
这儿是子列表1
这儿是子列表2
这儿是子列表3

2
这儿是子列表1
这儿是子列表2
这儿是子列表3

3
这儿是子列表1
这儿是子列表2
这儿是子列表3

作者: Phzzy   发布时间: 2005-09-18

晕死,你的template.php是什么版本的,我的是1.5版

set_var的函数定义里没有第三个参数呀。

作者: seraph   发布时间: 2005-09-18

俺是这个......一直用这个.....-.-""

  1. <?php
  2. /*
  3. * (C) Copyright 1999-2000 NetUSE GmbH
  4. *                    Kristian Koehntopp
  5. *
  6. * $Id: template.inc,v 1.12 2002/07/11 22:29:51 richardarcher Exp $
  7. *
  8. */
  9. class Template
  10. {
  11.   var $classname = "Template";

  12.   var $debug    = false;

  13.   var $root     = ".";

  14.   var $file     = array();

  15.   var $varkeys  = array();

  16.   var $varvals  = array();

  17.   var $unknowns = "remove";

  18.   var $halt_on_error  = "yes";

  19.   var $last_error     = "";

  20.   function Template($root = ".", $unknowns = "remove") {
  21.     if ($this->debug & 4) {
  22.       echo "<p><b>Template:</b> root = $root, unknowns = $unknowns</p>\n";
  23.     }
  24.     $this->set_root($root);
  25.     $this->set_unknowns($unknowns);
  26.   }


  27.   function set_root($root) {
  28.     if ($this->debug & 4) {
  29.       echo "<p><b>set_root:</b> root = $root</p>\n";
  30.     }
  31.     if (!is_dir($root)) {
  32.       $this->halt("set_root: $root is not a directory.");
  33.       return false;
  34.     }

  35.     $this->root = $root;
  36.     return true;
  37.   }


  38.   function set_unknowns($unknowns = "remove") {
  39.     if ($this->debug & 4) {
  40.       echo "<p><b>unknowns:</b> unknowns = $unknowns</p>\n";
  41.     }
  42.     $this->unknowns = $unknowns;
  43.   }



  44.   function set_file($varname, $filename = "") {
  45.     if (!is_array($varname)) {
  46.       if ($this->debug & 4) {
  47.         echo "<p><b>set_file:</b> (with scalar) varname = $varname, filename = $filename</p>\n";
  48.       }
  49.       if ($filename == "") {
  50.         $this->halt("set_file: For varname $varname filename is empty.");
  51.         return false;
  52.       }
  53.       $this->file[$varname] = $this->filename($filename);
  54.     } else {
  55.       reset($varname);
  56.       while(list($v, $f) = each($varname)) {
  57.         if ($this->debug & 4) {
  58.           echo "<p><b>set_file:</b> (with array) varname = $v, filename = $f</p>\n";
  59.         }
  60.         if ($f == "") {
  61.           $this->halt("set_file: For varname $v filename is empty.");
  62.           return false;
  63.         }
  64.         $this->file[$v] = $this->filename($f);
  65.       }
  66.     }
  67.     return true;
  68.   }



  69.   function set_block($parent, $varname, $name = "") {
  70.     if ($this->debug & 4) {
  71.       echo "<p><b>set_block:</b> parent = $parent, varname = $varname, name = $name</p>\n";
  72.     }
  73.     if (!$this->loadfile($parent)) {
  74.       $this->halt("set_block: unable to load $parent.");
  75.       return false;
  76.     }
  77.     if ($name == "") {
  78.       $name = $varname;
  79.     }

  80.     $str = $this->get_var($parent);
  81.     $reg = "/[ \t]*<!--\s+BEGIN $varname\s+-->\s*?\n?(\s*.*?\n?)\s*<!--\s+END $varname\s+-->\s*?\n?/sm";
  82.     preg_match_all($reg, $str, $m);
  83.     $str = preg_replace($reg, "{" . "$name}", $str);
  84.     $this->set_var($varname, $m[1][0]);
  85.     $this->set_var($parent, $str);
  86.     return true;
  87.   }


  88.   function set_var($varname, $value = "", $append = false) {
  89.     if (!is_array($varname)) {
  90.       if (!empty($varname)) {
  91.         if ($this->debug & 1) {
  92.           printf("<b>set_var:</b> (with scalar) <b>%s</b> = '%s'<br>\n", $varname, htmlentities($value));
  93.         }
  94.         $this->varkeys[$varname] = "/".$this->varname($varname)."/";
  95.         if ($append && isset($this->varvals[$varname])) {
  96.           $this->varvals[$varname] .= $value;
  97.         } else {
  98.           $this->varvals[$varname] = $value;
  99.         }
  100.       }
  101.     } else {
  102.       reset($varname);
  103.       while(list($k, $v) = each($varname)) {
  104.         if (!empty($k)) {
  105.           if ($this->debug & 1) {
  106.             printf("<b>set_var:</b> (with array) <b>%s</b> = '%s'<br>\n", $k, htmlentities($v));
  107.           }
  108.           $this->varkeys[$k] = "/".$this->varname($k)."/";
  109.           if ($append && isset($this->varvals[$k])) {
  110.             $this->varvals[$k] .= $v;
  111.           } else {
  112.             $this->varvals[$k] = $v;
  113.           }
  114.         }
  115.       }
  116.     }
  117.   }



  118.   function clear_var($varname) {
  119.     if (!is_array($varname)) {
  120.       if (!empty($varname)) {
  121.         if ($this->debug & 1) {
  122.           printf("<b>clear_var:</b> (with scalar) <b>%s</b><br>\n", $varname);
  123.         }
  124.         $this->set_var($varname, "");
  125.       }
  126.     } else {
  127.       reset($varname);
  128.       while(list($k, $v) = each($varname)) {
  129.         if (!empty($v)) {
  130.           if ($this->debug & 1) {
  131.             printf("<b>clear_var:</b> (with array) <b>%s</b><br>\n", $v);
  132.           }
  133.           $this->set_var($v, "");
  134.         }
  135.       }
  136.     }
  137.   }



  138.   function unset_var($varname) {
  139.     if (!is_array($varname)) {
  140.       if (!empty($varname)) {
  141.         if ($this->debug & 1) {
  142.           printf("<b>unset_var:</b> (with scalar) <b>%s</b><br>\n", $varname);
  143.         }
  144.         unset($this->varkeys[$varname]);
  145.         unset($this->varvals[$varname]);
  146.       }
  147.     } else {
  148.       reset($varname);
  149.       while(list($k, $v) = each($varname)) {
  150.         if (!empty($v)) {
  151.           if ($this->debug & 1) {
  152.             printf("<b>unset_var:</b> (with array) <b>%s</b><br>\n", $v);
  153.           }
  154.           unset($this->varkeys[$v]);
  155.           unset($this->varvals[$v]);
  156.         }
  157.       }
  158.     }
  159.   }


  160.   function subst($varname, $append = false) {
  161.     $varvals_quoted = array();
  162.     if ($this->debug & 4) {
  163.       echo "<p><b>subst:</b> varname = $varname</p>\n";
  164.     }
  165.     if (!$this->loadfile($varname)) {
  166.       $this->halt("subst: unable to load $varname.");
  167.       return false;
  168.     }

  169.     // quote the replacement strings to prevent bogus stripping of special chars
  170.     reset($this->varvals);
  171.     while(list($k, $v) = each($this->varvals)) {
  172.       $varvals_quoted[$k] = preg_replace(array('/\\\\/', '/\$/'), array('\\\\\\\\', '\\\\$'), $v);
  173.     }

  174.     $str = $this->get_var($varname);
  175.     $str = preg_replace($this->varkeys, $varvals_quoted, $str);
  176.     return $str;
  177.   }



  178.   function psubst($varname) {
  179.     if ($this->debug & 4) {
  180.       echo "<p><b>psubst:</b> varname = $varname</p>\n";
  181.     }
  182.     print $this->subst($varname);

  183.     return false;
  184.   }



  185.   function parse($target, $varname, $append = false) {
  186.     if (!is_array($varname)) {
  187.       if ($this->debug & 4) {
  188.         echo "<p><b>parse:</b> (with scalar) target = $target, varname = $varname, append = $append</p>\n";
  189.       }
  190.       $str = $this->subst($varname);
  191.       if ($append) {
  192.         $this->set_var($target, $this->get_var($target) . $str);
  193.       } else {
  194.         $this->set_var($target, $str);
  195.       }
  196.     } else {
  197.       reset($varname);
  198.       while(list($i, $v) = each($varname)) {
  199.         if ($this->debug & 4) {
  200.           echo "<p><b>parse:</b> (with array) target = $target, i = $i, varname = $v, append = $append</p>\n";
  201.         }
  202.         $str = $this->subst($v);
  203.         if ($append) {
  204.           $this->set_var($target, $this->get_var($target) . $str);
  205.         } else {
  206.           $this->set_var($target, $str);
  207.         }
  208.       }
  209.     }

  210.     if ($this->debug & 4) {
  211.       echo "<p><b>parse:</b> completed</p>\n";
  212.     }
  213.     return $str;
  214.   }



  215.   function pparse($target, $varname, $append = false) {
  216.     if ($this->debug & 4) {
  217.       echo "<p><b>pparse:</b> passing parameters to parse...</p>\n";
  218.     }
  219.     print $this->finish($this->parse($target, $varname, $append));
  220.     return false;
  221.   }


  222.   function get_vars() {
  223.     if ($this->debug & 4) {
  224.       echo "<p><b>get_vars:</b> constructing array of vars...</p>\n";
  225.     }
  226.     reset($this->varkeys);
  227.     while(list($k, $v) = each($this->varkeys)) {
  228.       $result[$k] = $this->get_var($k);
  229.     }
  230.     return $result;
  231.   }


  232.   function get_var($varname) {
  233.     if (!is_array($varname)) {
  234.       if (isset($this->varvals[$varname])) {
  235.         $str = $this->varvals[$varname];
  236.       } else {
  237.         $str = "";
  238.       }
  239.       if ($this->debug & 2) {
  240.         printf ("<b>get_var</b> (with scalar) <b>%s</b> = '%s'<br>\n", $varname, htmlentities($str));
  241.       }
  242.       return $str;
  243.     } else {
  244.       reset($varname);
  245.       while(list($k, $v) = each($varname)) {
  246.         if (isset($this->varvals[$v])) {
  247.           $str = $this->varvals[$v];
  248.         } else {
  249.           $str = "";
  250.         }
  251.         if ($this->debug & 2) {
  252.           printf ("<b>get_var:</b> (with array) <b>%s</b> = '%s'<br>\n", $v, htmlentities($str));
  253.         }
  254.         $result[$v] = $str;
  255.       }
  256.       return $result;
  257.     }
  258.   }

  259.   function get_undefined($varname) {
  260.     if ($this->debug & 4) {
  261.       echo "<p><b>get_undefined:</b> varname = $varname</p>\n";
  262.     }
  263.     if (!$this->loadfile($varname)) {
  264.       $this->halt("get_undefined: unable to load $varname.");
  265.       return false;
  266.     }

  267.     preg_match_all("/{([^ \t\r\n}]+)}/", $this->get_var($varname), $m);
  268.     $m = $m[1];
  269.     if (!is_array($m)) {
  270.       return false;
  271.     }

  272.     reset($m);
  273.     while(list($k, $v) = each($m)) {
  274.       if (!isset($this->varkeys[$v])) {
  275.         if ($this->debug & 4) {
  276.          echo "<p><b>get_undefined:</b> undefined: $v</p>\n";
  277.         }
  278.         $result[$v] = $v;
  279.       }
  280.     }

  281.     if (count($result)) {
  282.       return $result;
  283.     } else {
  284.       return false;
  285.     }
  286.   }

  287.   function finish($str) {
  288.     switch ($this->unknowns) {
  289.       case "keep":
  290.       break;

  291.       case "remove":
  292.         $str = preg_replace('/{[^ \t\r\n}]+}/', "", $str);
  293.       break;

  294.       case "comment":
  295.         $str = preg_replace('/{([^ \t\r\n}]+)}/', "<!-- Template variable \\1 undefined -->", $str);
  296.       break;
  297.     }

  298.     return $str;
  299.   }


  300.   function p($varname) {
  301.     print $this->finish($this->get_var($varname));
  302.   }


  303.   function get($varname) {
  304.     return $this->finish($this->get_var($varname));
  305.   }


  306.   function filename($filename) {
  307.     if ($this->debug & 4) {
  308.       echo "<p><b>filename:</b> filename = $filename</p>\n";
  309.     }
  310.     if (substr($filename, 0, 1) != "/") {
  311.       $filename = $this->root."/".$filename;
  312.     }

  313.     if (!file_exists($filename)) {
  314.       $this->halt("文件:  $filename 不存在。有可能您的安装没有成功。");
  315.     }
  316.     return $filename;
  317.   }


  318.   function varname($varname) {
  319.     return preg_quote("{".$varname."}");
  320.   }

  321.   function loadfile($varname) {
  322.     if ($this->debug & 4) {
  323.       echo "<p><b>loadfile:</b> varname = $varname</p>\n";
  324.     }

  325.     if (!isset($this->file[$varname])) {
  326.       // $varname does not reference a file so return
  327.       if ($this->debug & 4) {
  328.         echo "<p><b>loadfile:</b> varname $varname does not reference a file</p>\n";
  329.       }
  330.       return true;
  331.     }

  332.     if (isset($this->varvals[$varname])) {
  333.       // will only be unset if varname was created with set_file and has never been loaded
  334.       // $varname has already been loaded so return
  335.       if ($this->debug & 4) {
  336.         echo "<p><b>loadfile:</b> varname $varname is already loaded</p>\n";
  337.       }
  338.       return true;
  339.     }
  340.     $filename = $this->file[$varname];

  341.     /* use @file here to avoid leaking filesystem information if there is an error */
  342.     $str = implode("", @file($filename));
  343.     if (empty($str)) {
  344.       $this->halt("loadfile: While loading $varname, $filename does not exist or is empty.");
  345.       return false;
  346.     }

  347.     if ($this->debug & 4) {
  348.       printf("<b>loadfile:</b> loaded $filename into $varname<br>\n");
  349.     }
  350.     $this->set_var($varname, $str);

  351.     return true;
  352.   }

  353.   function halt($msg) {
  354.     $this->last_error = $msg;

  355.     if ($this->halt_on_error != "no") {
  356.       $this->haltmsg($msg);
  357.     }

  358.     if ($this->halt_on_error == "yes") {
  359.       die("<b>程序意外终止。</b>");
  360.     }

  361.     return false;
  362.   }

  363.   function haltmsg($msg) {
  364.     printf("<b>模板错误:</b> %s<br>\n", $msg);
  365.   }

  366. }
  367. ?>
复制代码

[ 本帖最后由 Phzzy 于 2005-9-18 21:18 编辑 ]

作者: Phzzy   发布时间: 2005-09-18

我的笨办法,大家BS偶吧,哈哈。


  1. <?
  2. //proc template
  3.         global $template_path;
  4.         $t=new Template($template_path);
  5.         $t->set_file("file","template_xxx_master.html");
  6. //显示列表
  7.         $result=$c->get_list();
  8.         $t->set_block("file","row","rows");
  9.         foreach ($result as $r)        {
  10.                 $t->set_var(array(
  11.                         "test"=>$test,
  12.                         ));

  13. //处理子模板
  14.         global $template_path;
  15.         $ext_t=new Template($template_path);
  16.         $ext_t->set_file("ext_file","template_xxx_sub.html");
  17.         $result=$c->get_list();
  18.         $ext_t->set_block("file","row","rows");
  19.         foreach ($result as $r)        {
  20.                 $ext_t->set_var(array(
  21.                         "sub_text"=>$sub_text,
  22.                         ));
  23.                 $ext_t->parse("rows","row",true);
  24.         }
  25. //输出子模板
  26.         $ext_t->parse("temp_ext_file","ext_file");
  27.         $template_file=$ext_t->get_var("temp_ext_file");
  28.         $t->set_var(array(
  29.                 "template_xxx_sub"=>$template_file,
  30.                 ));

  31.                 $t->parse("rows","row",true);
  32.         }
  33. //输出
  34.         $t->parse("out","file");
  35.         $t->p("out");
  36. ?>
复制代码


主模板template_xxx_master.html
  1. <!-- BEGIN row -->
  2. 这是主模板{text}

  3. 下面是显示子模板的参数
  4. {template_xxx_sub}
  5. <!-- END row -->
复制代码


子模板template_xxx_sub.html
  1. <!-- BEGIN row -->
  2. 这是子模板{sub_text}
  3. <!-- END row -->
复制代码

作者: seraph   发布时间: 2005-09-18

寒....
突然发现我的set_var也没用到第三个参数啊.....
刚才被你说晕了...
最好还是重新开贴讨论吧
一个smarty的主题被俺俩弄成这样了

作者: Phzzy   发布时间: 2005-09-18

以上的办法虽笨,但却带给我意外的思路,不光是可以解决嵌套列表的需要,这个子模板的思路还可以应用于模块化显示不同功能页面的处理上。

作者: seraph   发布时间: 2005-09-18

原帖由 Phzzy 于 2005-9-18 21:16 发表
俺是这个......一直用这个.....-.-""

[code]
<?php
/*
* (C) Copyright 1999-2000 NetUSE GmbH
*                    Kristian Koehntopp
*
* $Id: template.inc,v 1.12 2002/07/11 22 ...


晕死。。。BS一下偶自已,原来一直没把template看透了。set_var第三个参数是这么用的。拜一下Phzzy。哈哈。

作者: seraph   发布时间: 2005-09-18