该如何使我的PHP脚本从设计中独立出来?这无疑地是在 PHP 邮件列表上所提问的最多的问题之一。虽然 PHP 被标榜为 "HTML 嵌入式语言", 在写过许多php和html混合式的工程之后,我产生了一个分离表单和内容的想法。而且,在许多公司里规划设计者的角色和程序设计者是分开的。于是,这样的一个模板解决方案产生了........
例如在我们公司,一个应用程序的开发流程如下:在提交计划文档之后,界面设计者[美工]制作了网站的外观模型,然后把它交给后台程序员。程序员使用PHP实现商业逻辑,同时使用外观模型做成基本架构。然后工程被返回到html页面设计者继续完善。就这样工程可能在后台程序员和页面设计者之间来来回回好几次。由于后台程序员不喜欢干预任何有关html标签,同时也不需要美工们和php鬼混在一起;美工设计者只需要配置文件,动态区块和其他的界面部分,不必要去接触那些错综复杂的php代码 。因此,这时候有一个很好的模板支持就显得很重要了。
纵观现今存在的许多php模板解决方案,大多数都只是提供了用模板取代变量和将动态区块的功能有限的格式化的基本方法。但是我们的需求比这个要高的多。我们完全不想要php程序员去设计html页面,可是这又是不可避免的。例如:如果美工想要在动态区块之间交替不同的背景颜色,他就可能得和程序员预先说好。同样,美工们也应该有自己对于页面设计的配置文件,这同样可以通过变量把他们拉到模板里边去。继续。
早在1999年后期,我们就已经开始为模板引擎写说明文档。在完成这个文档之后,我们开始用c写一个模板引擎,并有希望被包含到php里去。在 撞上了许多的技术难题的同时,“什么是模板应该做的,什么不该做”这个问题,也被热烈的讨论着。从这些经验,我们决定应该用Php将模板引擎写成一个类,让任何觉得合适的人使用它。所以我们写了一个引擎,从此就有了smarty.(注:这个类以前从来没有公开发表过)。这个类几乎达到了我们所有的要求:常规变量替换,支持包括其他模板,使用配置文件集成设置,嵌入Php代码,限制'if'语句的作用,还有更多的可以多层嵌套的健壮的动态区块。它用常规表达式做到这一切,于是代码变得相当,我们可以说:令人费解的。在每次调用的时候,都要去解析那些语法和常规表达式,于是在大型应用的时候,它显然慢了下来。在程序员的眼光看来,最大的问题还是使用php脚本建立和处理模板和动态区块的所有必要工作。我们应该如何使他变得更简单?
我们可以想象smarty应该有怎样的最后表现。我们知道php代码如果没有了模板解析的开销将有多快,我们也知道从一般的美工看来php语言是多么的"恐怖",然而这一切可以被一种更简单的模板语法掩饰掉。我们应该怎样把这两种方法的长处结合起来?于是,Smarty诞生了......
Smarty是一个php模板引擎。更准确的说,它分开了逻辑程序和外在的内容,提供了一种易于管理的方法。可以描述为应用程序员和美工扮演了不同的角色,因为在大多数情况下 ,他们不可能是同一个人。例如,你正在创建一个用于浏览新闻的网页,新闻标题,标签栏,作者和内容等都是内容要素,他们并不包含应该怎样去呈现。在Smarty的程序里,这些被忽略了。模板设计者们编辑模板,组合使用html标签和模板标签去格式化这些要素的输出(html表格,背景色,字体大小,样式表,等等)。有一天程序员想要改变文章检索的方式(也就是程序逻辑的改变)。这个改变不影响模板设计者,内容仍将准确的输出到模板。同样的,哪天美工吃多了想要完全重做界面,也不会影响到程序逻辑。因此,程序员可以改变逻辑而不需要重新构建模板,模板设计者可以改变模板而不影响到逻辑。
现在简短的说一下什么是smarty不做的。smarty不尝试将逻辑完全和模板分开。如果逻辑程序严格的用于页面表现,那么它在模板里不会出现问题。有个建议:让应用程序逻辑远离模板, 页面表现逻辑远离应用程序逻辑。这将在以后使内容更容易管理,程序更容易升级。
Smarty的特点之一是"模板编译"。意思是Smarty读取模板文件然后用他们创建php脚本。这些脚本创建以后将被执行。因此并没有花费模板文件的语法解析,同时每个模板可以享受到诸如Zend加速器(http://www.zend.com) 或者PHP加速器(http://www.php-accelerator.co.uk)。这样的php编译器高速缓存解决方案。
Smaty的一些特点:
1、 非常非常的快!
2、 用php分析器干这个苦差事是有效的
3、 不需要多余的模板语法解析,仅仅是编译一次
4、 仅对修改过的模板文件进行重新编译
5、 可以编辑'自定义函数'和自定义'变量',因此这种模板语言完全可以扩展
6、 可以自行设置模板定界符,所以你可以使用{}, {{}}, , 等等
7、 诸如 if/elseif/else/endif 语句可以被传递到php语法解析器,所以 {if ...} 表达式是简单的或者是复合的,随你喜欢啦
8、 如果允许的话,section之间可以无限嵌套
9、 引擎是可以定制的.可以内嵌php代码到你的模板文件中,虽然这可能并不需要(不推荐)
10、 内建缓存支持
11、 独立模板文件
12、 可自定义缓存处理函数
13、 插件体系结构
第一节 Requirements 要求
Smarty要求web服务器运行php4.0.6和以上版本.
第二节Basic Installation 基本安装
安装Smarty发行版在/libs/目录里的库文件(就是解压了). 这些php文件你可不能乱画哦.这些文件被所有应用程序共享,也只能在你升级到新版的smarty的时候得到更新。
例 2-1.Smarty库文件
Smarty.class.php Smarty_Compiler.class.php Config_File.class.php debug.tpl /core/*.php (all of them) /plugins/*.php (all of them) |
Smarty使用一个叫做'SMARTY_DIR'的php常量作为它的系统库目录。基本上,如果你的应用程序可以找到 Smarty.class.php文件,你不需要设置SMARTY_DIR,Smarty将会自己运作。但是,如果 Smarty.class.php没有在你的include_path(php.ini里的一项设置)里,或者没有在你的应用程序里设置它的绝对路径的时候,你就必须手动配置SMARTY_DIR 了(大多数程序都如此)SMARTY_DIR必须包含结尾斜杠。
这里是你在你的php脚本里创建一个smarty的应用实例的例子:
例 2-2.创建Smarty实例
require('Smarty.class.php'); $smarty = new Smarty; |
试着运行一下以上脚本,如果你发现"未找到Smarty.class.php 文件"的错误时,你应该这样做:
例 2-3.加入库文件目录的绝对路径
require('/usr/local/lib/php/Smarty/Smarty.class.php'); $smarty = new Smarty; |
例 2-4.在include_path加入库文件目录
// Edit your php.ini file, add the Smarty library // directory to the include_path and restart web server. // Then the following should work: require('Smarty.class.php'); $smarty = new Smarty; |
例 2-5.手工设置SMARTY_DIR常量
define('SMARTY_DIR','/usr/local/lib/php/Smarty/'); require(SMARTY_DIR.'Smarty.class.php'); $smarty = new Smarty; |
现在库文件已经搞定,该是设置为你的应用程序配置其他有关Smarty的目录的时候了。Smarty要求4个目录,默认下命名为:tempalates, templates_c, configs and cache。每个都是可以自定义的,可以修改Smarty类属性: $template_dir, $compile_dir, $config_dir, and $cache_dir respectively。强烈推荐你为每个用到smarty的应用程序设置单一的目录!
确定你已经知道了你的web服务器文件根目录。在我们的例子里,文件根目录是:"/web/www.mydomain.com/docs/"Smarty的4个目录 只可以被那些库文件访问,不可以被网络上的浏览器访问的目录。因此为避免任何安全问题,要求将那4个目录和网页文件目录(就是浏览器看的)分开来。
在你的文档目录下至少得有一个文件,这个文件可以被浏览器访问.我们叫它 "index.php"好了.把它放到"/guestbook/"目录下.
技术提示:建立web服务器很方便,这个文件可以被web服务器自动识别。如果你访问"http://www.mydomain.com/guestbook/",你不需要在URL上输入"index.php",index.php脚本就可以被执行。在Apache服务器中,可以通过在DirectoryIndex的后面添加"index.php" 文件(用反斜杠分开每个入口)来完成设置。
例 2-6.例子的文件结构
/usr/local/lib/php/Smarty/Smarty.class.php /usr/local/lib/php/Smarty/Smarty_Compiler.class.php /usr/local/lib/php/Smarty/Config_File.class.php /usr/local/lib/php/Smarty/debug.tpl /usr/local/lib/php/Smarty/core/*.php /usr/local/lib/php/Smarty/plugins/*.php
/web/www.mydomain.com/smarty/guestbook/templates/ /web/www.mydomain.com/smarty/guestbook/templates_c/ /web/www.mydomain.com/smarty/guestbook/configs/ /web/www.mydomain.com/smarty/guestbook/cache/
/web/www.mydomain.com/docs/guestbook/index.php |
Smarty的 $compile_dir 和$cache_dir必须可写。通常是user "nobody" 和 group "nobody"。如果是 OSX用户,默认为user "web" 和 group "web"。如果你在使用Apache,你可以看看httpd.conf 文件 (通常在"/usr/local/apache/conf/"目录下)哪些user和group正在被使用。
例 2-7 文件权限设置
chown nobody:nobody /web/www.mydomain.com/smarty/guestbook/templates_c/ chmod 770 /web/www.mydomain.com/smarty/guestbook/templates_c/
chown nobody:nobody /web/www.mydomain.com/smarty/guestbook/cache/ chmod 770 /web/www.mydomain.com/smarty/guestbook/cache/ |
技术提示: chmod 770相当安全了,它只让user "nobody" 和 group "nobody" 读/写 访问。如果你要对任何人开放读取访问权限(大多是为了你自己查看文件),你可以使用 775。
我们需要创建index.tpl文件让smarty载入.这个文件放在 $template_dir目录里。
例 2-8 编辑/web/www.mydomain.com/smarty/templates/index.tpl
{* Smarty *}
Hello, {$name}! |
技术提示:{* Smarty *} 是一个模板注释。虽然并不是必须的,但是这可以很好的锻炼你在模板文件里加入注释的习惯。它可以使文件便于识别。例如,一些文本编辑器可以识别这个文件,并加以语法高亮显示。
现在来编辑index.php。我们将创建一个Smarty的实例,指派模板变量,显示 index.tpl文件。在我们的例子的环境里, "/usr/local/lib/php/Smarty"已经包括在了 include_path里了。
例 2-9.编辑/web/www.mydomain.com/docs/guestbook/index.php
// load Smarty library require('Smarty.class.php');
$smarty = new Smarty;
$smarty->template_dir = '/web/www.mydomain.com/smarty/guestbook/templates/'; $smarty->compile_dir = '/web/www.mydomain.com/smarty/guestbook/templates_c/'; $smarty->config_dir = '/web/www.mydomain.com/smarty/guestbook/configs/'; $smarty->cache_dir = '/web/www.mydomain.com/smarty/guestbook/cache/';
$smarty->assign('name','Ned');
$smarty->display('index.tpl'); |
技术提示:在我们的例子里,已经设置了所有Smarty目录的绝对目录。如果 '/web/www.mydomain.com/smarty/guestbook/' 已经包括在 include_path里了,那么这些设置则没有必要。但是,从经验和通用性看来,为避免发生错误,还是配置一下为好。
现在在浏览器打开 index.php,你应该看到"Hello, Porky!",你现在已经完成了Smarty的基本设置,恭喜!!。
第三节 Extended Setup扩展设置
一个更灵活一点的配置Smarty的方法是扩展类,和初始化你的smarty环境。
为了避免重复地配置路径,我们可以在一个文件里配置这些变量。
我们创建一个目录 "/php/includes/guestbook/" 建立一个文件"setup.php"
同样先设置好smarty路径。
例2-10.编辑 /php/includes/guestbook/setup.php
// load Smarty library require('Smarty.class.php');
// The setup.php file is a good place to load // required application library files, and you // can do that right here. An example: // require('guestbook/guestbook.lib.php');是一个很好的加载应用程序的类库文件(就是扩展类) //例如你可以在index文件里包含它
class Smarty_GuestBook extends Smarty {
function Smarty_GuestBook() {
// Class Constructor. These automatically get set with each new instance. //类构造函数.创建实例的时候自动配置
$this->Smarty();
$this->template_dir = '/web/www.mydomain.com/smarty/guestbook/templates/'; $this->compile_dir = '/web/www.mydomain.com/smarty/guestbook/templates_c/'; $this->config_dir = '/web/www.mydomain.com/smarty/guestbook/configs/'; $this->cache_dir = '/web/www.mydomain.com/smarty/guestbook/cache/';
$this->caching = true; $this->assign('app_name','Guest Book'); }
} |
现在我们针对setup文件更改一下index文件
例 2-11.编辑/web/www.mydomain.com/docs/guestbook/index.php
require('guestbook/setup.php');
$smarty = new Smarty_GuestBook;
$smarty->assign('name','Ned');
$smarty->display('index.tpl'); |
现在你看到创建一个使用smarty的实例有多么的简单.从Smarty_GuestBook开始,重新构建我们的应用程序吧^_^
有的smarty模板标签都被加上了定界符.
默认情况下是 { 和},但它们是可被改变的.
例如,我们假定你在使用默认定界符.
在smarty里,所有定界符以外的内容都是静态输出的,或者称之为不可改变.
当smarty遇到了模板标签,将尝试解释他们,然后再以恰当的方式输出 .
第一节 Comments[注释]
.
模板注释被*号包围,例如 {* this is a comment *}
smarty注释不会在模板文件的最后输出中出现.
它只是模板内在的注释.
例 3-1.注释
{* Smarty *}
{* include the header file here *} {include file="header.tpl"}
{include file=$includeFile}
{include file=#includeFile#}
{* display dropdown lists *} {html_options values=$vals selected=$selected output=$output} |
第二节 Functions函数
每一个smarty标签输出一个变量或者调用某种函数.
在定界符内 函数(用'{'包住)和其属性(用界符包住)将被处理和输出.例如:
{funcname attr1="val" attr2="val"}.
例 3-2.函数语法
{config_load file="colors.conf"}
{include file="header.tpl"}
{if $highlight_name} Welcome, {$name}! {else} Welcome, {$name}! {/if}
{include file="footer.tpl"} |
在模板里无论是内建函数还是自定义函数都有相同的语法.
内建函数将在smarty内部工作,例如 {if} , {section} and {strip} .他们不能被修改.
自定义函数通过插件机制起作用,它们是附加函数. 只要你喜欢,可以随意修改.你也可以自行添加.
例如 {html_options} 和 {html_select_date}
第三节 Attributes[属性]
大多数函数都带有自己的属性以便于明确说明或者修改他们的行为.
smarty函数的属性很像HTML中的属性.
静态数值不需要加引号,但是字符串建议使用引号.
如果用变量作属性,它们也不能加引号.
一些属性用到了布尔值(真或假).
它们不需要加引号,可以是true,on,yes或者false,off,no.
例 3-3.函数属性语法
{include file="header.tpl"}
{include file=$includeFile}
{include file=#includeFile#}
{html_select_date display_days=yes}
{html_options values=$vals selected=$selected output=$output} |
Smarty有几种不同类型的变量.
变量 的类型取决于它的前缀是什么符号(或者被什么符号包围)
Smarty的变量可以直接被输出或者作为函数属性和修饰符(modifiers)的参数,或者用于内部的条件表达式等等.
如果要输出一个变量,只要用定界符将它括起来就可以.例如:
{$Name}
{$Contacts[row].Phone}
|
第一节 从PHP分配的变量
调用从PHP分配的变量需在前加"$"符号.(译注:同php一样)
调用模板内的assign函数分配的变量也是这样.(译注:也是用$加变量名来调用)
例 4-1.分配的变量
index.php:
$smarty->assign('lastLoginDate', 'January 11th, 2001'); $smarty->display('index.tpl'); index.tpl:
Hello {$firstname}, glad to see you could make it. Your last login was on {$lastLoginDate}.
OUTPUT:
Hello Doug, glad to see you could make it. Your last login was on January 11th, 2001. |
1、Associative arrays
Example 4-2. accessing associative array variables
index.php:
$smarty = new Smarty; $smarty->assign('Contacts', array('fax' => '555-222-9876', 'email' => '[email protected]', 'phone' => array('home' => '555-444-3333', 'cell' => '555-111-1234'))); $smarty->display('index.tpl');
index.tpl:
{$Contacts.fax} {$Contacts.email} {* you can print arrays of arrays as well *} {$Contacts.phone.home} {$Contacts.phone.cell}
OUTPUT:
555-222-9876 555-444-3333 555-111-1234 |
2、Array indexes
Example 4-3. accessing arrays by index
index.php:
$smarty = new Smarty; $smarty->assign('Contacts', array('555-222-9876', array('555-444-3333', '555-111-1234'))); $smarty->display('index.tpl');
index.tpl:
{$Contacts[0]} {$Contacts[1]} {* you can print arrays of arrays as well *} {$Contacts[2][0]} {$Contacts[2][1]}
OUTPUT:
555-222-9876 555-444-3333 555-111-1234 |
3、Objects
Example 4-4. accessing object properties
name: {$person->name} email: {$person->email}
OUTPUT:
name: Zaphod Beeblebrox email: [email protected] |
第二节 从配置文件读取的变量
配置文件中的变量需要通过用两个"#"或者是smarty的保留变量 $smarty.config.来调用(下节将讲到)
第二种语法在变量作为属性值并被引号括住的时候非常有用.
(译注:举个例子 {include file="#includefile#"} 这样#includefile#将被当作字符处理,而不表示配置文件变量,
但可以这样表示 {include file="`$smarty.config.includefile`"}不要忘了加``)
例 4-5.从配置文件引用的变量
foo.conf:
pageTitle = "This is mine" bodyBgColor = "#eeeeee" tableBorderSize = "3" tableBgColor = "#bbbbbb" rowBgColor = "#cccccc"
index.tpl:
{config_load file="foo.conf"}
index.tpl: (alternate syntax)
{config_load file="foo.conf"}
OUTPUT: (same for both examples)
|
第三节 {$smarty}保留变量
{$smarty}保留变量可以被用于访问一些特殊的模板变量.
以下是全部列表:
1、Request variables
Example 4-6. displaying request variables
{* display value of page from URL (GET) http://www.domain.com/index.php?page=foo *} {$smarty.get.page}
{* display the variable "page" from a form (POST) *} {$smarty.post.page}
{* display the value of the cookie "username" *} {$smarty.cookies.username}
{* display the server variable "SERVER_NAME" *} {$smarty.server.SERVER_NAME}
{* display the system environment variable "PATH" *} {$smarty.env.PATH}
{* display the php session variable "id" *} {$smarty.session.id}
{* display the variable "username" from merged get/post/cookies/server/env *} {$smarty.request.username} |
2、{$smarty.now}
Example 4-7. using {$smarty.now}
{* use the date_format modifier to show current date and time *} {$smarty.now|date_format:"%Y-%m-%d %H:%M:%S"} |
3、{$smarty.const}
Example 4-8. using {$smarty.const}
{$smarty.const._MY_CONST_VAL} |
4、{$smarty.capture}
The output captured via {capture}..{/capture} construct can be accessed using {$smarty} variable. See section on capture for an example.
5、{$smarty.config}
{$smarty} variable can be used to refer to loaded config variables. {$smarty.config.foo} is a synonym for {#foo#}. See the section on config_load for an example.
6、{$smarty.section}, {$smarty.foreach}
{$smarty} variable can be used to refer to 'section' and 'foreach' loop properties. See docs for section and foreach
7、{$smarty.template}
This variable contains the name of the current template being processed.
变量调节器用于变量,自定义函数和字符串。请使用‘|’符号和调节器名称应用调节器。变量调节器由赋予的参数值决定其行为。参数由‘:’符号分开。
例 5-1.调节器的例子
{* Uppercase the title *}
{$title|upper}
{* Truncate the topic to 40 characters use ... at the end *} Topic: {$topic|truncate:40:"..."}
{* format a literal string *} {"now"|date_format:"%Y/%m/%d"}
{* apply modifier to a custom function *} {mailto|upper address="[email protected]"} |
如果你给数组变量应用单值变量的调节,结果是数组的每个值都被调节。如果你只想要调节器用一个值调节整个数组,你必须在调节器名字前加上@符号。例如: {$articleTitle|@count}(这将会在 $articleTitle 数组里输出元素的数目)
第一节 capitalize
将变量里的所有单词首字大写。
例 5-2.首字大写
index.php:
$smarty = new Smarty; $smarty->assign('articleTitle', 'Police begin campaign to rundown jaywalkers.'); $smarty->display('index.tpl');
index.tpl:
{$articleTitle} {$articleTitle|capitalize} 转换成大写的
OUTPUT:
Police begin campaign to rundown jaywalkers. Police Begin Campaign To Rundown Jaywalkers. |
第二节 count_characters[字符计数]
Parameter Position |
Type |
Required |
Default |
Description |
1 |
boolean |
No |
false |
This determines whether or not to include whitespace characters in the count. |
计算变量里的字符数
Example 5-3. count_characters
index.php:
$smarty = new Smarty; $smarty->assign('articleTitle', 'Cold Wave Linked to Temperatures.'); $smarty->display('index.tpl');
index.tpl:
{$articleTitle} {$articleTitle|count_characters} {$articleTitle|count_characters:true}
OUTPUT输出:
Cold Wave Linked to Temperatures. 29 33 |
第三节 cat[连接字符串]
将cat里的值连接到给定的变量后面.
Example 5-4. cat
index.php:
$smarty = new Smarty; $smarty->assign('articleTitle', "Psychics predict world didn't end"); $smarty->display('index.tpl');
index.tpl:
{$articleTitle|cat:" yesterday. "}
OUTPUT:
Psychics predict world didn't end yesterday. |
第四节 count_paragraphs[计算段数]
计算变量里的段落数量。
Example 5-5. count_paragraphs
index.php:
$smarty = new Smarty; $smarty->assign('articleTitle', "War Dims Hope for Peace. Child's Death Ruins Couple's Holiday.\n\nMan is Fatally Slain. Death Causes Loneliness, Feeling of Isolation."); $smarty->display('index.tpl');
index.tpl:
{$articleTitle} {$articleTitle|count_paragraphs}
OUTPUT:
War Dims Hope for Peace. Child's Death Ruins Couple's Holiday.
Man is Fatally Slain. Death Causes Loneliness, Feeling of Isolation. 2 |
第五节 count_sentences[计算句数]
计算变量里句子的数量。
Example 5-6. count_sentences
index.php:
$smarty = new Smarty; $smarty->assign('articleTitle', 'Two Soviet Ships Collide - One Dies. Enraged Cow Injures Farmer with Axe.'); $smarty->display('index.tpl');
index.tpl:
{$articleTitle} {$articleTitle|count_sentences}
OUTPUT:
Two Soviet Ships Collide - One Dies. Enraged Cow Injures Farmer with Axe. 2 |
第六节 count_words[计算词数]
计算变量里的词数 。
Example 5-7. count_words
index.php:
$smarty = new Smarty; $smarty->assign('articleTitle', 'Dealers Will Hear Car Talk at Noon.'); $smarty->display('index.tpl');
index.tpl:
{$articleTitle} {$articleTitle|count_words}
OUTPUT:
Dealers Will Hear Car Talk at Noon. 7 |
第七节 date_format[格式化日期]
格式化从函数strftime()获得的时间和日期。
Unix或者mysql等的时间戳记(parsable by strtotime)都可以传递到smarty。
设计者可以使用date_format完全控制日期格式。
如果传给date_format的数据是空的,将使用第二个参数作为时间格式。
Parameter Position |
Type |
Required |
Default |
Description |
1 |
string |
No |
%b %e, %Y |
This is the format for the outputted date. |
2 |
string |
No |
n/a |
This is the default date if the input is empty. |
格式化从函数strftime()获得的时间和日期。
Unix或者mysql等的时间戳记(parsable by strtotime)都可以传递到smarty。
设计者可以使用date_format完全控制日期格式。
如果传给date_format的数据是空的,将使用第二个参数作为时间格式。
Example 5-8. date_format[日期格式]
index.php:
$smarty = new Smarty; $smarty->assign('yesterday', strtotime('-1 day')); $smarty->display('index.tpl');
index.tpl:
{$smarty.now|date_format} {$smarty.now|date_format:"%A, %B %e, %Y"} {$smarty.now|date_format:"%H:%M:%S"} {$yesterday|date_format} {$yesterday|date_format:"%A, %B %e, %Y"} {$yesterday|date_format:"%H:%M:%S"}
OUTPUT:
Feb 6, 2001 Tuesday, February 6, 2001 14:33:00 Feb 5, 2001 Monday, February 5, 2001 14:33:00 |
Example 5-9. date_format conversion specifiers[日期转换说明]
%a - abbreviated weekday name according to the current locale (根据当地格式输出“星期”缩写格式)
%A - full weekday name according to the current locale (根据当地格式输出“星期”全称格式)
%b - abbreviated month name according to the current locale (根据当地格式输出“月”缩写格式)
%B - full month name according to the current locale (根据当地格式输出“月”全称格式)
%c - preferred date and time representation for the current locale
%C - century number (the year divided by 100 and truncated to an integer, range 00 to 99)
%d - day of the month as a decimal number (range 00 to 31)
%D - same as %m/%d/%y
%e - day of the month as a decimal number, a single digit is preceded by a space (range 1 to 31)
%g - Week-based year within century [00,99]
%G - Week-based year, including the century [0000,9999]
%h - same as %b
%H - hour as a decimal number using a 24-hour clock (range 00 to 23)
%I - hour as a decimal number using a 12-hour clock (range 01 to 12)
%j - day of the year as a decimal number (range 001 to 366)
%k - Hour (24-hour clock) single digits are preceded by a blank. (range 0 to 23)
%l - hour as a decimal number using a 12-hour clock, single digits preceeded by a space (range 1 to 12)
%m - month as a decimal number (range 01 to 12)
%M - minute as a decimal number
%n - newline character
%p - either `am' or `pm' according to the given time value, or the corresponding strings for the current locale
%r - time in a.m. and p.m. notation
%R - time in 24 hour notation
%S - second as a decimal number
%t - tab character
%T - current time, equal to %H:%M:%S
%u - weekday as a decimal number [1,7], with 1 representing Monday
%U - week number of the current year as a decimal number, starting with the first Sunday as the first day of the first week
%V - The ISO 8601:1988 week number of the current year as a decimal number, range 01 to 53, where week 1 is the first week that has at least 4 days in the current year, and with Monday as the first day of the week.
%w - day of the week as a decimal, Sunday being 0
%W - week number of the current year as a decimal number, starting with the first Monday as the first day of the first week
%x - preferred date representation for the current locale without the time
%X - preferred time representation for the current locale without the date
%y - year as a decimal number without a century (range 00 to 99)
%Y - year as a decimal number including the century
%Z - time zone or name or abbreviation
%% - a literal `%' character
PROGRAMMERS NOTE: date_format is essentially a wrapper to PHP's strftime() function. You may have more or less conversion specifiers available depending on your system's strftime() function where PHP was compiled. Check your system's manpage for a full list of valid specifiers. 程序员提示:date_format本质上是php的strftime()函数的一个包装。 |
第八节 default[默认值]
Parameter Position |
Type |
Required |
Default |
Description |
1 |
string |
No |
empty |
This is the default value to output if the variable is empty. |
为空变量设置一个默认值。
当变量为空或者未分配的时候,将由给定的默认值替代输出。
Example 5-10. default
index.php:
$smarty = new Smarty; $smarty->assign('articleTitle', 'Dealers Will Hear Car Talk at Noon.'); $smarty->display('index.tpl');
index.tpl:
{$articleTitle|default:"no title"} {$myTitle|default:"no title"}
OUTPUT:
Dealers Will Hear Car Talk at Noon. no title |
第九节 escape[编码]
Parameter Position |
Type |
Required |
Possible Values |
Default |
Description |
1 |
string |
No |
html,htmlall,url,quotes,hex,hexentity,javascript |
html |
This is the escape format to use. |
用于html转码,url转码,在没有转码的变量上转换单引号,十六进制转码,十六进制美化,或者javascript转码。默认是html转码。
Example 5-11. escape
index.php:
$smarty = new Smarty; $smarty->assign('articleTitle', "'Stiff Opposition Expected to Casketless Funeral Plan'"); $smarty->display('index.tpl');
index.tpl:
{$articleTitle} {$articleTitle|escape} {$articleTitle|escape:"html"} {* escapes & " ' < > *} {$articleTitle|escape:"htmlall"} {* escapes ALL html entities *} {$articleTitle|escape:"url"} {$articleTitle|escape:"quotes"} {$EmailAddress|escape:"hexentity"}
OUTPUT:
'Stiff Opposition Expected to Casketless Funeral Plan' 'Stiff Opposition Expected to Casketless Funeral Plan' 'Stiff Opposition Expected to Casketless Funeral Plan' 'Stiff Opposition Expected to Casketless Funeral Plan' %27Stiff+Opposition+Expected+to+Casketless+Funeral+Plan%27 \'Stiff Opposition Expected to Casketless Funeral Plan\' |
第十节 indent[缩进]
Parameter Position |
Type |
Required |
Default |
Description |
1 |
integer |
No |
4 |
This determines how many characters to indent to. |
2 |
string |
No |
(one space) |
This is the character used to indent with.使用什么字符来代替缩进。 |
在每行缩进字符串,默认是4个字符。
作为可选参数,你可以指定缩进字符数。
作为第二个可选参数,你可以指定缩进用什么字符代替。
特别提示:使用缩进时如果是在HTML中,则需要使用& n b s p;(空格)来代替缩进,否则没有效果。
Example 5-12. indent
index.php:
$smarty = new Smarty; $smarty->assign('articleTitle', 'NJ judge to rule on nude beach.'); $smarty->display('index.tpl');
index.tpl:
{$articleTitle}
{$articleTitle|indent}
{$articleTitle|indent:10}
{$articleTitle|indent:1:"\t"}
OUTPUT:
NJ judge to rule on nude beach. Sun or rain expected today, dark tonight. Statistics show that teen pregnancy drops off significantly after 25.
NJ judge to rule on nude beach. Sun or rain expected today, dark tonight. Statistics show that teen pregnancy drops off significantly after 25.
NJ judge to rule on nude beach. Sun or rain expected today, dark tonight. Statistics show that teen pregnancy drops off significantly after 25.
NJ judge to rule on nude beach. Sun or rain expected today, dark tonight. Statistics show that teen pregnancy drops off significantly after 25. |
第十一节 lower 小写
将变量字符串小写
例 5-13.小写
index.php:
$smarty = new Smarty; $smarty->assign('articleTitle', 'Two Convicts Evade Noose, Jury Hung.'); $smarty->display('index.tpl');
index.tpl:
{$articleTitle} {$articleTitle|lower}
OUTPUT:
Two Convicts Evade Noose, Jury Hung. two convicts evade noose, jury hung. |
第十二节 nl2br换行符替换成
所有的换行符将被替换成
.功能同PHP中的nl2br()函数一样.
例 5-14.换行符替换成
index.php:
$smarty = new Smarty; $smarty->assign('articleTitle', "Sun or rain expected\ntoday, dark tonight"); $smarty->display('index.tpl');
index.tpl:
{$articleTitle|nl2br}
OUTPUT:
Sun or rain expected |
第十三节 regex_replace 正则替换
Parameter Position参数位置 |
Type类型 |
Required必需 |
Default默认 |
Description |
1 |
string |
Yes |
n/a |
This is the regular expression to be replaced. |
2 |
string |
Yes |
n/a |
This is the string of text to replace with. |
寻找和替换正则表达式 .
欲使用其语法,请参考Php手册中的preg_replace()函数.
例 5-15.正则替换
index.php:
$smarty = new Smarty; $smarty->assign('articleTitle', "Infertility unlikely to\nbe passed on, experts say."); $smarty->display('index.tpl');
index.tpl:
{* replace each carriage return, tab & new line with a space *} {$articleTitle} {$articleTitle|regex_replace:"/[\r\t\n]/":" "}
OUTPUT:
Infertility unlikely to be passed on, experts say. Infertility unlikely to be passed on, experts say. |
第十四节 replace 替换
Parameter Position参数位置 |
Type参数类型 |
Required必需 |
Default默认 |
Description |
1 |
string |
Yes |
n/a |
This is the string of text to be replaced. |
2 |
string |
Yes |
n/a |
This is the string of text to replace with. |
简单的搜索和替换字符串
例 5-16.替换
index.php:
$smarty = new Smarty; $smarty->assign('articleTitle', "Child's Stool Great for Use in Garden."); $smarty->display('index.tpl');
index.tpl:
{$articleTitle} {$articleTitle|replace:"Garden":"Vineyard"} {$articleTitle|replace:" ":" "}
OUTPUT:
Child's Stool Great for Use in Garden. Child's Stool Great for Use in Vineyard. Child's Stool Great for Use in Garden. |
第十五节 spacify 插空
Parameter Position参数位置 |
Type参数类型 |
Required必需 |
Default默认 |
Description描述 |
1 |
string |
No |
one space |
This what gets inserted between each character of the variable. |
插空(不知道这个词是什么意思,顾名思义了^^)是一种在字符串的每个字符之间插入空格或者其他的字符(串).
例 5-17.插空
|
第十六节 string_format 字符串格式化
Parameter Position参数位置 |
Type参数类型 |
Required必需 |
Default默认 |
Description描述 |
1 |
string |
Yes |
n/a |
This is what format to use. (sprintf) |
是一种格式化字符串的方法.例如格式化为十进制数等等.使用sprintf语法格式化
字符串格式化
index.php:
$smarty = new Smarty; $smarty->assign('number', 23.5787446); $smarty->display('index.tpl');
index.tpl:
{$number} {$number|string_format:"%.2f"} {$number|string_format:"%d"}
OUTPUT:
23.5787446 23.58 24 |
第十七 strip去除(多余空格)
用一个空格或一个给定字符替换所有重复空格,换行和制表符.
注意:如果想要去除模板文本中的区块,请使用 strip函数
例 5-19.去除(多余空格)
index.php:
$smarty = new Smarty; $smarty->assign('articleTitle', "Grandmother of\neight makes\t hole in one."); $smarty->display('index.tpl');
index.tpl:
{$articleTitle} {$articleTitle|strip} {$articleTitle|strip:" "}
OUTPUT:
Grandmother of eight makes hole in one. Grandmother of eight makes hole in one. Grandmother of eight makes hole in one. |
第十八 strip_tags 去除html标签
去除<和>标签,包括在<和>之间的任何内容.
例 5-20.去除Html标签
index.php:
$smarty = new Smarty; $smarty->assign('articleTitle', "Blind Woman Gets New Kidney from Dad she Hasn't Seen in years."); $smarty->display('index.tpl');
index.tpl:
{$articleTitle} {$articleTitle|strip_tags}
OUTPUT:
Blind Woman Gets New Kidney from Dad she Hasn't Seen in years. Blind Woman Gets New Kidney from Dad she Hasn't Seen in years. |
第十九 truncate 截取
Parameter Position参数位置 |
Type参数类型 |
Required必需 |
Default默认 |
Description描述 |
1 |
integer |
No |
80 |
This determines how many characters to truncate to. |
2 |
string |
No |
... |
This is the text to append if truncation occurs. |
3 |
boolean |
No |
false |
This determines whether or not to truncate at a word boundary (false), or at the exact character (true). |
从字符串开始处截取某长度的字符.默认是80个.
你也可以指定第二个参数作为追加在截取字符串后面的文本字串.该追加字串被计算在截取长度中。
默认情况下,smarty会截取到一个词的末尾。
如果你想要精确的截取多少个字符,把第三个参数改为"true"
例5-21.截取
index.php:
$smarty = new Smarty; $smarty->assign('articleTitle', 'Two Sisters Reunite after Eighteen Years at Checkout Counter.'); $smarty->display('index.tpl');
index.tpl:
{$articleTitle} {$articleTitle|truncate} {$articleTitle|truncate:30} {$articleTitle|truncate:30:""} {$articleTitle|truncate:30:"---"} {$articleTitle|truncate:30:"":true} {$articleTitle|truncate:30:"...":true}
OUTPUT:
Two Sisters Reunite after Eighteen Years at Checkout Counter. Two Sisters Reunite after Eighteen Years at Checkout Counter. Two Sisters Reunite after... Two Sisters Reunite after Two Sisters Reunite after--- Two Sisters Reunite after Eigh Two Sisters Reunite after E... |
第二十 upper 大写
将变量改为大写
例 5-22.大写
index.php:
$smarty = new Smarty; $smarty->assign('articleTitle', "If Strike isn't Settled Quickly it may Last a While."); $smarty->display('index.tpl');
index.tpl:
{$articleTitle} {$articleTitle|upper}
OUTPUT:
If Strike isn't Settled Quickly it may Last a While. IF STRIKE ISN'T SETTLED QUICKLY IT MAY LAST A WHILE. |
对于同一个变量,你可以使用多个修改器。它们将从左到右按照设定好的顺序被依次组合使用。使用时必须要用"|"字符作为它们之间的分隔符。http://www.kaixinmi.com/
例 6-1.组合修改器
index.php:
$smarty = new Smarty; $smarty->assign('articleTitle', 'Smokers are Productive, but Death Cuts Efficiency.'); $smarty->display('index.tpl');
index.tpl:
{$articleTitle} {$articleTitle|upper|spacify} {$articleTitle|lower|spacify|truncate} {$articleTitle|lower|truncate:30|spacify} {$articleTitle|lower|spacify|truncate:30:". . ."}
OUTPUT:
Smokers are Productive, but Death Cuts Efficiency. S M O K E R S A R E P R O D U C T I V E , B U T D E A T H C U T S E F F I C I E N C Y . s m o k e r s a r e p r o d u c t i v e , b u t d e a t h c u t s... s m o k e r s a r e p r o d u c t i v e , b u t . . . s m o k e r s a r e p. . . |
Smarty自带一些内建函数.
内建函数是模板语言的一部分.
用户不能创建名称和内建函数一样的自定义函数,也不能修改内建函数.
第一节
1、capture
属性 |
类型 |
是否必须 |
缺省值 |
描述 |
name |
string |
no |
default |
数据采集区域名称 |
assign |
string |
No |
n/a |
数据采集区域在哪分配给变量name[待考] |
capture函数的作用是捕获模板输出的数据并将其存储到一个变量里,而不是把它们输出到页面.
任何在 {capture name="foo"}和{/capture}之间的数据将被存储到变量$foo中,该变量由name属性指定.
在模板中通过 $smarty.capture.foo 访问该变量.
如果没有指定 name 属性,函数默认将使用 "default" 作为参数.
{capture}必须成对出现,即以{/capture}作为结尾,该函数不能嵌套使用.
技术提示:
Smarty 1.4.0 - 1.4.4 版把捕获到的内容存储于 $return 变量里.
在 1.4.5 版以后就将该数据保存到了由 name 属性指定的变量里.请升级你的模板.
警告 |
当希望捕获包含 {insert} 命令的数据时要特别注意. 如果打开了缓存并希望将 {insert} 命令输出到缓存中,不要捕获该区域的数据. |
例 7-1.捕获模板内容
{* we don't want to print a table row unless content is displayed *} {capture name=banner} {include file="get_banner.tpl"} {/capture} {if $smarty.capture.banner ne ""}
|
{$smarty.capture.banner}
|
2、config_load该函数用于从配置文件中加载变量.
属性 |
类型 |
是否必须 |
缺省值 |
描述 |
file |
string |
Yes |
n/a |
待包含的配置文件的名称 |
section |
string |
No |
n/a |
配置文件中待加载部分的名称 |
scope |
string |
no |
local |
加载数据的作用域,取值必须为local, parent 或 global. local 说明该变量的作用域为当前模板. parent 说明该变量的作用域为当前模板和当前模板的父模板(调用当前模板的模板). global 说明该变量的作用域为所有模板. |
global |
boolean |
No |
No |
说明加载的变量是否全局可见,等同于 scope=parent. 注意: 当指定了 scope 属性时,可以设置该属性,但模板忽略该属性值而以 scope 属性为准。 |
例 7-2.演示 config_load 函数
{config_load file="colors.conf"}
|
配置文件有可能包含多个部分,此时可以使用附加属性 section 指定从哪一部分中取得变量.
注意:配置文件中的 section 和模板内建函数 section 只是命名相同,毫不相干。
例 7-3. 带 section 属性的 config_load 函数演示
{config_load file="colors.conf" section="Customer"}
|
3、foreach,foreachelse
属性 |
类型 |
是否必须 |
缺省值 |
描述 |
from |
string |
Yes |
n/a |
待循环数组的名称 |
item |
string |
Yes |
n/a |
当前处理元素的变量名称 |
key |
string |
No |
n/a |
当前处理元素的键名 |
name |
string |
No |
n/a |
该循环的名称,用于访问该循环 |
foreach 是除 section 之外处理循环的另一种方案(根据不同需要选择不同的方案).
foreach 用于处理简单数组(数组中的元素的类型一致),它的格式比 section 简单许多,缺点是只能处理简单数组.
foreach 必须和 /foreach 成对使用,且必须指定 from 和 item 属性.
name 属性可以任意指定(字母、数字和下划线的组合).
foreach 可以嵌套,但必须保证嵌套中的 foreach 名称唯一.
from 属性(通常是数组)决定循环的次数.
foreachelse 语句在 from 变量没有值的时候被执行.
例 7-4. foreach 演示
{* this example will print out all the values of the $custid array *} {* 该例将输出数组 $custid 中的所有元素的值 *} {foreach from=$custid item=curr_id} id: {$curr_id} {/foreach}
OUTPUT:
id: 1000 id: 1001 id: 1002 |
例 7-5. foreach 键的演示
{* The key contains the key for each looped value
assignment looks like this:
$smarty->assign("contacts", array(array("phone" => "1", "fax" => "2", "cell" => "3"), array("phone" => "555-4444", "fax" => "555-3333", "cell" => "760-1234"))); *} {* 键就是数组的下标,请参看关于数组的解释 *}
{foreach name=outer item=contact from=$contacts} {foreach key=key item=item from=$contact} {$key}: {$item} {/foreach} {/foreach}
OUTPUT:
phone: 1 fax: 2 cell: 3 phone: 555-4444 fax: 555-3333 cell: 760-1234 |
foreach 循环有自己的变量名,使用该变量名可以访问该循环. 使用方法为{$smarty.foreach.foreachname.varname},其中 foreachname 即在 foreach 中指定的 name 属性.
4、include
属性 |
类型 |
是否必须 |
缺省值 |
描述 |
file |
string |
Yes |
n/a |
待包含的模板文件名 |
assign |
string |
No |
n/a |
该属性指定一个变量保存待包含模板的输出 |
[var ...] |
[var type] |
No |
n/a |
传递给待包含模板的本地参数,只在待包含模板中有效 |
Include 标签用于在当前模板中包含其它模板. 当前模板中的变量在被包含的模板中可用. 必须指定 file 属性,该属性指明模板资源的位置.
如果设置了 assign 属性,该属性对应的变量名用于保存待包含模板的输出,这样待包含模板的输出就不会直接显示了。
例 7-6. include 函数演示
{include file="header.tpl"}
{* body of template goes here *}
{include file="footer.tpl"} |
可以在属性中传递参数给待包含模板. 传递给待包含模板的参数只在待包含模板中可见. 如果传递的参数在待包含模板中有同名变量,那么该变量被传递的参数替代.
例 7-7. 带传递参数的 include 函数演示
{include file="header.tpl" title="Main Menu" table_bgcolor="#c0c0c0"}
{* body of template goes here *}
{include file="footer.tpl" logo="http://my.domain.com/logo.gif"} |
包含 $template_dir 文件夹之外的模板请使用 模板资源 说明的格式.
例 7-8. 使用外部模板资源的 include 函数演示
{* absolute filepath *} {include file="/usr/local/include/templates/header.tpl"}
{* absolute filepath (same thing) *} {include file="file:/usr/local/include/templates/header.tpl"}
{* windows absolute filepath (MUST use "file:" prefix) *} {include file="file:C:/www/pub/templates/header.tpl"}
{* include from template resource named "db" *} {include file="db:header.tpl"} |
5、include_php
属性 |
类型 |
是否必须 |
缺省值 |
描述 |
file |
string |
Yes |
n/a |
待包含php文件的名称 |
once |
boolean |
No |
true |
如果待包含php文件已被包含是否仍然包含(类似php中的include_once函数) |
assign |
string |
No |
n/a |
该属性指定一个变量保存待包含php文件的输出 |
inluce_php 函数用于在模板中包含 php 脚本. 如果设置了安全模式,被包含的脚本必须位于 $trusted_dir 路径下. include_php 函数必须设置 file 属性,该属性指明被包含 php 文件的路径,可以是 $trusted_dir 的相对路径,也可以是绝对路径.
include_php 是解决模板部件化的好方法,它使得 php 代码从模板文件中被分离出来. 举个例子:假设有一个从数据库中动态取出数据用于显示站点导航的模板,你可以将得数据内容的 php 逻辑部分分离出来保存在一个单独的文件夹下,并在模板开始的位置包含该 php 脚本. 那么就可以在任何地方包含此模板而不用担心之前数据库信息是否已被程序取出.
即使是在模板中多次地调用 php 文件,默认情况下它们只被包含一次. 你可以设置 once 属性从而指明每次调用都重新包含该文件. 如果将 once 属性设置为 false,每次调用该文件都将被重新包含.
如果设置了 assign 属性,该属性对应的变量名用于保存待包含 php 的输出,这样待包含 php 文件的输出就不会直接显示了。
在待包含 php 文件中可以通过 $this 访问 smarty 对象.
例 7-9. include_php 函数演示
load_nav.php -------------
// load in variables from a mysql db and assign them to the template // 从mysql数据库中取得数据,将数据赋给模板变量 $sql = new MySQL; $sql->query("select * from site_nav_sections order by name",SQL_ALL); $this->assign('sections',$sql->record);
?>
index.tpl ---------
{* absolute path, or relative to $trusted_dir *} {* 绝对路径或 $trusted_dir 的相对路径 *} {include_php file="/path/to/load_nav.php"}
{foreach item="curr_section" from=$sections} {/foreach} |
6、insert
属性 |
类型 |
是否必须 |
缺省值 |
描述 |
name |
string |
Yes |
n/a |
插入函数的名称 |
assign |
string |
No |
n/a |
该属性指定一个变量保存待插入函数输出 |
script |
string |
No |
n/a |
插入函数前需要先包含的php脚本名称 |
[var ...] |
[var type] |
No |
n/a |
传递给待插入函数的本地参数 |
Insert 函数类似欲 inluce 函数,不同之处是 insert 所包含的内容不会被缓存,每次调用该模板都会重新执行该函数.
例如你在页面上端使用一个带有广告条位置的模板,广告条可以包含任何HTML、图象、FLASH等混合信息. 因此这里不能使用一个静态的链接,同时我们也不希望该广告条被缓存. 这就需要在 insert 函数指定:#banner_location_id# 和 #site_id# 值(从配置文件中取),同时需要一个函数取广告条的内容信息.
例 7-10. insert 函数演示
{* example of fetching a banner *} {insert name="getBanner" lid=#banner_location_id# sid=#site_id#} |
在此例中,我们使用了 getBanner 作为 name 属性,同时传递了 #banner_location_id# 和 #site_id# 两个参数. 接下来 Smarty 在你的 php 程序中搜索名为 insert_getBanner() 的函数,#banner_location_id# 和 #site_id# 的值被组合成一个数组作为函数的第一个参数传递给该函数. 为了避免函数命名混乱,所有的 insert 函数都必须以 insert_ 开头. 你的 insert_getBanner() 函数根据传递的参数执行并返回执行的结果. 这些结果就显示在模板中调用该函数的位置. 在此例中 Smarty 调用该函数类似insert_getBanner(array("lid"=>"12345","sid"=>67890"));并将返回的结果显示在调用的位置.
如果设置了 assign 属性,该属性对应的变量名用于保存待包含函数的输出,这样待包含函数的输出就不会直接显示了.注意:赋给模板变量的输出信息在缓存的时候同样无效.
如果指定了 script 属性,在调用函数并执行前将先包含(只包含一次)script指定的 php 脚本. 这是为了防止被调用的函数不存在,先调用包含该函数的 php 脚本将避免该情况.
Smart 对象作为函数的第二个参数被传递,在待包含函数中可以通过 $this 访问并修改 smarty 对象信息.
技术要点: 使模板的一部分不被缓存. 如果打开了缓存, insert 函数却不会被缓存,每次调用页面它们都会被动态加载,即使是在缓存页面中. 该特性可以广泛应用于广告条、投票、实时天气预报、搜索结果、反馈信息等区域.
7、if,elseif,else
Smarty 中的 if 语句和 php 中的 if 语句一样灵活易用,并增加了几个特性以适宜模板引擎. if 必须于 /if 成对出现. 可以使用 else 和 elseif 子句. 可以使用以下条件修饰词:eq、ne、neq、gt、lt、lte、le、gte、ge、is even、is odd、is not even、is not odd、not、mod、div by、even by、odd by、==、!=、>、<、<=、>=. 使用这些修饰词时必须和变量或常量用空格格开.
例 7-11. if 语句演示
{if $name eq "Fred"} Welcome Sir. {elseif $name eq "Wilma"} Welcome Ma'am. {else} Welcome, whatever you are. {/if}
{* an example with "or" logic *} {if $name eq "Fred" or $name eq "Wilma"} ... {/if}
{* same as above *} {if $name == "Fred" || $name == "Wilma"} ... {/if}
{* the following syntax will NOT work, conditional qualifiers must be separated from surrounding elements by spaces *} {if $name=="Fred" || $name=="Wilma"} ... {/if}
{* parenthesis are allowed *} {if ( $amount < 0 or $amount > 1000 ) and $volume >= #minVolAmt#} ... {/if}
{* you can also embed php function calls *} {if count($var) gt 0} ... {/if}
{* test if values are even or odd *} {if $var is even} ... {/if} {if $var is odd} ... {/if} {if $var is not odd} ... {/if}
{* test if var is divisible by 4 *} {if $var is div by 4} ... {/if}
{* test if var is even, grouped by two. i.e., 0=even, 1=even, 2=odd, 3=odd, 4=even, 5=even, etc. *} {if $var is even by 2} ... {/if}
{* 0=even, 1=even, 2=even, 3=odd, 4=odd, 5=odd, etc. *} {if $var is even by 3} ... {/if} |
8、ldelim,rdelim
ldelim 和 rdelim 用于输出分隔符,也就是大括号 "{" 和 "}". 模板引擎总是尝试解释大括号内的内容,因此如果需要输出大括号,请使用此方法.
例 7-12. 使用 ldelim, rdelim 演示
{* this will print literal delimiters out of the template *}
{ldelim}funcname{rdelim} is how functions look in Smarty!
OUTPUT:
{funcname} is how functions look in Smarty! |
9、literal
Literal 标签区域内的数据将被当作文本处理,此时模板将忽略其内部的所有字符信息. 该特性用于显示有可能包含大括号等字符信息的 javascript 脚本. 当这些信息处于 {literal}{/literal} 标签中时,模板引擎将不分析它们,而直接显示.
例 7-13. literal 标签演示
{literal}
{/literal} |
10、php
php 标签允许在模板中直接嵌入 php 脚本. 是否处理这些语句取决于$php_handling的设置. 该语句通常不需要使用,当然如果你非常了解此特性或认为必须要用,也可以使用.
例 7-14. php 标签演示
{php} // including a php script directly // from the template. include("/path/to/display_weather.php"); {/php} |
第二节section,sectionelse
属性 |
类型 |
是否必须 |
缺省值 |
描述 |
name |
string |
Yes |
n/a |
该循环的名称 |
loop |
[$variable_name] |
Yes |
n/a |
决定循环次数的变量名称 |
start |
integer |
No |
0 |
循环执行的初始位置. 如果该值为负数,开始位置从数组的尾部算起. 例如:如果数组中有7个元素,指定start为-2,那么指向当前数组的索引为5. 非法值(超过了循环数组的下限)将被自动调整为最接近的合法值. |
step |
integer |
No |
1 |
该值决定循环的步长. 例如指定step=2将只遍历下标为0、2、4等的元素. 如果step为负值,那么遍历数组的时候从后向前遍历. |
max |
integer |
No |
1 |
设定循环最大执行次数. |
show |
boolean |
No |
true |
决定是否显示该循环. |
模板的 section 用于遍历数组中的数据. section 标签必须成对出现. 必须设置 name 和 loop 属性. 名称可以是包含字母、数字和下划线的任意组合. 可以嵌套但必须保证嵌套的 name 唯一. 变量 loop (通常是数组)决定循环执行的次数. 当需要在 section 循环内输出变量时,必须在变量后加上中括号包含着的 name 变量. sectionelse 当 loop 变量无值时被执行.
例 7-15. section 函数演示
{* this example will print out all the values of the $custid array *} {section name=customer loop=$custid} id: {$custid[customer]} {/section}
OUTPUT:
id: 1000 id: 1001 id: 1002 |
例 7-16.loop 变量演示
{* the loop variable only determines the number of times to loop. you can access any variable from the template within the section. This example assumes that $custid, $name and $address are all arrays containing the same number of values *} {section name=customer loop=$custid} id: {$custid[customer]} name: {$name[customer]} address: {$address[customer]}
{/section}
OUTPUT:
id: 1000 name: John Smith address: 253 N 45th id: 1001 name: Jack Jones address: 417 Mulberry ln id: 1002 name: Jane Munson address: 5605 apple st |
例 7-17. section 名称演示
{* the name of the section can be anything you like, and it is used to reference the data within the section *} {section name=mydata loop=$custid} id: {$custid[mydata]} name: {$name[mydata]} address: {$address[mydata]}
{/section} |
例 7-18. 嵌套 section 演示
{* sections can be nested as deep as you like. With nested sections, you can access complex data structures, such as multi-dimensional arrays. In this example, $contact_type[customer] is an array of contact types for the current customer. *} {section name=customer loop=$custid} id: {$custid[customer]} name: {$name[customer]} address: {$address[customer]} {section name=contact loop=$contact_type[customer]} {$contact_type[customer][contact]}: {$contact_info[customer][contact]} {/section}
{/section}
OUTPUT:
id: 1000 name: John Smith address: 253 N 45th home phone: 555-555-5555 cell phone: 555-555-5555 e-mail: [email protected] id: 1001 name: Jack Jones address: 417 Mulberry ln home phone: 555-555-5555 cell phone: 555-555-5555 e-mail: [email protected] id: 1002 name: Jane Munson address: 5605 apple st home phone: 555-555-5555 cell phone: 555-555-5555 e-mail: [email protected] |
例 7-19. section 遍历多维数组演示
{* This is an example of printing an associative array of data within a section *} {section name=customer loop=$contacts} name: {$contacts[customer].name} home: {$contacts[customer].home} cell: {$contacts[customer].cell} e-mail: {$contacts[customer].email} {/section}
OUTPUT:
name: John Smith home: 555-555-5555 cell: 555-555-5555 e-mail: [email protected] name: Jack Jones home phone: 555-555-5555 cell phone: 555-555-5555 e-mail: [email protected] name: Jane Munson home phone: 555-555-5555 cell phone: 555-555-5555 e-mail: [email protected] |
例 7-20. sectionelse 演示
{* sectionelse will execute if there are no $custid values *} {section name=customer loop=$custid} id: {$custid[customer]} {sectionelse} there are no values in $custid. {/section} |
Section 循环也有可供调用的变量名. 通过如下方式调用{$smarty.section.sectionname.varname}.
注意:Smarty 1.5.0 版中,section 名称属性变量的格式由{%sectionname.varname%}变成 {$smarty.section.sectionname.varname},老版本的格式依然支持,但在手册的例子中只提供新的格式.
1、index
index 用于显示当前循环的索引,从0开始(如果指定了start属性,那么由该值开始),每次加1(如果指定了step属性,那么由该值决定).
技术细节:如果没有指定step和start属性,此值的作用和iteration类似,只不过从0开始而已.
例 7-21. section 的 index 属性演示
{section name=customer loop=$custid} {$smarty.section.customer.index} id: {$custid[customer]} {/section}
OUTPUT:
0 id: 1000 1 id: 1001 2 id: 1002 |
2、index_prev
index_prev 用于显示上一个循环索引值. 循环开始时,此值为-1.
例 7-22. section 的 index_prev 属性演示
{section name=customer loop=$custid} {$smarty.section.customer.index} id: {$custid[customer]} {* FYI, $custid[customer.index] and $custid[customer] are identical in meaning *} {if $custid[customer.index_prev] ne $custid[customer.index]} The customer id changed {/if} {/section}
OUTPUT:
0 id: 1000 The customer id changed 1 id: 1001 The customer id changed 2 id: 1002 The customer id changed |
3、index_next
index_next 用于显示下一个循环索引值. 循环执行到最后一次时,此值仍然比当前索引值大1(如果指定了step,取决于此值).
例 7-22. section 的 index_next 属性演示
{section name=customer loop=$custid} {$smarty.section.customer.index} id: {$custid[customer]} {* FYI, $custid[customer.index] and $custid[customer] are identical in meaning *} {if $custid[customer.index_next] ne $custid[customer.index]} The customer id will change {/if} {/section}
OUTPUT:
0 id: 1000 The customer id will change 1 id: 1001 The customer id will change 2 id: 1002 The customer id will change |
4、iteration
iteration 用于显示循环的次数.
注意:iteration 不像index属性受start、step和max属性的影响,该值总是从1开始(index是从0开始的).rownum 是iteration的别名,两者等同.
例 7-24. section 的 iteration 属性演示
{section name=customer loop=$custid start=5 step=2} current loop iteration: {$smarty.section.customer.iteration} {$smarty.section.customer.index} id: {$custid[customer]} {* FYI, $custid[customer.index] and $custid[customer] are identical in meaning *} {if $custid[customer.index_next] ne $custid[customer.index]} The customer id will change {/if} {/section}
OUTPUT:
current loop iteration: 1 5 id: 1000 The customer id will change current loop iteration: 2 7 id: 1001 The customer id will change current loop iteration: 3 9 id: 1002 The customer id will change |
5、first
如果当前循环第一次执行,first 被设置为true.
例 7-25. section 的 first 属性演示
{section name=customer loop=$custid} {if $smarty.section.customer.first}
{/if} {/section}
OUTPUT:
|
6、last
如果当前循环执行到最后一次,last 被设置为true.
例 7-26. section 的 last 属性演示
{section name=customer loop=$custid} {if $smarty.section.customer.first}
{/if} {/section}
OUTPUT:
|
7、rownum
rownum 用于显示循环的次数. 该属性是iteration的别名,两者等同.
例 7-27. section 的 rownum 属性演示
{section name=customer loop=$custid} {$smarty.section.customer.rownum} id: {$custid[customer]} {/section}
OUTPUT:
1 id: 1000 2 id: 1001 3 id: 1002 |
8、loop
loop 用于显示该循环上一次循环时的索引值. 该值可以用于循环内部或循环结束后.
Example 7-28. section property index
{section name=customer loop=$custid} {$smarty.section.customer.index} id: {$custid[customer]} {/section}
There were {$smarty.section.customer.loop} customers shown above.
OUTPUT:
0 id: 1000 1 id: 1001 2 id: 1002
There were 3 customers shown above. |
9、show
show 是 section 的参数. show 取值为布尔值 true 或 false. 如果设置为 false,该循环将不显示. 如果指定了 sectionelse 子句,该字句是否显示也取决于该值.
例 7-29. section 的 show 属性演示
{* $show_customer_info may have been passed from the PHP application, to regulate whether or not this section shows *} {section name=customer loop=$custid show=$show_customer_info} {$smarty.section.customer.rownum} id: {$custid[customer]} {/section}
{if $smarty.section.customer.show} the section was shown. {else} the section was not shown. {/if}
OUTPUT:
1 id: 1000 2 id: 1001 3 id: 1002
the section was shown. |
11、total
total 用于显示循环执行总的次数. 可以在循环中或执行结束后调用此属性.
例 7-30. section 的 total 属性演示
{section name=customer loop=$custid step=2} {$smarty.section.customer.index} id: {$custid[customer]} {/section}
There were {$smarty.section.customer.total} customers shown above.
OUTPUT:
0 id: 1000 2 id: 1001 4 id: 1002
There were 3 customers shown above. |
第三节 strip
Web 开发者多次遇到空格和回车影响HTML输出的情形(浏览器的"特性"),为了得到特定的结果,因此你不得不在模板里运行所有的标签. 通常在难以理解或难以处理的模板中遇到此问题.
Smarty 在显示前将除区任何位于 {strip}{/strip} 标记中数据的首尾空格和回车. 这样可以保证模板容易理解且不用担心多余的空格导致问题.
例 7-31. strip 标签演示
{* the following will be all run into one line upon output *} {strip}
{/strip}
OUTPUT:
|
请注意上例,所有行都以HTML标签开头结尾. 所有行被组织到一起运行. 如果在行首和行尾有文本的话,它们也会被组织到一起,就有可能得到你不想得到的结果.
用户可以使用 Smarty 自带的一组自定义函数.
第一节assign
属性 |
类型 |
是否必须 |
缺省值 |
描述 |
var |
string |
Yes |
n/a |
被赋值的变量名 |
value |
string |
Yes |
n/a |
赋给变量的值 |
assign 用于在模板被执行时为模板变量赋值.
例 8-1. assign 函数演示
{assign var="name" value="Bob"}
The value of $name is {$name}.
OUTPUT:
The value of $name is Bob. |
第二节 counter
属性 |
类型 |
是否必须 |
缺省值 |
描述 |
name |
string |
No |
default |
计数器的名称 |
start |
number |
No |
1 |
记数器初始值 |
skip |
number |
No |
1 |
记数器间隔、步长 |
direction |
string |
No |
up |
记数器方向,(增/减) |
boolean |
No |
true |
是否输出值 |
|
assign |
string |
No |
n/a |
输出值将被赋给模板变量的名称 |
counter 用于输出一个记数过程. counter 保存了每次记数时的当前记数值. 用户可以通过调节 interval 和 direction 调节该值. 也可以决定是否输出该值. 如果需要同时运行多个计数器,必须为它们指定不同的名称. 如果没有指定名称,模板引擎使用 "default" 作为缺省值.
如果指定了 "assign" 这个特殊属性,该计数器的输出值将被赋给由 assign 指定的模板变量,而不是直接输出.
例 8-2. counter 函数演示
{* initialize the count *} {counter start=0 skip=2 print=false}
{counter} {counter} {counter} {counter}
OUTPUT:
2 4 6 8 |
第三节 cycle
属性 |
类型 |
是否必须 |
缺省值 |
描述 |
name |
string |
No |
default |
轮转的名称 |
values |
mixed |
Yes |
N/A |
待轮转的值,可以是用逗号分隔的列表(请查看 delimiter 属性)或一个包含多值的数组. |
boolean |
No |
true |
是否输出值 |
|
advance |
boolean |
No |
true |
是否使用下一个值(为 false 时使用当前值) |
delimiter |
string |
No |
, |
指出values 属性中使用的分隔符,默认是逗号. |
assign |
string |
No |
n/a |
输出值将被赋给模板变量的名称 |
Cycle 用于轮转使用一组值. 该特性使得在表格中交替输出颜色或轮转使用数组中的值变得很容易.
如果需要在模板中使用多个轮转,需要给出唯一的 name 属性.
用户可以设置 print 属性为 false 强制不输出当前值. 该特性可以很方便地略过某个值.
advance 属性用于重复使用某个值. 当该属性设置为 false 时,下次调用该轮转时将输出同样的值.
如果指定了 "assign" 这个特殊属性,该轮转的输出值将被赋给由 assign 指定的模板变量,而不是直接输出.
例 8-3. cycle 函数演示
{section name=rows loop=$data} |
{$data[rows]} |
1 |
2 |
3 |
第四节 debug
属性 |
类型 |
是否必须 |
缺省值 |
描述 |
output |
string |
No |
html |
输出类型,html或javascript |
{debug} 将调式信息输出到页面上. 该函数是否可用取决于 Smarty 的 debug 设置. 该函数在运行时取得数据,因此不能显示使用中的模板,只能显示运行时被赋值的变量. 不过还是可以看到所有模板内当前可用的变量.
第五节 eval
属性 |
类型 |
是否必须 |
缺省值 |
描述 |
var |
mixed |
Yes |
n/a |
待求值的变量(或字符串) |
assign |
string |
No |
n/a |
输出值将被赋给模板变量的名称 |
eval 按处理模板的方式计算取得变量的值. 该特性可用于在配置文件中的标签/变量中嵌入其它模板标签/变量.
如果指定了 "assign" 这个特殊属性,该函数的输出值将被赋给由 assign 指定的模板变量,而不是直接输出.
技术要点: 待求值处理的变量被当作模板来处理. 它们和模板一样遵循同样的结构和安全特性.
技术要点: 待求值处理的变量每次调用时被重编译,不保存编译版本! 但当打开缓冲设置时,该输出会被其它模板缓冲.
例 8-4. eval 函数演示
setup.conf ----------
emphstart = emphend = title = Welcome to {$company}'s home page! ErrorCity = You must supply a {#emphstart#}city{#emphend#}. ErrorState = You must supply a {#emphstart#}state{#emphend#}.
index.tpl ---------
{config_load file="setup.conf"}
{eval var=$foo} {eval var=#title#} {eval var=#ErrorCity#} {eval var=#ErrorState# assign="state_error"} {$state_error}
OUTPUT:
This is the contents of foo. Welcome to Foobar Pub & Grill's home page! You must supply a city. You must supply a state. |
第六节 fetch
属性 |
类型 |
是否必须 |
缺省值 |
描述 |
file |
string |
Yes |
n/a |
待请求的文件,http或ftp方式. |
assign |
string |
No |
n/a |
输出值将被赋给模板变量的名称 |
fetch 用于从本地文件系统、HTTP或FTP上取得文件并显示文件的内容. 如果文件名称以"http://"开头,将取得该网站页面并显示. 如果文件名称以"ftp://"开头,将从ftp服务器取得该文件并显示.
如果指定了 "assign" 这个特殊属性,该函数的输出值将被赋给由 assign 指定的模板变量,而不是直接输出.(Smarty 版本 1.5.0 新特性)
技术要点: 该函数不支持HTTP重定向,如果要取得web默认页,比如想取得www.domain.com的主页资料,但是不知道主页的具体名称,可能是index.php或index.htm或default.php等等,可以直接使用该站点的url,记得在url结尾处加上反斜线.
技术要点: 如果模板的安全设置打开了,当取本地文件时只能取位于定义为安全文件夹下的资料. ($secure_dir)
例 8-5. fetch 函数演示
{* include some javascript in your template *} {fetch file="/export/httpd/www.domain.com/docs/navbar.js"}
{* embed some weather text in your template from another web site *} {fetch file="http://www.myweather.com/68502/"}
{* fetch a news headline file via ftp *} {fetch file="ftp://user:[email protected]/path/to/currentheadlines.txt"}
{* assign the fetched contents to a template variable *} {fetch file="http://www.myweather.com/68502/" assign="weather"} {if $weather ne ""} {$weather} {/if} |
第七节 html_checkboxes
属性 |
类型 |
是否必须 |
缺省值 |
描述 |
name |
string |
No |
checkbox |
复选按钮组的名称 |
values |
array |
Yes, 或指定 options 属性 |
n/a |
包含复选按钮组值的数组 |
output |
array |
Yes, 或指定 options 属性 |
n/a |
包含复选按钮组显示值的数组 |
selected |
string/array |
No |
empty |
已选定的元素或元素数组 |
options |
associative array |
Yes,或指定 values 属性 |
n/a |
包含值和显示的关联数组 |
separator |
string |
No |
empty |
分隔每个复选按钮的字符串 |
labels |
boolean |
No |
true |
是否为每个复选按钮添加 |
自定义函数 html_checkboxes 根据给定的数据创建复选按钮组. 该函数可以指定哪些元素被选定. 要么必须指定 values 和 ouput 属性,要么指定 options 替代. 所有的输出与 XHTML 兼容.
上表未提到的其它参数在 标签中以"名称/属性"对的方式显示.
例 8-6. html_checkboxes 函数演示
index.php:
require('Smarty.class.php'); $smarty = new Smarty; $smarty->assign('cust_ids', array(1000,1001,1002,1003)); $smarty->assign('cust_names', array('Joe Schmoe','Jack Smith','Jane Johnson','Charlie Brown')); $smarty->assign('customer_id', 1001); $smarty->display('index.tpl');
index.tpl:
{html_checkboxes values=$cust_ids checked=$customer_id output=$cust_names separator="
index.php:
require('Smarty.class.php'); $smarty = new Smarty; $smarty->assign('cust_checkboxes', array( 1000 => 'Joe Schmoe', 1001 => 'Jack Smith', 1002 => 'Jane Johnson', 1003 => 'Charlie Brown')); $smarty->assign('customer_id', 1001); $smarty->display('index.tpl');
index.tpl:
{html_checkboxes name="id" options=$cust_checkboxes checked=$customer_id separator="
OUTPUT: (both examples)
|
第八节 html_image
属性 |
类型 |
是否必须 |
缺省值 |
描述 |
file |
string |
Yes |
n/a |
图象文件的名称或路径 |
border |
string |
No |
0 |
图象边框大小 |
height |
string |
No |
actual image height |
显示图象高度 |
width |
string |
No |
actual image width |
显示图象宽度 |
basedir |
string |
no |
web server doc root |
图象文件位置的相对路径 |
alt |
string |
no |
"" |
可选图象描述(鼠标指向图象或图象文件不存在时显示的字符串信息) |
href |
string |
no |
n/a |
图象链接到的地址 |
定义函数 html_image 产生一个图象的 HTML 标签. 如果没有提供高度和宽度值,将根据图象的实际大小自动取得.
basedir 是相对图象路径的基路径. 如果没有给出该属性,将依据WEB服务器的根路径(环境变量 DOCUMENT_ROOT)为准. 如果模板的安全设置打开了,图象的位置必须位于为安全文件夹下.
href是图象链接指向的位置. 如果设置了该属性,图象两侧将被加上超级链接标签,形成一个图象链接.
技术要点: html_image 需要访问磁盘以获取图象的尺寸. 如果不使用缓冲,为了优化性能,一般情况下建议使用静态图象标签而避免使用 html_iamge.
例 8-7. html_image 函数演示
index.php:
require('Smarty.class.php'); $smarty = new Smarty; $smarty->display('index.tpl');
index.tpl:
{html_image file="pumpkin.jpg"} {html_image file="/path/from/docroot/pumpkin.jpg"} {html_image file="../path/relative/to/currdir/pumpkin.jpg"}
OUTPUT: (possible)
|
第九节 html_options
属性 |
类型 |
是否必须 |
缺省值 |
描述 |
values |
array |
Yes, unless using options attribute |
n/a |
包含下拉列表各元素值的数组 |
output |
array |
Yes, unless using options attribute |
n/a |
包含下拉列表各元素显示值的数组 |
selected |
string/array |
No |
empty |
已选定的元素或元素数组 |
options |
associative array |
Yes, unless using values and output |
n/a |
包含值和显示的关联数组 |
name |
string |
No |
empty |
下拉菜单的名称 |
自定义函数 html_options 根据给定的数据创建选项组. 该函数可以指定哪些元素被选定. 要么必须指定 values 和 ouput 属性,要么指定 options 替代.
如果给定值是数组,将作为 OPTGROUP 处理,且支持递归. 所有的输出与 XHTML 兼容.
如果指定了可选属性 name,该选项列表将将被置于标签对中. 如果没有指定,那么只产生选项列表.
上表未提到的其它参数在
例 8-8. html_options 函数演示
index.php:
require('Smarty.class.php'); $smarty = new Smarty; $smarty->assign('cust_ids', array(1000,1001,1002,1003)); $smarty->assign('cust_names', array('Joe Schmoe','Jack Smith','Jane Johnson','Carlie Brown')); $smarty->assign('customer_id', 1001); $smarty->display('index.tpl');
index.tpl:
{html_options values=$cust_ids selected=$customer_id output=$cust_names}
index.php:
require('Smarty.class.php'); $smarty = new Smarty; $smarty->assign('cust_options', array( 1001 => 'Joe Schmoe', 1002 => 'Jack Smith', 1003 => 'Jane Johnson', 1004 => 'Charlie Brown')); $smarty->assign('customer_id', 1001); $smarty->display('index.tpl');
index.tpl:
{html_options options=$cust_options selected=$customer_id}
OUTPUT: (both examples)
|
第十节 html_radios
属性 |
类型 |
是否必须 |
缺省值 |
描述 |
name |
string |
No |
radio |
单选按钮列表的名称 |
values |
array |
Yes, 或指定 options 属性 |
n/a |
包含单选按钮值的数组 |
output |
array |
Yes, 或指定 options 属性 |
n/a |
包含单选按钮显示值的数组 |
checked |
string |
No |
empty |
已选定的元素 |
options |
associative array |
Yes, 或指定 values 属性 |
n/a |
包含值和显示的关联数组 |
separator |
string |
No |
empty |
分隔每个单选按钮的字符串 |
自定义函数 html_radios 根据给定的数据创建单选按钮组. 该函数可以指定哪个元素被选定. 要么必须指定 values 和 ouput 属性,要么指定 options 替代. 所有的输出与 XHTML 兼容.
上表未提到的其它参数在 标签中以"名称/属性"对的方式显示.
例 8-9. html_radios 函数演示
index.php:
require('Smarty.class.php'); $smarty = new Smarty; $smarty->assign('cust_ids', array(1000,1001,1002,1003)); $smarty->assign('cust_names', array('Joe Schmoe','Jack Smith','Jane Johnson','Carlie Brown')); $smarty->assign('customer_id', 1001); $smarty->display('index.tpl');
index.tpl:
{html_radios values=$cust_ids checked=$customer_id output=$cust_names separator="
index.php:
require('Smarty.class.php'); $smarty = new Smarty; $smarty->assign('cust_radios', array( 1001 => 'Joe Schmoe', 1002 => 'Jack Smith', 1003 => 'Jane Johnson', 1004 => 'Charlie Brown')); $smarty->assign('customer_id', 1001); $smarty->display('index.tpl');
index.tpl:
{html_radios name="id" options=$cust_radios checked=$customer_id separator="
OUTPUT: (both examples)
Joe Schmoe Jane Johnson Charlie Brown |
第十一节 html_select_date
属性 |
类型 |
是否必须 |
缺省值 |
描述 |
prefix |
string |
No |
Date_ |
变量名称前缀 |
time |
timestamp/YYYY-MM-DD |
No |
UNIX时间戳或年-月-日 |
使用时间类型(data/time) |
start_year |
string |
No |
年份或与当前年份的相对值 |
下拉列表中第一个年份,或与当前年份的相对值(正/负 几年) |
end_year |
string |
No |
同start_year |
下拉列表中最后一个年份,或与当前年份的相对值(正/负 几年) |
display_days |
boolean |
No |
true |
是否显示天 |
display_months |
boolean |
No |
true |
是否显示月 |
display_years |
boolean |
No |
true |
是否显示年 |
month_format |
string |
No |
%B |
月份的表示方法(strftime) |
day_format |
string |
No |
%02d |
天显示的格式(sprintf) |
day_value_format |
string |
No |
%d |
天的表示方法(sprintf) |
year_as_text |
boolean |
No |
false |
是否以文本方式显示年份 |
reverse_years |
boolean |
No |
false |
逆序显示年份 |
field_array |
string |
No |
null |
如果指定了名称,选定的区域将以[Day],[Year],[Month]的形式返回给PHP(待考) |
day_size |
string |
No |
null |
如果给定,为标签添加大小属性 |
month_size |
string |
No |
null |
如果给定,为标签添加大小属性 |
year_size |
string |
No |
null |
如果给定,为标签添加大小属性 |
all_extra |
string |
No |
null |
如果给定,为所有标签添加附加属性 |
day_extra |
string |
No |
null |
如果给定,为标签添加附加属性 |
month_extra |
string |
No |
null |
如果给定,为标签添加附加属性 |
year_extra |
string |
No |
null |
如果给定,为标签添加附加属性 |
field_order |
string |
No |
MDY |
显示区域的顺序 |
field_separator |
string |
No |
\n |
各区域间输出的分隔字符串 |
month_value_format |
string |
No |
%m |
月份值的strftime表示方法,默认为 %m |
自定义函数 html_select_date 用于创建日期下拉菜单. 它可以显示任意年月日.
例 8-10. html_select_date 函数演示
{html_select_date}
OUTPUT:
|
例 8-11. html_select_date 函数演示
{* start and end year can be relative to current year *} {html_select_date prefix="StartDate" time=$time start_year="-5" end_year="+1" display_days=false}
OUTPUT: (current year is 2000)
|
第十二节 html_select_time
属性 |
类型 |
是否必须 |
缺省值 |
描述 |
prefix |
string |
No |
Time_ |
变量名称前缀 |
time |
timestamp |
No |
UNIX时间戳或年-月-日 |
使用时间类型(data/time) |
display_hours |
boolean |
No |
true |
是否显示小时 |
display_minutes |
boolean |
No |
true |
是否显示分钟 |
display_seconds |
boolean |
No |
true |
是否显示秒 |
display_meridian |
boolean |
No |
true |
是否显示正午界(上午/下午) |
use_24_hours |
boolean |
No |
true |
是否使用24小时制 |
minute_interval |
integer |
No |
1 |
分钟下拉列表的间隔 |
second_interval |
integer |
No |
1 |
秒钟下拉列表的间隔 |
field_array |
string |
No |
n/a |
输出值到该值指定的数组 |
all_extra |
string |
No |
null |
如果给定,为标签添加附加属性 |
hour_extra |
string |
No |
null |
如果给定,为标签添加附加属性 |
minute_extra |
string |
No |
null |
如果给定,为标签添加附加属性 |
second_extra |
string |
No |
null |
如果给定,为标签添加附加属性 |
meridian_extra |
string |
No |
null |
如果给定,为标签添加附加属性 |
自定义函数 html_select_time 用于创建时间下拉菜单. 它可以显示任意时分秒.
例 8-12. html_select_time 函数演示
{html_select_time use_24_hours=true}
OUTPUT:
|
第十三节 html_table
属性 |
类型 |
是否必须 |
缺省值 |
描述 |
loop |
array |
Yes |
n/a |
待遍历的数组 |
cols |
integer |
No |
3 |
表格的列数目 |
table_attr |
string |
No |
border="1" |
表格的属性 |
tr_attr |
string |
No |
empty |
行标签属性(或轮转数组) |
td_attr |
string |
No |
empty |
列标签属性(或轮转数组) |
trailpad |
string |
No |
|
最后一行附加的数据(如果有的话) |
hdir |
string |
No |
right |
行的对齐方式,可能的值为 left 或 right |
vdir |
string |
No |
down |
列的对齐方式,可能的值为 up 或 down |
自定义函数 html_table 将数组中的数据填充到 HTML 表格中. cols 属性决定表格有多少列. table_attr , tr_attr 和 td_attr 属性决定表格中 tr 和 td 标签的一些附加属性. 如果 tr_attr 和 td_attr 属性值为数组,将轮流使用其中的值. 如果指定了 trailpad 属性,将在表尾最后一行附加一些数据.
例 8-13. html_table 函数演示
index.php:
require('Smarty.class.php'); $smarty = new Smarty; $smarty->assign('data',array(1,2,3,4,5,6,7,8,9)); $smarty->assign('tr',array('bgcolor="#eeeeee"','bgcolor="#dddddd"')); $smarty->display('index.tpl');
index.tpl:
{html_table loop=$data} {html_table loop=$data cols=4 table_attr='border="0"'} {html_table loop=$data cols=4 tr_attr=$tr}
OUTPUT:
|
第十四节 math
属性 |
类型 |
是否必须 |
缺省值 |
描述 |
equation |
string |
Yes |
n/a |
待执行的表达式 |
format |
string |
No |
n/a |
结果的格式(遵从sprintf函数) |
var |
numeric |
Yes |
n/a |
表达式变量值 |
assign |
string |
No |
n/a |
输出值将被赋给模板变量的名称 |
[var ...] |
numeric |
Yes |
n/a |
表达式变量值 |
math 允许模板设计者在模板中进行数学表达式运算. 均表达式中可以使用任何数值类型的变量,结果在 math 标签的位置输出. 表达式中使用的变量被当做参数传递给函数,可以是模板变量或静态值. 目前可以使用的运算符有:+, -, /, *, abs, ceil, cos, exp, floor, log, log10, max, min, pi, pow, rand, round, sin, sqrt, srans 和 tan .关于数学函数的详细信息,请查看 PHP 文档.
如果指定了 "assign" 这个特殊属性,该函数的输出值将被赋给由 assign 指定的模板变量,而不是直接输出.
技术要点: 由于使用了 php 的 eval() 函数,math 函数的执行效率不高. 在 PHP 中做数学运算效率会更高一些,因此要尽可能在 PHP 中做数学运算,将结果赋给模板变量. 类似在 section 循环,应明确避免反复调用 math 函数.
例 8-14. math 函数演示
{* $height=4, $width=5 *}
{math equation="x + y" x=$height y=$width}
OUTPUT:
9
{* $row_height = 10, $row_width = 20, #col_div# = 2, assigned in template *}
{math equation="height * width / division" height=$row_height width=$row_width division=#col_div#}
OUTPUT:
100
{* you can use parenthesis *}
{math equation="(( x + y ) / z )" x=2 y=10 z=2}
OUTPUT:
6
{* you can supply a format parameter in sprintf format *}
{math equation="x + y" x=4.4444 y=5.0000 format="%.2f"}
OUTPUT:
9.44 |
第十五节 mailto
属性 |
类型 |
是否必须 |
缺省值 |
描述 |
address |
string |
Yes |
n/a |
电子邮件地址 |
text |
string |
No |
n/a |
邮件链接上显示的文本,默认为电子邮件地址 |
encode |
string |
No |
none |
编码方式,可选值为 none,hex或javascript |
cc |
string |
No |
n/a |
邮件抄送地址,多条地址信息以逗号分隔 |
bcc |
string |
No |
n/a |
邮件暗送地址,多条地址信息以逗号分隔 |
subject |
string |
No |
n/a |
邮件主题 |
newsgroups |
string |
No |
n/a |
发送到新闻组的地址,多条地址信息以逗号分隔 |
followupto |
string |
No |
n/a |
追踪地址信息,多条信息以逗号分隔 |
extra |
string |
No |
n/a |
其它需要传递给链接的信息,如css样式 |
mailto 自动生成电子邮件链接,并根据选项决定是否对地址信息编码. 电子邮件地址编码使得网络嗅探程序难以收集到电子邮件地址信息.
技术要点: 尽管可以使用 hex 进制编码,但 javascript 已经算得上是很彻底的编码形式了.
例 8-15. mailto 函数演示
{mailto address="[email protected]"} {mailto address="[email protected]" text="send me some mail"} {mailto address="[email protected]" encode="javascript"} {mailto address="[email protected]" encode="hex"} {mailto address="[email protected]" subject="Hello to you!"} {mailto address="[email protected]" cc="[email protected],[email protected]"} {mailto address="[email protected]" extra='class="email"'}
OUTPUT:
#x6f;main.com |
第十六节 popup_init
popup 函数整合了 overLib(用于弹出窗口的函数库) 库. 这些函数用于上下文敏感信息如帮助窗口或工具提示. 如果准备使用 popup 函数,在页首必须先调用 popup_init 函数. overLib 由 Erik Bosrup 开发,其主页位于http://www.bosrup.com/web/overlib/.
在 Smarty 2.1.2 版中没有带 overLib 库. 必须下载该库,将 overlib.js 文件置于文档根目录下,调用 popup_init 的时候将该文件的相对路径作为参数"src"传递.
例 8-16. popup_init 函数演示
{* popup_init must be called once at the top of the page *} {popup_init src="/javascripts/overlib.js"} |
第十七节 popup
属性 |
类型 |
是否必须 |
缺省值 |
描述 |
text |
string |
Yes |
n/a |
弹出窗口中要显示的内容,文本或超文本 |
trigger |
string |
No |
onMouseOver |
触发弹出窗口的条件,可选择onMouseOver(鼠标经过)或onClick(鼠标单击) |
sticky |
boolean |
No |
false |
弹出窗口始终显示,直到关闭 |
caption |
string |
No |
n/a |
标题文本内容 |
fgcolor |
string |
No |
n/a |
弹出窗口内部颜色 |
bgcolor |
string |
No |
n/a |
弹出窗口边框颜色 |
textcolor |
string |
No |
n/a |
弹出窗口内部文字颜色 |
capcolor |
string |
No |
n/a |
弹出窗口标题颜色 |
closecolor |
string |
No |
n/a |
设置"关闭"文本信息的颜色 |
textfont |
string |
No |
n/a |
设置内容文本使用的字体类型 |
captionfont |
string |
No |
n/a |
设置标题文本的字体 |
closefont |
string |
No |
n/a |
设置"关闭"文本信息的字体类型 |
textsize |
string |
No |
n/a |
设置内容文本使用的字体大小 |
captionsize |
string |
No |
n/a |
设置标题文本使用的字体大小 |
closesize |
string |
No |
n/a |
设置"关闭"文本信息的字体大小 |
width |
integer |
No |
n/a |
sets the width of the box设置宽度 |
height |
integer |
No |
n/a |
sets the height of the box设置高度 |
left |
boolean |
No |
false |
使弹出窗口位于鼠标左侧 |
right |
boolean |
No |
false |
使弹出窗口位于鼠标右侧 |
center |
boolean |
No |
false |
使弹出窗口的中间位置和鼠标位置重合 |
above |
boolean |
No |
false |
使弹出窗口位于鼠标上侧. 注: 仅在设置了height属性时有效 |
below |
boolean |
No |
false |
使弹出窗口位于鼠标下侧 |
border |
integer |
No |
n/a |
决定弹出窗口的边框厚度 |
offsetx |
integer |
No |
n/a |
横向显示位置偏移量 |
offsety |
integer |
No |
n/a |
纵向显示位置偏移量 |
fgbackground |
url to image |
No |
n/a |
使用背景图片代替背景颜色 |
bgbackground |
url to image |
No |
n/a |
使用背景图片代替边框颜色. 注1: 必须设置bgcolor为"",边框颜色才不会显示. 注2: 当有关闭链接时,Netscape会重新渲染表格,看起来可能会有点问题. |
closetext |
string |
No |
n/a |
自定义关闭链接显示文本 |
noclose |
boolean |
No |
n/a |
不显示关闭链接 |
status |
string |
No |
n/a |
设置状态栏显示的文本 |
autostatus |
boolean |
No |
n/a |
设置弹出窗口状态栏显示的文本为当前窗口状态栏显示的文本. 注: 该设置将覆盖status的设置 |
autostatuscap |
string |
No |
n/a |
设置状态栏显示的文本为标题栏显示的信息. 注: 该设置将覆盖status和autostatus设置 |
inarray |
integer |
No |
n/a |
该属性告诉overLib在ol_text数组中读该属性指定的索引的元素到text中. 该属性可以代替text属性 |
caparray |
integer |
No |
n/a |
该属性告诉overLib在ol_caps数组中读该属性指定的索引的元素到caption中. |
capicon |
url |
No |
n/a |
弹出前先显示该图象 |
snapx |
integer |
No |
n/a |
横向将弹出窗口附着于指定位置 |
snapy |
integer |
No |
n/a |
纵向将弹出窗口附着于指定位置 |
fixx |
integer |
No |
n/a |
锁定弹出窗口的横向位置. 注: 该设置将覆盖其它横向设置 |
fixy |
integer |
No |
n/a |
锁定弹出窗口的纵向位置. 注: 该设置将覆盖其它纵向设置 |
background |
url |
No |
n/a |
设置图象作为输出表格区块的背景 |
padx |
integer,integer |
No |
n/a |
在背景图象后附加横向空白. 注: 该属性有两个参数 |
pady |
integer,integer |
No |
n/a |
在背景图象后附加纵向空白. 注: 该属性有两个参数 |
fullhtml |
boolean |
No |
n/a |
允许用户完全控制背景图片上的HTML. HTML代码位于"text"属性中 |
frame |
string |
No |
n/a |
控制弹出窗口在不同的框架中. 关于此函数更多详细信息,请查阅overlib文档. |
timeout |
string |
No |
n/a |
调用特定javascript脚本函数,将返回值显示在弹出窗口中. |
delay |
integer |
No |
n/a |
使得弹出窗口像一个工具提示,窗口将显示到该属性指定的时间(毫秒) |
hauto |
boolean |
No |
n/a |
自动决定弹出窗口位于鼠标的左侧或右侧. |
vauto |
boolean |
No |
n/a |
自动决定弹出窗口位于鼠标的上侧或下侧. |
popup 用于创建javascript弹出窗口.
例 8-17. popup 函数演示
{* popup_init must be called once at the top of the page *} {popup_init src="/javascripts/overlib.js"}
{* create a link with a popup window when you move your mouse over *}
{* you can use html, links, etc in your popup text *} |
第十八 textformat
属性 |
类型 |
是否必须 |
缺省值 |
描述 |
style |
string |
No |
n/a |
预处理风格 |
indent |
number |
No |
0 |
单行缩进的字符数目 |
indent_first |
number |
No |
0 |
首行缩进的字符数目 |
indent_char |
string |
No |
(single space) |
填充缩进区域的字符(或字符串) |
wrap |
number |
No |
80 |
单行长度,超过该长度自动折行 |
wrap_char |
string |
No |
\n |
折行使用的字符(或字符串),被附加在行尾 |
wrap_cut |
boolean |
No |
false |
如果设置为真,换行时不考虑换行点所在位置是否为完整单词,直接换行. 反之将在单词的边界处换行. |
assign |
string |
No |
n/a |
输出值将被赋给模板变量的名称 |
textformat 用于格式化文本. 该函数主要清理空格和特殊字符,对段落按单词边界换行和行缩进等段落格式化处理.
用户可以明确设置各参数,或使用预处理风格. 目前只有唯一可用风格"email".
例 8-18. textformat 函数演示
{textformat wrap=40}
This is foo. This is foo. This is foo. This is foo. This is foo. This is foo.
This is bar.
bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo.
{/textformat}
OUTPUT:
This is foo. This is foo. This is foo. This is foo. This is foo. This is foo.
This is bar.
bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo.
{textformat wrap=40 indent=4}
This is foo. This is foo. This is foo. This is foo. This is foo. This is foo.
This is bar.
bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo.
{/textformat}
OUTPUT:
This is foo. This is foo. This is foo. This is foo. This is foo. This is foo.
This is bar.
bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo.
{textformat wrap=40 indent=4 indent_first=4}
This is foo. This is foo. This is foo. This is foo. This is foo. This is foo.
This is bar.
bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo.
{/textformat}
OUTPUT:
This is foo. This is foo. This is foo. This is foo. This is foo. This is foo.
This is bar.
bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo.
{textformat style="email"}
This is foo. This is foo. This is foo. This is foo. This is foo. This is foo.
This is bar.
bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo.
{/textformat}
OUTPUT:
This is foo. This is foo. This is foo. This is foo. This is foo. This is foo.
This is bar.
bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. bar foo bar foo foo. |
配置文件有利于设计者管理文件中的模板全局变量。最简单的例子就是模板色彩变量。一般情况下你如果想改变一个程序的外观色彩,你就必须通过去更改每一个文件的颜色变量。如果有这个配置文件的话,色彩变量就可以保存在一个地方,只要改变这个配置文件就可以实现你色彩的更新。
例 9-1 配置文件语法例子
# global variables pageTitle = "Main Menu" bodyBgColor = #000000 tableBgColor = #000000 rowBgColor = #00ff00
[Customer] pageTitle = "Customer Info"
[Login] pageTitle = "Login" focus = "username" Intro = """This is a value that spans more than one line. you must enclose it in triple quotes."""
# hidden section [.Database] host=my.domain.com db=ADDRESSBOOK user=php-user pass=foobar |
配置文件变量值能够在引号中使用,但是没有必要。你可以用单引号或者双引号。如果你有一个不只在一个区域内使用的变量值,你可以使用三引号(""")将它完整的封状起来,可以把它们放金配置文件,只要没有语法错误。我们建议在程序行前使用 “#”加一些注释信息来标示。
上面关于配置文件的例子共有两个部分。每部分的名称都是用一个“[]”给括起来。每部分的名称命名规则就是任意的字符串,只要不包括有符号“[”或者“]”。例子开头的四个变量都是全局变量,也就是说不仅仅是可以在一个区域内使用。这些变量总是从配置文件中载入。如果某个特定的局部变量已经载入,这样全局变量和局部变量都还可以载入。如果当某个变量名既是全局变量又是局部变量时,局部变量将被优先赋予值来使用。如果在一个局部中两个变量名相同的话,最后一个将被赋值使用。
配置文件是通过内建函数载入到模板 { config load }
你可以在某个段时期通过预先想好的变量名或者局部名隐藏变量或者完整的一个节。当你的应用程序读取配置文件和取得有用数据而不用读取模板时这个非常有用,如果你有第三方来做模板编辑的话,可以肯定的说它们不能通过载入配置文件到模板而读取到任何有用的数据。
SMARTY里面包括有一个调式控制台。它可以告诉你模板里面包含的所有内容,同时也可以为当前使用模板中的变量和配置文件变量赋值。一个叫 debug.tpl 的模板包含了很多控制调式控制台格式化的SMARTY类,在SMARTY中把变量 $debugging 设置为 true ,如果需要的话设置变量 $debug_tpl 为模板源文件路径(在SMARTY_DIR用已经自定义)。当你载入页面时,有一个JAVASCRIPT控制台窗口将弹出且告诉你所有模板中包含的名称和当前页已经赋值的变量。如果要了解某个模板的详细变量,可以去看 {debug} 模板定义函数章节。如果要关闭掉调试控制台,设置变量 $debugging 为 false 就可以了。如果你开启了 $debugging ctrl 选项,也可以通过放置 SMARTY_DEBUG 在 URL 来临时打开调试控制台。
技术提示:当你使用函数 fetch() API 时调试控制台不能用,在使用 display() 时才可以使用。它将自动地把 javascript 添加到已经应用模板的每一个按扭中。如果你不喜欢 javascript ,你可以编辑文件 debug.tpl 模板,格式化输出为你自己喜欢的格式。调试数据是没有被缓存的,并且 debug.tpl 信息也没有包含在调试控制台的输出文件中。
注意:每个模板和配置文件的载入都是以秒来计算的,甚至是以几分之一秒。
SMARTY_DIR:Smarty目录
定位Smarty类文件的完整系统路径,如果没有定义Smarty目录,Smarty将会试着自动创建合适的值。如果定义了,路径必须要以斜线结束。
Example 11-1. SMARTY_DIR
// set path to Smarty directory define("SMARTY_DIR","/usr/local/lib/php/Smarty/");
require_once(SMARTY_DIR."Smarty.class.php"); |
第一节 $template_dir模板目录变量
该变量定义默认模板目录的名字。当包含文件时,如果不提供一个源类型(即源地址),那么将会到模板目录中寻找。默认情况下,目录是:“./templates”,也就是说他将会在和php执行脚本相同的目录下寻找模板目录。
技巧注意:不推荐把模板目录放在web服务器根目录下。
第二节 $compile_dir编译目录变量
该变量定位编译模板的目录名字。默认情况下,目录是:“./templates_c”,也就是说他将会在和php执行脚本相同的目录下寻找编译目录。
技巧:该设置必须是一个相对或绝对路径。包含路径不用于写文件。
技巧:不推荐把编译目录放在web服务器根目录下。
第三节 $config_dir配置目录变量
该变量定义用于存放模板配置文件的目录,默认情况下,目录是:“./configs”,也就是说他将会在和php执行脚本相同的目录下寻找配置目录。
技巧:不推荐把编译目录放在web服务器根目录下。
第四节 $plugins_dir插件目录变量
该变量定义Smarty寻找所需插件的目录。默认是在SMARTY目录下的“plugins”目录。如果提供了一个相对路径,Smarty将首先在SMARTY目录下寻找,然后到当前工作目录下寻找,继而到php包含路径中的每个路径中寻找。
技巧:为了获取最好性能,不要将插件目录安装成必须使用php包含路径的境地。最好用一个绝对路径名字,或者是一个相对SMARTY目录或当前工作目录的路径。
第五节 $debugging调试变量
它能启动调试控制台。该控制台是一个javascript窗口,该窗口告诉你被包含的模板和应用于当前模板页面的变量。
第六节 $debug_tpl调试模板
该变量定义用于调试控制台的模板文件名字。默认情况下,其名字为:debug.tpl,位于Smarty目录中。
第七节 $debugging_ctrl调试控制变量
该变量作用是允许以交替的方式启动调试设置。NONE表示不允许交替方式。URL表示当关键词SMARTY_DEBUG出现在QUERY_STRING(查询字符串)中时,针对此脚本的调用,调试被启动。如果$debugging变量是真,则忽略其调试控制变量值。
第八节 $global_assign全局配置变量
定义一组总是隐式地作用于模板引擎的变量列表。这对于使全局变量或服务器变量可用于所有模板是很方便的,因为无需手工配置它们。在全局配置中的每一元素应当要么是一全局变量的名字,要么是一键/值对(键是全局数组名,值是对应该全局数组的变量数组)。$SCRIPT_NAME变量默认属于$HTTP_SERVER_VARS数组。
技巧:服务器变量可以通过$smarty变量获得,如{$smarty.server.SCRIPT_NAME}。参看$smarty变量一节。
第九节 $undefined未定义变量
该变量为Smarty设定没有得到定义的变量的值,默认为空.当前仅用来设定全局配置中的未定义变量为一个默认值.
第十节 $autoload_filters自动加载过滤器变量
如果你希望在每次模板调用过程中加载过滤器,你可以指定他们使用此变量,Smarty将自动为你加载它们.该变量是一个联合数组,在数组中键是过滤器类型,值是过滤器名字所组成的数组.例如:
$smarty->autoload_filters = array('pre' => array('trim', 'stamp'),
'output' => array('convert'));
第十一节 $compile_check编译检查变量
每次调用PHP应用程序,Smarty 会试着查看自上次编译时间以来,当前模板是否被修改过.如果修改过了,她会重新编译那个模板.如果模板还没有被编译过,她将编译模板而不管编译检查如何设置.默认情况下编译检查这个变量设置为true.一旦一个应用程序投入产品中(模板将不会修改了),就不再需要编译检查这一步了.为了最大性能,确定将$compile_check设为"false".注意:如果设为了"false",虽然模板文件被修改,但你不会看到修改结果,因为模板没有得到重新编译.如果启动了缓存和编译检查,一旦有关模板文件或配置文件被更新,缓存文件将会重建.
第十二节 $force_compile强迫编译变量
强迫Smarty每次调用(重新)编译模板时.这项设置不受$compile_check的限制.默认情况下,它是无效的.它对于开发和调试很方便.但它决不能使用于产品环境下.如果启动了缓存,每次将会重新生成缓存文件.
第十节 $caching缓存变量
告诉Smarty是否缓存模板的输出.默认情况下,她设为0,或无效.如果模板产生冗余内容,建议打开缓存.这样有利于获得良好的性能增益.你也可以为同一模板设有多个缓存.当值为1或2时启动缓存.1告诉Smarty 使用当前的$cache_lifetime变量判断缓存是否过期.2告诉 Smarty 使用生成缓存时的cache_lifetime值.用这种方式你正好可以在获取模板之前设置缓存生存时间,以便较精确地控制缓存何时失效.
如果启动了编译检查,一旦任何的模板文件或配置文件(有关缓存部分的配置文件)被修改,缓存的内容将会重新生成.如果启动了强迫编译,缓存的内容将总会重新生成.
第十一节 $cache_dir缓存目录变量
这是存放模板缓存的目录名.默认情况下,它是:"./cache",也就是说你可以在和php执行脚本相同目录下寻找缓存目录.你也可以用你自己的自定义缓存处理函数来控制缓存文件,它将会忽略这项设置.
技巧:这项设置必须是一个相对或绝对路径.包含路径不用于写文件.
技巧:不推荐将此目录放在web服务器根目录下.
第十二节 $cache_lifetime缓存生存时间变量
该变量定义模板缓存有效时间段的长度(单位秒),一旦这个时间失效,则缓存将会重新生成.如果要想实现所有效果,$caching必须因$cache_lifetime需要而设为"true".值为-1时,将强迫缓存永不过期.0值将导致缓存总是重新生成(仅有利于测试,一个更有效的使缓存无效的方法是设置$caching = false.)
如果启动了强迫编译,则缓存文件每次将会重新生成.要想有效地停止缓存,你可以利用clear_all_cache() 函数清除所有的缓存文件,或者利用clear_cache() 函数清除个别文件(或文件组).
技巧:如果你想给某些模板设定它们自己的缓存生存时间,你可以在调用display()或fetch()函数之前,通过设置$caching = 2,然后设置$cache_lifetime为一个唯一值来实现.
第十三节 $cache_handler_func缓存处理函数变量
你可以提供一个自定义函数来处理缓存文件,而不是通过变量$cache_dir使用内置方法.祥见:cache handler function section
第十四节 $cache_modified_check缓存修改检查变量
如果设置该变量为真,Smarty将分析客户端发送来的If-Modified-Since头信息.如果缓存文件时间戳自上次访问以来没有改变,则发送一个"304 Not Modified"头,而不是缓存文件内容.这种方式仅工作于没有 {insert} 标记的缓存内容.
第十五节 $config_overwrite配置覆盖变量
如果设该变量为真,则从配置文件中读取出来的变量将会互相覆盖.否则,变量将会放到一个数组中.如果你想把配置文件中的数据存储到数组里,这种方式是很有用的,仅仅列出每个元素多次就可以了.默认情况下,设为真.
第十六节 $config_booleanize配置布尔化变量
如果该变量设为真,配置文件中的on/true/yes 和 off/false/no值会自动转化为布尔值.这样的话,你就可以在模板中像{if #foobar#} ... {/if}这样使用这些值了.如果foobar为on, true 或 yes,那么 {if}语句就会执行了.默认情况下,该变量值为真.
第十七节 $config_read_hidden配置读取隐藏变量
如果设为真,在配置文件中的隐藏节块(******不会翻译啦)可以从模版中读取出来.典型的你会设为假,这样你可以在配置文件里存放敏感数据,例如数据库参数,而不用担心模版会调用他们.默认情况下,该变量设为假.
第十八节 $config_fix_newlines配置固定换行符变量
如果该变量设为真,那么在配置文件中的mac 和 dos 换行符(\r and \r\n)在语法解析时将会转换为\n. 默认情况下,该变量为真.
第十九节 $default_template_handler_func默认模板处理函数变量
该函数在模板不能从它的源目录下获取时会得到调用.
第二十节 $php_handling php处理变量
该变量告诉Smarty怎样处理嵌入到模版中的php代码.有四种可能的设置,默认为SMARTY_PHP_PASSTHRU.注意:改变量的设置不会影响模板里面{php}{/php}标记中的php代码.
· 原样输出标记.
· 作为html实体引用标记
· 从模板中移出标记.
· 将作为php代码执行标记.
极度不赞成将php代码嵌入到模板中.
第二十一节 $security安全变量
安全变量要么是真,要么是假.默认为假.当你不信任模板中的可编辑部分(例如通过ftp方式上传编辑的),并想通过模板语言减小系统非安全的风险时,安全变量设为真比较适合.设为真会将下面的规则强加于模板语言中,除非特别地用$security_settings覆盖.
· 如果变量$php_handling设为了SMARTY_PHP_ALLOW,则会隐式地被修改成SMARTY_PHP_PASSTHRU
· PHP函数在IF语句中是不允许的,除了在$security_settings中另行指出.
· 模板仅可以包含于$secure_dir数组列出的目录中.
· 本地文件仅可以用{fetch}获取于$secure_dir数组列出的目录中.
· 不允许有{php}{/php}标记.
· PHP函数不允许作为修正器,除了在$security_settings中指出.
第十二节 $secure_dir安全目录变量
这是一个与安全有关的本地目录数组变量.当启动安全变量时{include} 和 {fetch}会用到此数组变量.
第十三节 $security_settings安全配置变量
用于当启动安全变量时覆盖或另行指定安全配置.有以下几种可能的配置:
· PHP_HANDLING - 真或假.如果真,则不检查$php_handling的配置.
· IF_FUNCS - 这是一个可允许包含在if语句中的php函数名数组.
· INCLUDE_ANY - 真或假.如果真,可以从文件系统中包含任何模板,而不管$secure_dir目录设置如何.
· PHP_TAGS - 真或假.如果真,{php}{/php}允许在模板中存在.
· MODIFIER_FUNCS - 这是一个可用作修正器的php函数名数组.
·
第十四节 $trusted_dir信任目录变量
信任目录变量仅用在$security启动之后.这是一个所有建立信任的目录数组变量.你可以将php脚本放到这些信任目录中,这些脚本会直接在模板里以{include_php}标记得到执行.
第十五节 $left_delimiter左结束符变量
用于模板语言中,默认是"{".
第十六节 $right_delimiter右结束符变量
用于模板语言中,默认是"}".
第十七节 $compiler_class编译类变量
定Smarty用来编译模板的编译类名.默认为:'Smarty_Compiler'.仅适合于高级用户.
第十八节 $request_vars_order变量顺序变量
请求变量的顺序在这里配置,类似于php.ini中的变量顺序.
第十九节 $compile_id编译id变量
永久的编译鉴别号.作为一个可选办法将相同的编译号传递给每个函数调用,你可以设置这个编译id,随后此id将会被隐含地使用.
第二十节 $use_sub_dirs子目录变量
如果你的php环境不允许Smarty创建子目录,则设此变量为假.子目录非常有用,所以尽可能的使用他们.
第二十一节 $default_modifiers 默认修正器变量
这是一个修正器数组变量,这些修正器隐式地作用于模板中的每个变量.例如:针对HTML,用数组('escape:"htmlall"')默认地忽略每个变量;为了使一个变量免除于默认修正器,请将参数为"nodefaults"的特殊"smarty"修正器作用于它,例如:{$var|smarty:nodefaults}.
第二十二节 $default_resource_type默认源类型变量
变量告诉smarty隐式地使用什么源类型.默认值为'file',也就是说,$smarty->display('index.tpl');和and $smarty->display('file:index.tpl');从意思上是一样的.祥
见resource一章。
第一节 append 添加
添加指定的元素到数组中。如果是添加一个字符串,该字符串会被转换为数组格式后再进行添加。所添加的数据可以采用名称, 数值的格式,或者是使用 “=>”连接的联合数组格式。如果第三个可选参数被指定为 TRUE,所添加的数据会和数组中现有数据进行合并,而不是直接添加。
注意:使用第三个参数“merge”时要考虑到数组的索引,所以,如果添加和被添加的数组都是以数字为索引,他们会互相覆盖,或者产生不连续的索引。这并不象PHP中的array_merge()函数,后者会删除原有的数字索引,重新对索引进行编号。
Example 13-1. append 例子 13-1. 添加
// passing name/value pairs 以 名称,数值 的方式添加
|
第二节 append_by_ref 引用添加
本函数用于采用引用的方式把变量的值添加到原有值之后。如果采用引用的方式添加了一个变量,那么当这个变量的值改变时,被添加的值也随之改变。对于对象,append_by_ref()函数也能够避免对于被添加对象的内存拷贝。关于变量引用的进一步解释可以查看PHP手册。如果第三个可选参数设置为 true,数值将会和现有数组合并,而不是添加在数组后面。
注意:使用第三个参数“merge”时要考虑到数组的索引,所以,如果添加和被添加的数组都是以数字为索引,他们会互相覆盖,或者产生不连续的索引。这并不象PHP中的array_merge()函数,后者会删除原有的数字索引,重新对索引进行编号。
例子 13-2. 引用添加
// appending name/value pairs |
第三节 assign赋值
用来赋值到模板中。可以指定一对 名称/数值 ,也可以指定包含 名称/数值 的联合数组。
例子 13-3. 赋值
// passing name/value pairs 名称/数值 方式
|
第四节 assign_by_ref引用赋值
采用引用的方式赋值到模板中,而不是在模板中创建一个数值的副本。引用的概念可以查看PHP手册的变量引用部分。
注意:本函数用于采用引用的方式赋值到模板中。如果把一个变量采用引用的方式赋值后,变量的值又被改变了,那么在模板中将会看到变量改变后的值。对于对象,assign_by_ref()函数也避免了对象的内存拷贝。进一步的解释可以查看PHP手册的变量引用部分。
第五节 clear_all_assign清除所有赋值
清除所有已赋值到模板中的值。
例子 13-5. 清除所有赋值
// clear all assigned variables |
第六节 clear_all_cache清除所有缓存
清除所有模板缓存。作为可选参数“expire time”,你可以指定一个以秒为单位的最小时间,超过这个时间的缓存都将被清除掉。
例子 13-6. 清除所有缓存
// clear the entire cache |
第七节 clear_assign清除赋值
清除指定模板变量的值。可以指定单独的一个变量名称,或者是一个数组。
例子 13-7. 清除赋值
// clear a single variable
|
第八节 clear_cache清除缓存
清除指定模板的缓存。如果这个模板有多个缓存,你可以用第二个参数指定要清除缓存的缓存号,还可以通过第三个参数指定编译号。你可以把模板分组,以便可以方便的清除一组缓存。更多的信息可以查看缓存部分。第四个参数是可选的,用来指定超过某一时间(以秒为单位)的缓存才会被清除。
例子 13-8. 清除缓存
// clear the cache for a template
|
第九节 clear_compiled_tpl清除已编译模板
清除指定模板资源的编译版本,如果不指定则清除所有已编译模板。除非特殊的需要,一般情况下不需要使用该函数。
(Fwolf:这个函数并不会删除模板本身,而是删除templates_c目录中存放的编译后生成的文件,这些编译后的文件会在下一次页面调用的时候再一次被生成。)
例子 13-9. 清除已编译模板
// clear a specific template resource
|
第十节 clear_config清除配置
清除所有配置变量,如果指定了变量名称,则只清除所指定的配置变量。
例子 13-10. 清除配置
// clear all assigned config variables.
|
第十一节 config_load加载配置
加载配置文件,并将其中的数据传送到模板中,它的功能和config_load函数是一样的。
注意:到Smarty 2.4.0为止,已赋值的模板变量对于fetch()和display()方法是共享调用的,而使用config_load()加载的变量是全局的。并且在编译时配置文件也将被编译,以加快执行速度,并且遵守force_compile和compile_check设置。
例子 13-11. 加载配置
// load config variables and assign them
|
第十二节 display显示
显示模板,需要指定一个合法的模板资源的类型和路径。你还可以通过第二个可选参数指定一个缓存号,相关的信息可以查看缓存。
通过第三个可选参数,可以指定一个编译号。这在你想把一个模板编译成不同版本时使用,比如针对不同的语言编译模板。编译号的另外一个作用是,如果你有多个$template_dir模板目录,但只有一个$compile_dir编译后存档目录,这时可以为每一个$template_dir模板目录指定一个编译号,以避免相同的模板文件在编译后会互相覆盖。相对于在每一次调用display()的时候都指定编译号,也可以通过设置$compile_id编译号属性来一次性设定。
例子 13-12. 显示
include("Smarty.class.php");
|
通过模板资源的语法来使用不在$template_dir模板目录下的文件。
例子 13-13. 显示模板资源
// absolute filepath
|
第十三节 fetch取得输出的内容
返回一个模板输出的内容(HTML代码),而不是直接显示出来,需要指定一个合法的模板资源的类型和路径。你还可以通过第二个可选参数指定一个缓存号,相关的信息可以查看缓存。
通过第三个可选参数,可以指定一个编译号。这在你想把一个模板编译成不同版本时使用,比如针对不同的语言编译模板。编译号的另外一个作用是,如果你有多个$template_dir模板目录,但只有一个$compile_dir编译后存档目录,这时可以为每一个$template_dir模板目录指定一个编译号,以避免相同的模板文件在编译后会互相覆盖。相对于在每一次调用display()的时候都指定编译号,也可以通过设置$compile_id编译号属性来一次性设定。
例子 13-14. 取得输出的内容
include("Smarty.class.php");
|
第十四节 get_config_vars取配置变量的值
返回指定配置变量的值。如果不指定变量名称,则会返回一个包含所有已加载配置变量的值的数组。
例子 13-15. 取配置变量的值
// get loaded config template var 'foo'
|
第十五节 get_registered_object取得已注册的对象
返回一个已注册对象的引用。用于在一个自定义函数里直接调用已注册的对象。
例子 13-16. 取得已注册的对象
function smarty_block_foo($params, &$smarty) { |
第十六节 get_template_vars取得模板变量的值
返回一个指定的已赋值的模板变量的值。如果不指定参数,则返回一个包含所有已赋值模板变量的值的数组
例子 13-17. 取得模板变量的值
// get assigned template var 'foo'
|
第十七节 is_cached是否已被缓存
在指定模板的缓存存在是返回真。只有在缓存设置为真时才可用。
例子 13-18. 是否已被缓存
$smarty->caching = true;
|
如果模板有多个缓存的话,可以通过第二个可选参数指定缓存号。
例子 13-19. 多缓存模板的判断
$smarty->caching = true;
|
第十八节 load_filter加载过滤器
这个函数用来加载过滤器插件。第一个参数指定过滤器的类型,只能是下列之一:“pre”,“post”,或者是“output”。第二个参数指定过滤器插件的名称,比如“trim”。
例子 13-20. 加载过滤器插件
$smarty->load_filter('pre', 'trim'); // load prefilter named 'trim' |
第十九节 register_block注册一个块
用来动态注册/定义块函数插件。前两个参数指定块函数名称和执行函数的名称。
执行函数的格式可以是一个包含函数名称的字符串;也可以是一个array(&$object, $method)数组形式,其中&$object是一个对象的引用,而$method是它的一个方法;还可以是一个array(&$ class, $method)数组形式,其中$class是一个类的名称,$method是类中的一个方法。
$cacheable 和 $cache_attrs 参数在大多数情况下可以省略。它们的使用方法可以查看控制插件输出的缓存。
例子 13-21. 注册一个块
/* PHP */
|
第二十节 register_compiler_function注册编译函数
动态注册一个编译函数插件,前两个参数是编译函数的名称、执行函数的名称。
执行函数的格式可以是一个包含函数名称的字符串;也可以是一个array(&$object, $method)数组形式,其中&$object是一个对象的引用,而$method是它的一个方法;还可以是一个array(&$ class, $method)数组形式,其中$class是一个类的名称,$method是类中的一个方法。
$cacheable 参数在大多数情况下可以省略。具体的使用方法可以查看控制插件输出的缓存。
第二十一节 register_function注册函数
动态注册模板函数插件,前两个参数是模板函数名称和执行函数名称。
执行函数的格式可以是一个包含函数名称的字符串;也可以是一个array(&$object, $method)数组形式,其中&$object是一个对象的引用,而$method是它的一个方法;还可以是一个array(&$ class, $method)数组形式,其中$class是一个类的名称,$method是类中的一个方法。
$cacheable 和 $cache_attrs 参数在大多数情况下可以省略。它们的使用方法可以查看控制插件输出的缓存。
例子 13-22. 注册函数
$smarty->register_function("date_now", "print_current_date");
|
第二十二节 register_modifier注册修饰器
动态注册一个修饰器插件,需要制定模板修饰器的名称,和实现具体功能的函数。
执行函数的格式可以是一个包含函数名称的字符串;也可以是一个array(&$object, $method)数组形式,其中&$object是一个对象的引用,而$method是它的一个方法;还可以是一个array(&$ class, $method)数组形式,其中$class是一个类的名称,$method是类中的一个方法。
例子 13-23. 注册修饰器
// let's map PHP's stripslashes function to a Smarty modifier.
|
第二十三节 register_object注册对象
注册一个在模板中使用的对象,相关的例子在手册的对象小节中。
第二十四节 register_outputfilter 注册输出过滤器
动态注册一个输出过滤器,以便在模板输出之前进行操作。如何设立输出过滤函数,请查看模板输出过滤。
执行函数的格式可以是一个包含函数名称的字符串;也可以是一个array(&$object, $method)数组形式,其中&$object是一个对象的引用,而$method是它的一个方法;还可以是一个array(&$ class, $method)数组形式,其中$class是一个类的名称,$method是类中的一个方法。
第二十五节 register_postfilter注册提交过滤器
动态注册一个在模板编译之后执行的提交过滤器。如何设立提交过滤函数,请查看模板提交过滤器。
执行函数的格式可以是一个包含函数名称的字符串;也可以是一个array(&$object, $method)数组形式,其中&$object是一个对象的引用,而$method是它的一个方法;还可以是一个array(&$ class, $method)数组形式,其中$class是一个类的名称,$method是类中的一个方法。
第二十六节 register_prefilter注册预过滤器
注册一个在模板编译之前执行的预过滤器。如何设立预过滤函数,请查看模板预过滤器。
执行函数的格式可以是一个包含函数名称的字符串;也可以是一个array(&$object, $method)数组形式,其中&$object是一个对象的引用,而$method是它的一个方法;还可以是一个array(&$ class, $method)数组形式,其中$class是一个类的名称,$method是类中的一个方法。
第二十七节 register_resource注册资源
动态注册一个资源插件,前两个参数是资源的名称和执行函数的数组。关于如何建立一个函数取出模板,请看模板资源部分
注意:资源的名称主要要有两个字符组成。一个字符的资源名称将被忽略,并被视为是文件路径的一部分,比如$smarty->display('c:/path/to/index.tpl');。
执行函数数组必须包含4或5个元素。包含4个元素的情况下,这些函数分别是处理“source 源文本”、“timestamp 时间戳”、“secure 安全”、“trusted 可信的”的函数。5个元素的情况下,第一个元素必须是一个对象的引用,或者是一个类名,后面的4个元素是实现处理“source 源文本”、“timestamp 时间戳”、“secure 安全”、“trusted 可信的”的方法。
例子 13-24. 注册资源
$smarty->register_resource("db", array("db_get_template", |
第二十八节 trigger_error触发错误
用来使用Smarty内置的方法输出错误信息。参数level可以是PHP函数trigger_error()的一个参数值,如E_USER_NOTICE, E_USER_WARNING等,一般默认为E_USER_WARNING。
第二十九节 template_exists模板是否存在
检查制定的模板是否存在,参数template既可以是模板的文件路径,也可以是指定的资源字符串。
第三十节 unregister_block注销一个块
动态注销一个块函数插件,参数是块函数的名称。
第三十一节 unregister_compiler_function注销编译函数
动态注销一个编译函数,参数name是编译函数的名称。
第三十二节 unregister_function注销函数
动态注销一个模板函数插件,参数是模板函数的名称。
例子 13-35. 注销函数
// we don't want template designers to have access to system files
|
第三十三节 unregister_modifier注销修饰器
动态注销修饰器插件,参数是模板修饰器的名称。
例子 13-26. 注销修饰器
// we don't want template designers to strip tags from elements
|
第三十四节 unregister_object注销对象
注销一个对象。
第三十五节 unregister_outputfilter注销输出过滤器
动态注销一个输出过滤器。
第三十六节 unregister_postfilter注销提交过滤器
动态注销提交过滤器(在模板编译完成后执行)。
第三十七节 unregister_prefilter注销预过滤器
动态注销一个预过滤器(模板编译前执行)。
第三十八节 unregister_resource注销资源
动态注销一个资源插件,参数是资源的名称。
例子 13-27. 注销资源
$smarty->unregister_resource("db"); |
存被用来保存一个文档的输出从而加速display()或fetch()函数的执行。如果一个函数被加进缓存,那么实际输出的内容将用缓存来代替。缓存可让事物非常快速的执行,特别是带有长计算时间的模板。一旦display()或fetch()用缓存输出,那么一个缓存文档将非常容易用几个模板文档或是配置文档等来组成〔功力不小〕。
一旦模板是动态〔应该不难理解〕的,哪些文档你加了缓存,缓存时间多长都是很重要的。举个例子,比如你站点的首页内容不是经常更改,那么对首页缓存一个小时或是更长都可得到很好效果。相反,几分钟就要更新一下信息的天气地图页面,用缓存就不好了。
第一节 Setting Up Caching [建立缓存]
首先要做的就是让缓存可用。这就要设置$caching = true(或 1.)
例14-1.使缓存可用
require('Smarty.class.php'); $smarty = new Smarty;
$smarty->caching = true;
$smarty->display('index.tpl'); |
建立缓存后,display('index.tpl')函数会把模板返回原来状态〔没缓存〕,也会把输出保存copy〖n.名词〗到$cache_dir.下次调用display('index.tpl'),保存的缓存copy〖n.〗会被再用来代替原来的模板。
技术提示:在$chche_dir目录里的文档命名跟模板一致。尽管是用.php作为扩展名,但并不会被当作php代码来解析。所以不要去修改它。
每个缓存页都有一个用$cache_lifetime来控制的会话期。初始值是3600秒,就是一小时〔废话嘛〕。会话期结束,缓存就会重建。你可以通过设置$caching=2来控制单个缓存文件各自的的过期时间。祥细内容察看$cache_lifetime里面的列表。
例14-2 设置单个缓存会话期〔时间〕
require('Smarty.class.php'); $smarty = new Smarty;
$smarty->caching = 2; // lifetime is per cache
// set the cache_lifetime for index.tpl to 5 minutes $smarty->cache_lifetime = 300; $smarty->display('index.tpl');
// set the cache_lifetime for home.tpl to 1 hour $smarty->cache_lifetime = 3600; $smarty->display('home.tpl');
// NOTE: the following $cache_lifetime setting will not work when $caching = 2. |
如果$compile_check可用,每个跟缓存文档相关的模板文档和配置文档都会被检查来确定是否需要修改。在缓存产生后,改动任何文档,缓存也跟着更新改动。设置$compile_check为false,这是实现最佳性能的最小改动〔应该是这样:D〕。
例14-3.可用$compile_check
require('Smarty.class.php'); $smarty = new Smarty;
$smarty->caching = true; $smarty->compile_check = true;
$smarty->display('index.tpl'); |
一旦$force_compile可用,缓存文档会一直重建。这有效地关闭缓存。$force_compile只是用来调试,更有效关闭缓存的方法是让$caching = false(或0.)
is_cached()函数可用来测试一个模板是否有有效的缓存。如果一个缓存模板需要从数据库中获取数据,可以用这个函数来跳过这个过程。
例14-4.使用is_cached()
require('Smarty.class.php'); $smarty = new Smarty;
$smarty->caching = true;
if(!$smarty->is_cached('index.tpl')) { // No cache available, do variable assignments here. $contents = get_database_contents(); $smarty->assign($contents); }
$smarty->display('index.tpl'); |
你可以插入模板函数insert来使部分页面动态化。除了在右下方显示的标语外整个页面都可以缓存。在缓存内容里面可以插入函数来使标语也动态化。查看相关文档关于insert的细节和例子。
你可以用clear_all_cache()来清除所有缓存,或用clear_cache()来清除单个缓存文档。
例14-5.清除缓存
require('Smarty.class.php'); $smarty = new Smarty;
$smarty->caching = true;
// clear out all cache files $smarty->clear_all_cache();
// clear only cache for index.tpl $smarty->clear_cache('index.tpl');
$smarty->display('index.tpl'); |
第二节 Multiple Caches Per Page 每页多个缓存
你可以用单个函数display()或fetch()来输出多个缓存文档。display('index.tpl')在多种条件下会有不同的输出内容,要单独的把缓存分开。可以通过函数的第二参数cache_id来达到效果。
例14-6.传给display()一个cache_id
require('Smarty.class.php'); $smarty = new Smarty;
$smarty->caching = true;
$my_cache_id = $_GET['article_id'];
$smarty->display('index.tpl',$my_cache_id); |
上面,我们通过变量$my_cache_id作为cache_id来display()。在index.tpl里$my_cache_id的每个唯一值,会建立单独的缓存。在这个例子里,"article_id"在URL传送,并用作cache_id。
技术提示:要注意从客户端(web浏览器)传值到Smarty(或任何PHP应用程序)的过程。尽管上面的例子用article_id从URL传值看起来很方便,却可能有糟糕的后果[安全问题]。cache_id被用来在文件系统里创建目录,如果用户想为article_id赋一个很大的值,或写一些代码来快速发送随机的article_ids,就有可能会使服务器出现问题。确定在使用它之前清空已存在的数据。在这个例子,可能你知道article_id的长度(值吧?!)是10字符,并只由字符-数字组成,在数据库里是个可用的article_id。Check for this!要注意检查这个问题!〔要注意这个提示!不用再说了吧?〕
确定传给is_cached()和clear_cache()的第二参数是同一个cache_id。
例14-7.传给is_cached()一个cache_id
require('Smarty.class.php'); $smarty = new Smarty;
$smarty->caching = true;
$my_cache_id = $_GET['article_id'];
if(!$smarty->is_cached('index.tpl',$my_cache_id)) { // No cache available, do variable assignments here. $contents = get_database_contents(); $smarty->assign($contents); }
$smarty->display('index.tpl',$my_cache_id); |
你可以通过把clear_cache()的第一参数设为null来为特定的cache_id清除所有缓存。
例14-8.为特定的cache_id清除所有缓存
require('Smarty.class.php'); $smarty = new Smarty;
$smarty->caching = true;
// clear all caches with "sports" as the cache_id $smarty->clear_cache(null,"sports");
$smarty->display('index.tpl',"sports"); |
通过这种方式,你可以用相同的cache_id来把你的缓存集合起来。
第三节 Cache Groups [缓存集合]
你可以通过建立cache_id集合做更祥细的集合体。在cache_id的值里用竖线"|"来分开子集合。你可以尽可能多的包含子集合。
例14-9.cache_id集合
require('Smarty.class.php'); $smarty = new Smarty;
$smarty->caching = true;
// clear all caches with "sports|basketball" as the first two cache_id groups $smarty->clear_cache(null,"sports|basketball");
// clear all caches with "sports" as the first cache_id group. This would // include "sports|basketball", or "sports|(anything)|(anything)|(anything)|..." $smarty->clear_cache(null,"sports");
$smarty->display('index.tpl',"sports|basketball"); |
技术提示:缓存集合并不像cache_id一样对模板使用路径。比如,如果你display('themes/blue/index.tpl'),那么在"themes/blue"目录下你并不能清除缓存。想要清除缓存,必须先用cache_id把缓存集合,像这样display('themes/blue/index.tpl','themes|blue');然后就可以用clear_cache(null,'themes|blue')清除blue theme(蓝色主题?!老外也真会叫...)下的缓存。
第四节 Controlling Cacheability of Plugins' Output控制插件输出的缓冲能力
自从Smarty-2.6.0插件以来,如果注册它们,则插件的缓存能力能够被重新声明的。register_block,register_compiler_function 和register_function的第3个参数就是$ cacheable , 并且它的值默认为true。当然,在2.6.0版本之前它的默认值也是这样的。
当用$cacheable=false来这册一个插件,则每次这个页面被输出的时候,这个插件就会被使用,即使这个页面来自缓存。这个插件函数的行为有点像这个函数insert。
和{insert}相反,插件的属性默认是不缓存的。通过使用第四个参数 $cache_attrs ,它们能够被重新声明为缓存的。 $cache_attrs 是一个属性名字的数组,可以被缓存,所以每次当它被从缓存中取出的时候,这个插件函数获得值-----因为这个页面会被写入用来缓存。
例14-10.阻止插件从缓存中输出
index.php:
require('Smarty.class.php'); $smarty = new Smarty; $smarty->caching = true;
function remaining_seconds($params, &$smarty) { $remain = $params['endtime'] - time(); if ($remain >=0) return $remain . " second(s)"; else return "done"; }
$smarty->register_function('remaining', 'remaining_seconds', false, array('endtime'));
if (!$smarty->is_cached('index.tpl')) { // fetch $obj from db and assign... $smarty->assign_by_ref('obj', $obj); }
$smarty->display('index.tpl');
index.tpl:
Time Remaining: {remain endtime=$obj->endtime} |
直到$obj运行结束,时间的秒数在每一个页面输出的时候会改变,即使这个页面被缓存。只要结束时间属性被缓存,当页面被写入到缓存但是没有对这个页面接着的请求的时候对象只是不得不重新从数据库里取出而已。
例14-11.阻止一个模板文件的 整篇被缓存
index.php:
require('Smarty.class.php'); $smarty = new Smarty; $smarty->caching = true;
function smarty_block_dynamic($param, $content, &$smarty) { return $content; } $smarty->register_block('dynamic', 'smarty_block_dynamic', false);
$smarty->display('index.tpl');
index.tpl:
Page created: {"0"|date_format:"%D %H:%M:%S"}
{dynamic}
Now is: {"0"|date_format:"%D %H:%M:%S"}
... do other stuff ...
{/dynamic} |
当重新加载这个页面,你将会注意到这两个日期不同。一个是“动态“,一个是“静态”。你能够在{dynamic}...{/dynamic}之间作任何事情,并且保证它将不会像剩下的页面一样被缓存。
第一节
1、Objects 对象
SMARTY允许通过模板访问PHP对象。有两种方式来访问它们。一种是注册对象到模板,然后通过类似于用户自定义函数的形式来访问它。另一种方法给模板分配对象,然后通过访问其它赋值变量类似的方法进行访问。第一种方法有一个很好的模板语法,同时它作为一个注册对象被限制为几个固定的方法和目标,这样是比较安全的。然而一个注册对象不能够在相对自身数组里面循环使用和赋值。总之,你根据你自己的需求来觉得选用那种方法,但是使用第一种方法的话,可以让你的模伴语法达到最小。
如果安全选项激活后,就没有私有成员或者函数能够被访问(以"_"开头)。如果有一个同名成员或者对象存在,那么方法将被使用。
你可以限制成员和函数,但是外解可以通过列举它们为一个第三注册变量的数组的方式来访问它。
一般情况下,参数通过模板传递给对象的方法和自定义函数获得参数的方法是一样的。一个混合数组作为第一个参数传递,而SMARTY对象作为第二个。如果你想像传统的对象参数一样一次传递一个参数,设置第四个参数为 FALSE即可。
Example 15-1. using a registered or assigned object
// the object
class My_Object() { function meth1($params, &$smarty_obj) { return "this is my meth1"; } }
$myobj = new My_Object; // registering the object (will be by reference) $smarty->register_object("foobar",$myobj); // if we want to restrict access to certain methods or properties, list them $smarty->register_object("foobar",$myobj,array('meth1','meth2','prop1')); // if you want to use the traditional object parameter format, pass a boolean of false $smarty->register_object("foobar",$myobj,null,false);
// We can also assign objects. Assign by ref when possible. $smarty->assign_by_ref("myobj", $myobj);
$smarty->display("index.tpl"); ?>
TEMPLATE:
{* access our registered object *} {foobar->meth1 p1="foo" p2=$bar}
{* you can also assign the output *} {foobar->meth1 p1="foo" p2=$bar assign="output"} the output was {$output)
{* access our assigned object *} {$myobj->meth1("foo",$bar)} |
2、Prefilters 预过滤器
模板后过滤器是一些PHP函数,模板就是在那些函数编译后才运行。这样有利于预先处理你的模板,删除不不需要的内容,监视对模板进行的操作,例如:预过滤器同样能够通过 load filter() 函数和设置 $autoload filters 变量来注册或者从工具目录里载入。SMARTY将传递模板输出作为第一个参数,通过自定义函数返回处理结果。
Example 15-2. using a template prefilter
// put this in your application function remove_dw_comments($tpl_source, &$smarty) { return preg_replace("//U","",$tpl_source); }
// register the prefilter $smarty->register_prefilter("remove_dw_comments"); $smarty->display("index.tpl"); ?>
{* Smarty template index.tpl *} |
3、Postfilters 后过滤器http://www.jinguandianpu.com/
模板后过滤器是一些PHP函数,模板就是在那些函数编译后才运行。后过滤器同样能够通过 load filter() 函数和设置 $autoload filters 变量来注册或者从工具目录里载入。SMARTY将传递模板输出作为第一个参数,通过自定义函数返回处理结果。
Example 15-3. using a template postfilter
// put this in your application function add_header_comment($tpl_source, &$smarty) { return "\n\" ?>\n".$tpl_source; }
// register the postfilter $smarty->register_postfilter("add_header_comment"); $smarty->display("index.tpl"); ?>
{* compiled Smarty template index.tpl *} {* rest of template content... *} |
4、Output Filters 输出滤镜
当模板通过函数 display() 或者 fetch()被调用时,它的输出能够通过一个或者多个滤镜而发出。它与预过滤器的不同之处就是预过滤器编译模板是在模板保存到磁盘之前,输出滤镜是在它执行的时候才操作模板输出的。
输出滤镜同样能够通过 load filter() 函数和设置 $autoload filters 变量来注册或者从工具目录里载入。SMARTY将传递模板输出作为第一个参数,通过自定义函数返回处理结果。
Example 15-4. using a template outputfilter
// put this in your application function protect_email($tpl_output, &$smarty) { $tpl_output = preg_replace('!(\S+)@([a-zA-Z0-9\.\-]+\.([a-zA-Z]{2,3}|[0-9]{1,3}))!', '$1%40$2', $tpl_output); return $tpl_output; }
// register the outputfilter $smarty->register_outputfilter("protect_email"); $smarty->display("index.tpl");
// now any occurrence of an email address in the template output will have // a simple protection against spambots ?> |
5、Cache Handler Function缓冲处理函数
作为一个可选择使用的默认基于文本的缓冲机制,你可以定制或者自定义缓冲处理函数来进行读、写、清除缓冲文件。
如果要在应用程序下建立一个函数,SMARTY将会使用一个缓冲处理。设置这个函数名为 $cache handler func 中类变量名。Smarty将使用这个函数来处理缓冲数据。第一个参数不管是‘读’,‘写’,‘清除’,都是动态的。第二个参数是 Smarty 对象。第三个参数是缓冲的内容。在进行写操作之前,Smarty 传递这些缓冲内容给这些参量。在进行读操作之前,Smarty预处理那些缓冲数据相关或者封装好了的函数。在进行清除操作之前,从他没有使用起,就传递一个虚拟变量。第四个参数是模板文件名(需要读和写的文件),第五个函数是缓冲ID(额外选项),然后第六个参数是编译的ID(额外选项)。
注意:最新的参数名 ($exp_time) 在Smarty-2.6.0中才加入的。http://www.jinguandianpu.com/
Example 15-5. example using MySQL as a cache source
/*
example usage:
include('Smarty.class.php'); include('mysql_cache_handler.php');
$smarty = new Smarty; $smarty->cache_handler_func = 'mysql_cache_handler';
$smarty->display('index.tpl');
mysql database is expected in this format:
create database SMARTY_CACHE;
create table CACHE_PAGES( CacheID char(32) PRIMARY KEY, CacheContents MEDIUMTEXT NOT NULL );
*/
function mysql_cache_handler($action, &$smarty_obj, &$cache_content, $tpl_file=null, $cache_id=null, $compile_id=null, $exp_time=null) { // set db host, user and pass here $db_host = 'localhost'; $db_user = 'myuser'; $db_pass = 'mypass'; $db_name = 'SMARTY_CACHE'; $use_gzip = false;
// create unique cache id $CacheID = md5($tpl_file.$cache_id.$compile_id);
if(! $link = mysql_pconnect($db_host, $db_user, $db_pass)) { $smarty_obj->_trigger_error_msg("cache_handler: could not connect to database"); return false; } mysql_select_db($db_name);
switch ($action) { case 'read': // save cache to database $results = mysql_query("select CacheContents from CACHE_PAGES where CacheID='$CacheID'"); if(!$results) { $smarty_obj->_trigger_error_msg("cache_handler: query failed."); } $row = mysql_fetch_array($results,MYSQL_ASSOC);
if($use_gzip && function_exists("gzuncompress")) { $cache_contents = gzuncompress($row["CacheContents"]); } else { $cache_contents = $row["CacheContents"]; } $return = $results; break; case 'write': // save cache to database
if($use_gzip && function_exists("gzcompress")) { // compress the contents for storage efficiency $contents = gzcompress($cache_content); } else { $contents = $cache_content; } $results = mysql_query("replace into CACHE_PAGES values( '$CacheID', '".addslashes($contents)."') "); if(!$results) { $smarty_obj->_trigger_error_msg("cache_handler: query failed."); } $return = $results; break; case 'clear': // clear cache info if(empty($cache_id) && empty($compile_id) && empty($tpl_file)) { // clear them all $results = mysql_query("delete from CACHE_PAGES"); } else { $results = mysql_query("delete from CACHE_PAGES where CacheID='$CacheID'"); } if(!$results) { $smarty_obj->_trigger_error_msg("cache_handler: query failed."); } $return = $results; break; default: // error, unknown action $smarty_obj->_trigger_error_msg("cache_handler: unknown action \"$action\""); $return = false; break; } mysql_close($link); return $return;
}
?> |
第二节 Resources资源
模板可以来自各种各样的资源。当你显示或者取得一个模板,或者当你在一个模板里面包含另外一个模板时,只要提供一个类型的资源,紧跟正确的路径和模板名。如果一个模板资源没有明确的给出 $default resource type 变量值,就认为这个资源为假定值。
1、Templates from $template_dir
Example 15-6. using templates from $template_dir
// from PHP script $smarty->display("index.tpl"); $smarty->display("admin/menu.tpl"); $smarty->display("file:admin/menu.tpl"); // same as one above
{* from within Smarty template *} {include file="index.tpl"} {include file="file:index.tpl"} {* same as one above *} |
2、Templates from any directory
Example 15-7. using templates from any directory
// from PHP script $smarty->display("file:/export/templates/index.tpl"); $smarty->display("file:/path/to/my/templates/menu.tpl");
{* from within Smarty template *} {include file="file:/usr/local/share/templates/navigation.tpl"} |
Example 15-8. using templates from windows file paths
// from PHP script $smarty->display("file:C:/export/templates/index.tpl"); $smarty->display("file:F:/path/to/my/templates/menu.tpl");
{* from within Smarty template *} {include file="file:D:/usr/local/share/templates/navigation.tpl"} |
3、Templates from other sources
Example 15-9. using custom resources
// from PHP script
// put these function somewhere in your application function db_get_template ($tpl_name, &$tpl_source, &$smarty_obj) { // do database call here to fetch your template, // populating $tpl_source $sql = new SQL; $sql->query("select tpl_source from my_table where tpl_name='$tpl_name'"); if ($sql->num_rows) { $tpl_source = $sql->record['tpl_source']; return true; } else { return false; } }
function db_get_timestamp($tpl_name, &$tpl_timestamp, &$smarty_obj) { // do database call here to populate $tpl_timestamp. $sql = new SQL; $sql->query("select tpl_timestamp from my_table where tpl_name='$tpl_name'"); if ($sql->num_rows) { $tpl_timestamp = $sql->record['tpl_timestamp']; return true; } else { return false; } }
function db_get_secure($tpl_name, &$smarty_obj) { // assume all templates are secure return true; }
function db_get_trusted($tpl_name, &$smarty_obj) { // not used for templates }
// register the resource name "db" $smarty->register_resource("db", array("db_get_template", "db_get_timestamp", "db_get_secure", "db_get_trusted"));
// using resource from php script $smarty->display("db:index.tpl");
{* using resource from within Smarty template *} {include file="db:/extras/navigation.tpl"} |
4、Default template handler function
Example 15-10. using the default template handler function
// put this function somewhere in your application
function make_template ($resource_type, $resource_name, &$template_source, &$template_timestamp, &$smarty_obj) { if( $resource_type == 'file' ) { if ( ! is_readable ( $resource_name )) { // create the template file, return contents. $template_source = "This is a new template."; $template_timestamp = time(); $smarty_obj->_write_file($resource_name,$template_source); return true; } } else { // not a file return false; } }
// set the default handler $smarty->default_template_handler_func = 'make_template'; ?> |
2.0版本引入了被广泛应用于自定义Smarty功能的插件机制。它包括如下类型:
· functions 函数插件
· modifiers 修饰插件
· block functions 区块函数插件
· compiler functions 编译函数插件
· prefilters 预滤器插件
· postfilters 补滤器插件
· outputfilters 输出过滤插件
· resources 资源插件
· inserts 嵌入插件
为了与旧有方式保持向后兼容,除资源插件外,保留了通过register_* API方式装载函数的处理方法。如果你不是使用API方式而是使用直接修改类变量 $custom_funcs, $custom_mods 等的方法,那么你就需要修改你的程序了。或者使用API的方法,或者将你的自定义功能转换成插件。
第一节 How Plugins Work插件如何工作
插件总在需要的时候被装载。只有在模板脚本里调用的特定修饰、函数、资源插件等会被装载。此外,即便在同一个请求中有几个不同的Smarty实体运行,每个插件也只被装载一次。
预/补过滤器插件和输出过滤器插件的装载方式有些不同。由于在模板中未被提及,它们必须在模板被处理前通过API函数明确地装入系统。同类型的多个过滤器插件依据被装载的次序先后不同分别先后执行。
插件目录是包含一条路径信息的字符串或包含多条路径信息的字符串数组。安装插件的时候,将插件置于其中一个目录下,Smarty会自动识别使用。
第二节 Naming Conventions命名约定
件文件和函数必须遵循特定的命名约定以便Smarty识别。
插件文件必须命名如下:
type . name .php
其中type是如下插件中的一种:
· function
· modifier
· block
· compiler
· prefilter
· postfilter
· outputfilter
· resource
· insert
name为仅包含字母、数字和下划线的合法标志符。
插件内的函数应遵循如下命名约定:
smarty_ type _ name ()
type和name的意义如前。
如果指定的插件文件不存在或命名不合规范,Smarty会输出相应的错误信息。
第三节 Writing Plugins编写插件
Smarty可自动从文件系统装载插件,或者运行时通过register_* API函数装载。可以通过unregister_* API函数卸载已经装载的插件。
只在运行时装载的插件的函数名称不需要遵守命名约定。
如果某个插件依赖其它插件内的某些功能(例如某些插件功能捆绑于Smarty内),那么可以通过如下方法装载必须的插件:
require_once $smarty->_get_plugin_filepath('function', 'html_options'); |
Smarty对象通常作为传递给插件的最后一个参数(有两个例外:1、修饰插件根本不接受传递过来的Smarty对象。2、为了向上兼容老版本的Smarty,区块插件将 &$repeat作为最后一个参数,因此Smarty对象是倒数第二个参数。)
第四节Template Functions模板函数
模板传递给模板函数的所有的属性都包含在参数数组 $params中,既可以通过如: $params['start'] 的方式直接处理其中的值,也可以使用 extract($params) 的方式将所有值导入符号表中。
函数输出(返回值)的内容将取代模板中函数名称出现的位置(例如:fetch()函数)。同时函数也可能只是执行些后台任务,并无任何输出
如果函数需要向模板中增加变量或者使用Smarty提供的某些功能,可以通过 $smarty对象实现。
See also相关内容: register_function(), unregister_function().
例16-1:有输出插件函数
/* * Smarty plugin * ------------------------------------------------------------- * File: function.eightball.php * Type: function * Name: eightball * Purpose: outputs a random magic answer * ------------------------------------------------------------- */ function smarty_function_eightball($params, &$smarty) { $answers = array('Yes', 'No', 'No way', 'Outlook not so good', 'Ask again soon', 'Maybe in your reality');
$result = array_rand($answers); return $answers[$result]; } ?> |
在模板中调用方法如下:
Question: Will we ever have time travel? Answer: {eightball}. |
例16-2:无输出插件函数
/* * Smarty plugin * ------------------------------------------------------------- * File: function.assign.php * Type: function * Name: assign * Purpose: assign a value to a template variable * ------------------------------------------------------------- */ function smarty_function_assign($params, &$smarty) { extract($params);
if (empty($var)) { $smarty->trigger_error("assign: missing 'var' parameter"); return; }
if (!in_array('value', array_keys($params))) { $smarty->trigger_error("assign: missing 'value' parameter"); return; }
$smarty->assign($var, $value); } ?> |
第五节 Modifiers修正器
修正器是一些短小的函数,这些函数被应用于模版中的一个变量,然后变量再显示或用于其他的一些文档。我们可以把修正器链接起来。
修正器插件的第一个参数是不可缺少的。剩余的参数是可选的,它们的有无取决于期望执行哪一种操作。
修正器必须有返回值。
也可参考register_modifier(), unregister_modifier().
Example 16-3. simple modifier plugin简单修正器插件 |
这个插件主要目的是用另一个名字替换一个内置PHP函数的名字。他没有任何多余的参数。
/* * Smarty plugin * ------------------------------------------------------------- * File: modifier.capitalize.php * Type: modifier * Name: capitalize * Purpose: capitalize words in the string * ------------------------------------------------------------- */ function smarty_modifier_capitalize($string) { return ucwords($string); } ?> |
Example 16-4. more complex modifier plugin更加复杂的修正器插件
/* * Smarty plugin * ------------------------------------------------------------- * File: modifier.truncate.php * Type: modifier * Name: truncate * Purpose: Truncate a string to a certain length if necessary, * optionally splitting in the middle of a word, and * appending the $etc string. * ------------------------------------------------------------- */ function smarty_modifier_truncate($string, $length = 80, $etc = '...', $break_words = false) { if ($length == 0) return '';
if (strlen($string) > $length) { $length -= strlen($etc); $fragment = substr($string, 0, $length+1); if ($break_words) $fragment = substr($fragment, 0, -1); else $fragment = preg_replace('/\s+(\S+)?$/', '', $fragment); return $fragment.$etc; } else return $string; } ?> |
第六节 Block Functions块函数
块函数的形式是这样的:{func} .. {/func}。换句话说,他们用标记圈起一个块,然后对这个块的内容进行操作。块函数优先于同名的传统函数,即你不能同时有通明的传统函数{func}和块函数{func} .. {/func}。
默认地你的函数执行被Smarty调用两次:一次是在开始标记,另一次是在结束标记(参考下面的&$repeat怎样改变这种情况)
块函数仅开始标记可以有属性。所有从模板传替给模板函数的属性被囊括与一个集合数组参数中。你可以直接获取其值,例如:$params['start']或者是用extract($params)将它们导入符号表中。当处理结束标记时,开始标记的属性对你的函数也是可用的。
变量 $content 的值取决于是否因开始标记或结束标记调用你的函数。假如是开始标记,它会是空的,如果是结束标记,它会是模板块的内容。请注意模板块已经被Smarty处理,所以你接收到的结果是输出后的模板而不是原样模板。
参数 &$repeat 通过参考引用传递给函数执行过程并为其提供一个可能值来控制显示块多少遍。默认情况下在首次调用块函数(块开始标记)时变量 $repeat 是真,在随后的所有块函数调用中其始终是假。每当函数执行返回的 &$repeat 是真时,在{func} .. {/func}之间的内容再次求值,函数执行接收一个新块参数 $content 内容值被再次调用。
如果你嵌套了块函数,通过访问变量$smarty->_tag_stack 找出父块函数是可能的。仅仅对块函数运行一下var_dump(),函数结构就会一目了然了。
See also: register_block(), unregister_block().
Example 16-5. block function
/* * Smarty plugin * ------------------------------------------------------------- * File: block.translate.php * Type: block * Name: translate * Purpose: translate a block of text * ------------------------------------------------------------- */ function smarty_block_translate($params, $content, &$smarty) { if (isset($content)) { $lang = $params['lang']; // do some intelligent translation thing here with $content return $translation; } } |
第七节 Compiler Functions编译函数
编译函数仅在模板编译过程中被调用。对于将PHP代码或对时间敏感的静态内容嵌入到模板中,他们是比较有用的。如果编译函数和普通函数都注册了同一个名字,则编译函数具有优先使用权。
此编译函数有两个参数:标记参数字符串——基本上是从函数名字直到结束位置的所有内容,另一个参数是Smarty对象。该函数将返回嵌入到被编译模板中的PHP代码。
See also register_compiler_function(), unregister_compiler_function().
Example 16-6. simple compiler function简单编译函数
/* * Smarty plugin * ------------------------------------------------------------- * File: compiler.tplheader.php * Type: compiler * Name: tplheader * Purpose: Output header containing the source file name and * the time it was compiled. * ------------------------------------------------------------- */ function smarty_compiler_tplheader($tag_arg, &$smarty) { return "\necho '" . $smarty->_current_file . " compiled at " . date('Y-m-d H:M'). "';"; } ?> |
这个函数在模板中以如下方式调用:
{* this function gets executed at compile time only *} {tplheader} |
在编译之后的模板中被嵌入的PHP代码内容如下:
echo 'index.tpl compiled at 2002-02-20 20:02'; ?> |
第八节 Prefilters/Postfilters预滤器/后滤器
从概念上看,预滤器和后滤器插件都很简单;不同之处就在于它们的执行,更确切地说是它们的执行时刻(非时间段,而是某一个时刻)。
string smarty_prefilter_
name (string $source, object &$smarty)
预滤器用来在编译之前直接处理模板源文件。预滤器函数的第一个参数是模板源文件,该文件可能被其他一些预滤器修正过。此预滤器插件将返回修正过的源文件。请记住此源文件仅用来编译,它不会在任何地方被保存。
string smarty_postfilter_
name (string $compiled, object &$smarty)
后滤器用来在编译之后直接处理模板的编译输出(PHP代码),但须在编译之后的模板被保存到文件系统之前就进行操作。预滤器函数的第一个参数是编译之后的模板代码,该代码可能被其他一些后滤器修正过。此后滤器插件将返回修正过的代码文件。
Example 16-7. prefilter plugin预滤器插件
/* * Smarty plugin * ------------------------------------------------------------- * File: prefilter.pre01.php * Type: prefilter * Name: pre01 * Purpose: Convert html tags to be lowercase. * ------------------------------------------------------------- */ function smarty_prefilter_pre01($source, &$smarty) { return preg_replace('!<(\w+)[^>]+>!e', 'strtolower("$1")', $source); } ?> |
Example 16-8. postfilter plugin后滤器插件
/* * Smarty plugin * ------------------------------------------------------------- * File: postfilter.post01.php * Type: postfilter * Name: post01 * Purpose: Output code that lists all current template vars. * ------------------------------------------------------------- */ function smarty_postfilter_post01($compiled, &$smarty) { $compiled = " \nget_template_vars()); ?>\n" . $compiled; return $compiled; } ?> |
第九节 Output Filters输出过滤器
输出过滤器插件的作用是,在装载并执行完一个模板之后显示模板之前,操作该模板的输出。
string smarty_outputfilter_
name (string $template_output, object &$smarty)
输出过滤器函数第一个参数是需要处理的模板输出,第二个参数是调用这个插件的Smarty实例。此插件将会对参数进行处理并返回相应的结果。
Example 16-9. output filter plugin输出过滤器插件
/* * Smarty plugin * ------------------------------------------------------------- * File: outputfilter.protect_email.php * Type: outputfilter * Name: protect_email * Purpose: Converts @ sign in email addresses to %40 as * a simple protection against spambots * ------------------------------------------------------------- */ function smarty_outputfilter_protect_email($output, &$smarty) { return preg_replace('!(\S+)@([a-zA-Z0-9\.\-]+\.([a-zA-Z]{2,3}|[0-9]{1,3}))!', '$1%40$2', $output); } |
第十节 Resources资源
资源插件被认为是为Smarty提供模板源或PHP脚本组件的一种普通方式。一些资源例子如:数据库、LDAP、共享内存、sockets(套接字)等等。
需要为每一种类型的资源注册四个函数。每一个函数将接收被请求的资源作为第一个参数,Smarty对象作为最后一个参数。剩余的参数取决于函数的不同。
bool smarty_resource_
name _source
(string $rsrc_name, string &$source, object &$smarty)
bool smarty_resource_
name _timestamp
(string $rsrc_name, int &$timestamp, object &$smarty)
bool smarty_resource_
name _secure
(string $rsrc_name, object &$smarty)
bool smarty_resource_
name _trusted
(string $rsrc_name, object &$smarty)
第一个函数将会检索资源。它的第二个参数是一个参考引用变量,结果值会存放到该变量里面。如果此函数能成功的检索到资源,将会返回true,否则返回false。
第二个函数将会检索被请求资源的最后修改时间(UNIX时间戳)。它的第二个参数是一个参考引用变量,时间戳值会存放到该变量里面。如果此函数能成功的确定时间戳,将会返回true,否则返回false。
第三个函数将会返回true或false,取决于被请求资源是否安全。这个函数仅用于模板资源,但仍应被定义。
第四个函数将会返回true或false,取决于被请求资源是否被信任。这个函数仅用于被 {include_php} 或 {insert} 标记以 src属性请求的PHP脚本组件。但仍应被定义,甚至用于模板资源也不例外。
See also register_resource(), unregister_resource().
Example 16-10. resource plugin资源插件
/* * Smarty plugin * ------------------------------------------------------------- * File: resource.db.php * Type: resource * Name: db * Purpose: Fetches templates from a database * ------------------------------------------------------------- */ function smarty_resource_db_source($tpl_name, &$tpl_source, &$smarty) { // do database call here to fetch your template, // populating $tpl_source $sql = new SQL; $sql->query("select tpl_source from my_table where tpl_name='$tpl_name'"); if ($sql->num_rows) { $tpl_source = $sql->record['tpl_source']; return true; } else { return false; } }
function smarty_resource_db_timestamp($tpl_name, &$tpl_timestamp, &$smarty) { // do database call here to populate $tpl_timestamp. $sql = new SQL; $sql->query("select tpl_timestamp from my_table where tpl_name='$tpl_name'"); if ($sql->num_rows) { $tpl_timestamp = $sql->record['tpl_timestamp']; return true; } else { return false; } }
function smarty_resource_db_secure($tpl_name, &$smarty) { // assume all templates are secure return true; }
function smarty_resource_db_trusted($tpl_name, &$smarty) { // not used for templates } ?> |
第十一节 Inserts插入
插入插件用来执行在模板中被 {insert} 标记调用的函数 。
string smarty_insert_
name (array $params, object &$smarty)
函数的第一个参数是一个传递给插入动作的属性集合数组。每一种方式都可以直接获取那些属性值,例如$params['start'],或用extract($params)将属性导入符号表中。
插入函数将会返回某值,该值将在模板中的 {insert} 标记处被替换。
Example 16-11. insert plugin插入插件
/* * Smarty plugin * ------------------------------------------------------------- * File: insert.time.php * Type: time * Name: time * Purpose: Inserts current date/time according to format * ------------------------------------------------------------- */ function smarty_insert_time($params, &$smarty) { if (empty($params['format'])) { $smarty->trigger_error("insert time: missing 'format' parameter"); return; }
$datetime = strftime($params['format']); return $datetime; } ?> |
1、Smarty/PHP errors错误
Smarty能够发现许多类似缺少标签属性或者不规范变量名这样的错误。如果发生这种错误,就会有下面的错误提示:
Example 17-1. Smarty errors错误
Warning: Smarty: [in index.tpl line 4]: syntax error: unknown tag - '%blah' in /path/to/smarty/Smarty.class.php on line 1041 警告:Smarty: 在index.tpl文件第4行,语法错误:'%blah'标签未知
Fatal error: Smarty: [in index.tpl line 28]: syntax error: missing section name in /path/to/smarty/Smarty.class.php on line 1041 严重错误:Smarty: 在index.tpl文件第28行,语法错误:缺少节段名字在 /path/to/smarty/路径中的Smarty.class.php文件1041行 |
Smarty可以显示模板名称以及行号和错误。这些错误显示未所发生错误所属的smarty类所在的实际行号。
某些错误Smarty不能捕捉,像缺少结束标签。这些类型的错误通常会在在php分析语法错误的编译时间中就捕捉出来了.
Example 17-2. PHP parsing errors
Parse error: parse error in /path/to/smarty/templates_c/index.tpl.php on line 75 |
当你遇到一个php解析错误时,错误行号将反应到php编译脚本,而不是模板本身。通常,你会看到模板并发现语法错误。通常会发现:缺少if}{/if} 或者
{section}{/section}的结束标签。或者{if}标签内的逻辑语法错误。如果你不能检查出错误,那就得在模板中打开php编译文件按照行号找出相应错误。
1、Blank Variable Handling空白变量处理
也许有时候你想给一个没有赋值的变量输出一个默认的值来代替什么也不输出,比如输出' '[这是一个空格符号,HTML里的标记]来使得表格里的背景能够正常工作。大多数人使用{if}语句来处理这些,但是用Smatry这里有一个捷径,那就是使用 default [默认的]值赋给变量。
例 18-1。输出 ---如果一个变量是空值
{* the long way *}
{if $title eq ""}
{else} {$title} {/if}
{* the short way *}
{$title|default:" "} |
2、Default Variable Handling默认变量处理
如果一个变量在你的整个模板里被经常使用,而当你每次要用到这个变量的时候就给它赋默认的值,那将是无法忍受的。你可以通过使用 assign[赋值]这个函数来给这个变量赋上它的默认值来你补救。
例 18-2.赋给一个模板变量默认的值
{* do this somewhere at the top of your template *} {assign var="title" value=$title|default:"no title"}
{* if $title was empty, it now contains the value "no title" when you print it *} {$title} |
3、Passing variable title to header template传递变量标题给头模板
当你的大多数模板文件用到了一些相同的头模板文件和脚模板文件,通常是把这些模板分开并且包含他们。但是如果头模板需要什么来使得显示一些不同的标题,取决于你用到的那些页面?你可以传递这些标题给头模板---当它们被包含的时候。
例 18-3.传递变量标题给头模板
mainpage.tpl ------------
{include file="header.tpl" title="Main Page"} {* template body goes here *} {include file="footer.tpl"}
archives.tpl ------------
{config_load file="archive_page.conf"} {include file="header.tpl" title=#archivePageTitle#} {* template body goes here *} {include file="footer.tpl"}
header.tpl ----------
footer.tpl ---------- |
当这个主页[main page]被浏览的时候,‘Main Page'这个标题就会传递给头模板文件[header.tpl],并且结果会被用成为标题。当这个档案页[archives page]被浏览的时候,文件标题将会是‘Archives'。注意在这个档案页例子中,我们用了一个来自这个文件[archives_page.conf]的变量来代替一个硬性的代码变量。当然,要是变量[$title]没有初始化,我们会发现‘BC News'被输出----用那种使用默认值的变量的方法。
4、Dates日期
就像一条经验法则,经常是把日期当成时间戳传递给Smarty。 这样使得模板设计人员可以使用date_format[日期格式化]这个函数来对日期格式化进行全面控制,当然,这使得在需要比较日期的时候比较容易。
注意:从Smarty 1.4.0起,你可以像用unix中的时间戳,mysql中的时间戳,或者任何能够用这个函数[strtotime()]进行分析的时间戳那样把日期传递给Smarty。
例 18-4. 使用日期格式化
{$startDate|date_format}
OUTPUT:
Jan 4, 2001
{$startDate|date_format:"%Y/%m/%d"}
OUTPUT:
2001/01/04
{if $date1 < $date2} ... {/if} |
当在一个模板文件里使用{html_select_date}的时候,程序员将可能想在一个输出文件中把这种形式转回成时间戳的形式。下面就是一个可以帮助你达到目的的函数。
Example 18-5. converting form date elements back to a timestamp
// this assumes your form elements are named // startDate_Day, startDate_Month, startDate_Year
$startDate = makeTimeStamp($startDate_Year,$startDate_Month,$startDate_Day);
function makeTimeStamp($year="",$month="",$day="") { if(empty($year)) $year = strftime("%Y"); if(empty($month)) $month = strftime("%m"); if(empty($day)) $day = strftime("%d");
return mktime(0,0,0,$month,$day,$year); } |
5、WAP/WML
WAP/WML模板需要一个说明文件内容形式的文件头和模板同时传递出去。最容易的方式就是编写一个客户型的函数用来输出这个文件头。如果你使用缓冲,那将不会起作用,所以我们使用一些插入标记(记住:插入标记不是缓冲!)。请确保在你的模板输出到浏览器之前没有任何东西被输出,否则文件头将实效。
例 18-6. 使用插入来写一个WML类型的文件头
// be sure apache is configure for the .wml extensions! // put this function somewhere in your application, or in Smarty.addons.php function insert_header() { // this function expects $content argument extract(func_get_arg(0)); if(empty($content)) return; header($content); return; }
// your Smarty template _must_ begin with the insert tag example:
{insert name=header content="Content-Type: text/vnd.wap.wml"}
Welcome to WAP with Smarty! Press OK to continue...
Pretty easy isn't it?
|
6、Componentized Templates组合的模板
这项技巧有点普通,但是仍然是个不错的思想,如果要使用的话,自担风险。;-)
传统上,把模板编入你的应用程序中步骤如下:首先,你累计一下你的PHP程序中的变量,(可能用到数据库查询。)然后,你实例化一个你的Smarty对象,给变量赋值并且输出这个模板。因此,例如我们说我们在我们的模板里有一个资源标记。我们可以在我们的应用程序中收集这些资源数据,然后给模板中的这些变量赋值并输出。现在如果你仅仅是通过包含这些模板就可以把资源标记加入到任何一个应用程序中不是很好吗?
你可以通过使用{php}{/php}这两个标签来在你的模板里嵌入PHP。这样,你就能够建立包含自身的使用自己的数据结构的模板来给他们自身的变量赋值。通过像这样逻辑的嵌入,你能够把模板和逻辑性结合起来。这种方法使得模板不管源于何处总是像一个构件一样组合在一起。
例 18-7. 组合的模板
{* Smarty *}
{php}
// setup our function for fetching stock data function fetch_ticker($symbol,&$ticker_name,&$ticker_price) { // put logic here that fetches $ticker_name // and $ticker_price from some resource }
// call the function fetch_ticker("YHOO",$ticker_name,$ticker_price);
// assign template variables $this->assign("ticker_name",$ticker_name); $this->assign("ticker_price",$ticker_price);
{/php}
Stock Name: {$ticker_name} Stock Price: {$ticker_price} |
就像Smarty 1.5.0,这里有一种更清晰的方法。你可以在你的模板里使用{include_php ...}这些标签来包含php。使用这种方法,你能够保持PHP的逻辑性和模板的逻辑性分离。参照include_php 这个函数来获得更多信息。
例 18-8. 使用include_php组合的模板
load_ticker.php ---------------
// setup our function for fetching stock data function fetch_ticker($symbol,&$ticker_name,&$ticker_price) { // put logic here that fetches $ticker_name // and $ticker_price from some resource }
// call the function fetch_ticker("YHOO",$ticker_name,$ticker_price);
// assign template variables $this->assign("ticker_name",$ticker_name); $this->assign("ticker_price",$ticker_price); ?>
index.tpl ---------
{* Smarty *}
{include_php file="load_ticker.php"}
Stock Name: {$ticker_name} Stock Price: {$ticker_price} |
7、Obfuscating E-mail Addresses拒绝电子邮件地址
你想知道你的电子邮件地址是怎样出现在如此众多的猎头邮件列表中吗?猎头们收集电子邮件地址的一种方式就是从网页上获取。为了对抗这种方式,你可以让你的电子邮件在HTML源文件中以动态javascript的方式显示,这样在浏览器里就能正确的显示出来。这个是通过maito插件做到的。
例 18-9. 拒绝电子邮件地址的一个例子
index.tpl ---------
Send inquiries to {mailto address=$EmailAddress encode="javascript" subject="Hello"} |
技术提示:这种方法不是100%安全的。一个猎头可能知道编写他的电子邮件收集器来解码,但不是很可能的。