建立模板标签系统应用程序只需几个步骤.
注意:以下步骤假设使用了新的SleeK例子应用程序(这个例子可以在www.phpmvc.net上找到).
修改应用程序的boot.ini文件
应用程序的boot.ini文件包含需要得到PHP.MVC框架的信息.boot.ini文件通常位于应用程序的"WEB-INF"目录下.为了设置应用程序使用模板标签类,我们需要在boot.ini文件中定义一些属性.
TagActionDispatcher类
TagActionDispatcher是ActionDispatcher类的标准实现.为了让框架能读取TagActionDispatcher类,我们为变量$appServerRootDir设置值为'TagActionDispatcher':
// Setup the application specific ActionDispatcher (RequestDispatcher)
$actionDispatcher = 'TagActionDispatcher';
模板标签系统库根目录
我们也需要设置路径指向我们的PHP.MVC库(需要文件系统的绝对路径):
// Set php.MVC library root directory (no trailing slash).
$appServerRootDir = 'C:\WWW\phpmvc-base';
可选设置
应用程序定时器可以使用$timerRun属性来设置开或关:
// Timer reporting. 1=on, 0=off
$timerRun = 1;
还可以指导框架总是(强制)编译应用程序phpmvc-config.xml配置类(最好用在开发阶段,因为会比较慢),我们使用:
// The application XML configuration data set:
$appXmlCfgs = array();
$appXmlCfgs['config'] = array('name'=>'phpmvc-config.xml', 'fc'=>True);
或者仅在phpmvc-config.xml文件被修改的时候重新编译应用程序配置文件(在开发完成后使用此项设置,速度快),我们使用:
// The application XML configuration data set:
$appXmlCfgs = array();
$appXmlCfgs['config'] = array('name'=>'phpmvc-config.xml', 'fc'=>False);
设置应用程序模板目录
当为模板标签应用程序设置模板目录时,我们需要去创建一个目录(和子目录),放置我们的应用程序模板文件.这个目录必须被命名为在View资源配置类的$tplDir属性所定义的值,默认是'./WEB-INF/tpl'.比如:例子应用程序有一个模板目录结构设置像这样:
- PhpMVC-Tags
Index.html
Main.php
WEB-INF
tpl
pageFooter.ssp
pageHeader.ssp
salePageBody.ssp
sale
pageContent.ssp
我们也需要去创建目录放置编译的页面.这个目录必须被命名为在View资源配置类的$tplDirC属性所定义的值.默认是'./WEB-INF/tpl_C'.例子应用程序有一个模板目录结构设置像这样:
PhpMVC-Tags
Index.html
Main.php
WEB-INF
tpl
...
sale
...
tpl_C
pageFooter.sspC
pageHeader.sspC
salePageBody.sspC
sale
pageContent.sspC
注意我们也需要在'./WEB-INF/tpl_C'下创建sale目录.
设置PHP.MVC库的路径和包含
检查以下路径设置已经被定义在GlobalPaths.php和globalPrepend.php文件在你的框架安装目录下的"/WEB-INF"目录下:
GlobalPaths.php
------------------------------------------------
$appDirs[] = 'WEB-INF/lib/phpmvc_tags';
globalPrepend.php
------------------------------------------------
include_once 'PhpMVC_Tags.php';
如果他们没有在添加到路径里,那么就定义这些变量.
安装PHP.MVC库
下载最新版的PHP.MVC库:http://www.phpmvc.net/download/cvsIdx.php?doc=cvs-snaps
解压库文档到一个目录.修改上面所描述过的路径设置和包含设置.
运行例子应用程序
下载例子应用程序.完整的例子代码文件和这个向导都能在这里下载:http://www.phpmvc.net/download/rel/phpmvc-tags-v1.0.zip
解压到web服务器目录中.可能像这样:C:/WWW/PhpMVC-Tags
修改应用程序和框架设置.
为了测试例子程序,需要浏览器例子程序的首页:http://localhost/PhpMVC-Tags/Index.html
附录A:ViewResources配置类
ViewResourcesConfig类表现了<view-resource>元素的配置信息.
下表列出了ViewResourcesConfig类的属性,条目描述和默认值:
在这个单元中我们将看到如何使用模板标签系统构造一个标准的模板页面。这个例子我们使用了一个简单的HTML页面布局,请看下图:
这个页面有多个标准单元组成,就像页面设计者和开发者熟悉的那样.这个页面的主体由3个包含的单元组成:页眉,页内容主体和页脚.我们现在就看看这些单元并且了解如何使用模板标签系统来实现.
页主体
下面的代码单元显示的是主体:
The Page Body Layout
1
<@ saleMonth = data.getValueBean('SALE_MONTH') @>
<@ saleTitle = data.getValueBean('SALE_TITLE') @>
<@ dealHeading = data.getValueBean('DEAL_HEADING') @>
<@ salesAreaID = "Central District" @>
<html>
<head>
<link rel='stylesheet' type='text/CSS' href="/blog_article/style/pageStyles.css"/>
<title>
2 <@ =viewConfig.getAppTitle @>
</title>
</head>
<body>
<table >
<!-- PAGE HEADER -->
<tr>
<td >
<!-- including the page header component -->
<!-- The base template base directory is "./tpl" -->
3 <@ include 'pageHeader.ssp' @>
</td>
</tr>
<!-- PAGE CONTENTS -->
<tr valign='top'>
<td >
<!-- including the page contents component -->
4 <@ include 'sale/pageContent.ssp' @>
</td>
</tr>
<!-- PAGE FOOTER -->
<tr>
<td >
<!-- including the page footer omponent -->
5 <@ include 'pageFooter.ssp' @>
</td>
</tr>
</table>
</body>
</html>
1:页声明
第一个有趣的条目是页顶部的页声明(1).我们在页面开始声明了这些变量,因此这些变量将能在下面的页面和像页眉那样的包含页所使用.
2:页标题
下一步我们使用表达式来初始化页面标题(2).这个值能够从配置文件中view-resources元素利用ViewResourcesConfig->getAppTitle来得到:
<view-resources
appTitle = "Flash Jacks' Sleek Tab Site"
...
</view-resources>
3:页眉
页眉是下一个有趣的条目(3).在这里我们使用包含指令来插入页眉模板文件到页主体中.我们将在下一个子单元中来看一看页眉.
我们仅仅使用了页面直接去读取页眉,不论页的组件存储在哪里.这是一个好机会来介绍模板标签系统的目录设置.默认情况下,模板目录布局如下所示(注意这些路径相对于我们的应用程序):
The Default PhpMVC_Tags Template Directory Layout Paths (relative)
The Template Files './WEB-INF/tpl'
The Compiled Template Files './WEB-INF/tpl_C'
如果需要的话我们可以在配置文件的view-resources结点来重新定义他们,就像这样:
<view-resources
...
tplDir = "./WEB-INF/tpl-admin"
tplDirC = "./WEB-INF/tpl_admin_C"
...
</view-resources>
4:页内容主体
这是另外一个包含指令被用来插入模板文件(4)到主体中.注意包含的文件位于模板目录的sales子目录中:
"./WEB-INF/tpl/sale/pageContent.ssp"
5:页脚
又是一个包含指令,就像页眉一样.
页眉单元
在这个例子中页眉模板文件('pageHeader.ssp')只是一个简单的单元,就像这样:
<!-- Page Header -->
<span>
<@ =viewConfig.getAppTitle @>
</span>
当主体页面(包括包含的页面)被编译的时候,页眉的表达式被转换成下面这样:
<!-- Page Header -->
<span>
<?php print $viewConfig->getAppTitle(); ?>
</span>
被编译的页面被存储在编译模板目录中,就像上面所说的,默认的编译模板目录是:
'./WEB-INF/tpl_C'
页内容主体单元
页内容主体模板文件有一点复杂.文件('sale/pageContent.ssp')内容显示如下:
...
1
<@ item1=data->getValueBean("ITEM_1") @>
<@ products=data->getValueBean("PRODUCTS_ARRAY") @>
2
<h4><@=dealHeading @> <@=saleMonth @></h4>
3
<b>Clearance deals</b>
<table >
<tr>
<td >
<@ =item1.getName @>
</td>
<td >
<@ =item1.getCost @>
</td>
</tr>
</table>
4
<b>Todays specials</b>
<table >
<?php foreach($products as $item) { ?>
<tr>
<td >
<@ =item.getName @>
</td>
<td >
<@ =item.getCost @>
</td>
</tr>
<?php } ?>
</table>
<b>Our Staff at Your Service</b>
...
5
<table >
<tr>
<td >
<b>Area Manager: </b>
</td>
<td >
<@ =viewConfig.getAreaManager @>
</td>
</tr>
...
</table>
1:一些更多的声明
在页面顶部所显示的额外声明(1)能让我们声明页变量以便下面能够使用.在内容被处理之后,这些声明将在编译后像下面这样显示:
<?php $item1=$data->getValueBean("ITEM_1"); ?>
...
<?php $products=$data->getValueBean("PRODUCTS_ARRAY"); ?>
2:使用表达式来显示内容单元标题
现在我们使用两个表达式(2)来显示内容单元的标题.注意我们声明这些变量是"全局"变量在主页面的顶部.处理完后,表达式将转换这些代码,就像这样:
<?php print $dealHeading; ?> <?php print $saleMonth; ?>
当页面被显示到用户的浏览器中,内容单元的标题看起来就像这样:
Jack's Super Deals for : May 2010.
3:使用表达式来显示一些数据条目
现在我们能显示一些实际的数据(3).在这个页内容主体单元中我们访问一些在PhpMVCTabAction类的ActionObject中的产品条目数据.一个简化版的PhpMVCTabAction类在下面展示:
class PhpMVCTabAction extends Action {
...
function execute($mapping, $form, &$request, &$response) {
// Our value bean container
$valueBeans =& new ValueBeans();
// Define some strings we need on our View template page
// These could be defined globally in the phpmvc-config.xml file.
// See: ExtendedController example.
$appTitle = "Flash Jack's Include Page";
$saleMonth = "May 2010";
$saleTitle = "Flash Jack's Super Sale";
$dealHeading = "Jack's Super Deals for :";
...
// Save the string variables to our Value object
$valueBeans->addValueBean('APP_TITLE' , $appTitle);
$valueBeans->addValueBean('SALE_MONTH' , $saleMonth);
$valueBeans->addValueBean('SALE_TITLE' , $saleTitle);
$valueBeans->addValueBean('DEAL_HEADING' , $dealHeading);
...
// Some float values we could receive from a database query
// Note: The prices are formatted in the Products class constructor.
// Eg: "$ n,nnn.nn"
$price1 = 125.00;
...
// Setup some clearance deals (individual object instances):
// Note: The Product class file was included in our local prepend.php file
$item1 = new Product('Super Duper', $price1);
...
$valueBeans->addValueBean('ITEM_1', $item1);
...
// Todays specials (array of object instances)
$products = array();
$products[] = new Product('Gooses Bridle', $price3);
...
$valueBeans->addValueBean('PRODUCTS_ARRAY', $products);
// Our staff
$staff1 =& new Staff('Bruce', 'Sales', 'Karate');
...
$valueBeans->addValueBean('STAFF_1', $staff1);
...
// Save the Value object
$this->saveValueObject($request, $valueBeans);
在上面的代码中,我们能看到$item1被创建并被保存成ActionObject的valueBeans条目.Bean数据条目现在能在模板页面中被重新获得:
<@ item1=data->getValueBean("ITEM_1") @>
我们可以像下面那样显示条目的值:
<@ =item1.getName @>
...
<@ =item1.getCost @>
4:显示数组
我们也可以直接使用一些PHP代码在我们的模板页上.在这个分离的MVC模式中,我们应该仅在这里编写代码去操纵这些通过ActionObject和ViewResourcesConfig实例(可能我们的自定义Bean也可以)提供的数据.在上面的也内容单元('sale/pageContent.ssp')中,我们使用一个PHP的foreach语法(4)来循环读取$products数组.我们能在上面的PhpMVCTabAction类中看到$products数组被创建并被保存在ActionObject中,就和上面的$item1 Bean相似.在foreach循环中我们能使用表达式来显示产品数据:
<?php foreach($products as $item) { ?>
<tr>
<td >
<@ =item.getName @>
</td>
<td >
<@ =item.getCost @>
</td>
</tr>
<?php } ?>
5:显示ViewResourcesConfig属性
最后我们从view-resources元素所定义的ViewResourcesConfig属性来显示"Area Manager"(5)在我们的内容页:
<view-resources
appTitle = "Flash Jacks' Sleek Tab Site"
...
className = "MyViewResourcesConfig">
<!-- We can set some properties on our custom ViewResourcesConfig class -->
<set-property property="areaManager" value="Joe J. Blogs Esq."/>
</view-resources>
但是注意在这个例子中我们使用了一个继承ViewResourcesConfig类的对象(MyViewResourcesConfig)来设置一些自定义的属性.我们定义了一个扩展ViewResourcesConfig类的对象,在配置文件里使用className="MyViewResourcesConfig"属性,并且MyViewResourcesConfig类定义在文件"MyViewResourcesConfig.php"中.MyViewResourcesConfig类(classes/MyViewResourcesConfig.php)实现了setter/getter方法去处理自定义属性("areaManager"),这个属性我们在view-resources结点中定义:
class MyViewResourcesConfig extends ViewResourcesConfig {
// ----- Properties ----------------------------------------------------- //
var $areaManager = '';
function getAreaManager() {
return $this->areaManager;
}
function setAreaManager($areaManager) {
$this->areaManager = $areaManager;
}
我们现在能使用表达式在我们的页面上实现"Area Manager"了:
<@ =viewConfig.getAreaManager @>
注意:在真实的应用程序中数据能从关系型数据库中得到.
页脚单元
页脚单元和上面讨论过的页眉单元的处理相类似.页脚模板文件('tpl/pageFooter.ssp')就像这样:
<!-- Page Footer -->
<span>
<@ =viewConfig.getCopyright @>
</span>
当主体页面(包括包含的页面)被编译,在页脚中的表达式被转换成下面这样:
<!-- Page Footer -->
<span>
<?php print $viewConfig->getCopyright(); ?>
</span>
编译的页眉页面被存储在编译模板目录.默认的编译模板目录是:
'./WEB-INF/tpl_C'
在基本的介绍之后,我们现在就可以来看看模板标签系统的语法.
在看具体的标签之前,我们应该定义什么作为我们的标签.为了写一个标签,我们使用<@ ... @>标签结点.左标签(<@)和右标签(@>)是默认的标签.如果必要的话,这些标签我们能够在phpmvc-config.xml中重新定义.
模板标签系统现在支持以下3种标签:包含指令,声明和表达式.我们现在来看看这些指令.
包含指令
包含指令能让我们将内容分隔为许多模块,比如:页眉,页脚或者内容.包含的页面可以是HTML,或者其他标签模板页.据个例子,下面的包含指令能用来包含一个页眉:
<@ include 'pageHeader.ssp' @>
一个包含指令在模板上下文种的例子:
<html>
<head>
...
</head>
<body>
<center>
<table >
<tr>
<td >
<@ include 'pageHeader.ssp' @>
</td>
</tr>
<!-- PAGE CONTENTS -->
...
<!-- PAGE FOOTER -->
...
</table>
...
</center>
</body>
</html>
在这里例子种pageHeader.ssp页眉文件内容将被插入到主页面上当这个页面被发送到用户浏览器上.这个页眉文件包含了一个表达式:
<!-- Page Header -->
<span>
<@ =viewConfig.getAppTitle @>
</span>
这个表达式将被编译并且将在运行时输出为:
<!-- Page Header -->
<span>
Flash Jacks' Sleek Tab Site
</span>
声明
声明允许我们在模板种声明一个页面级别的变量,或者甚至其他包含页面.一个声明看起来像以下代码:
<@ salesAreaID = "Central District" @>
我们能够在模板文件中使用声明:
<@ saleMonth = data.getValueBean('SALE_MONTH') @>
<@ saleTitle = data.getValueBean('SALE_TITLE') @>
<@ dealHeading = data.getValueBean('DEAL_HEADING') @>
<@ salesAreaID = "Central District" @>
<html>
<head>
<link rel='stylesheet' type='text/CSS' href="/blog_article/style/pageStyles.css"/>
<title>
...
</title>
</head>
<body>
...
</body>
</html>
在这里例子中,我们声明了一些页变量.前3个变量已经在我们创建的Action类中的ActionObject中被赋值:data.getValueBean('SALE_MONTH').第4个变量被赋了一个字符串值:salesAreaID = "Central District".
声明的变量现在可以在页面中使用了:
<!-- start_page_contents_include -->
...
<!-- Content section heading -->
<h4><@=dealHeading @> <@=saleMonth @></h4>
<center>
Clearance deals
<table >
...
</table>
</center>
<center>
Todays specials
<table >
...
</table>
</center>
...
<!-- end_page_contents_include -->
这些页变量将被输出为:
<!-- Content section heading -->
<h4>Jack's Super Deals for : May 2010</h4>
...
...
表达式
表达式标签允许我们在模板页中执行表达式.表达式的结果将被包含进模板页.以下表达式将被用来显示一个简单的字符串(salesAreaID),也可以找回框架配置类的属性:
<@ =salesAreaID @>
<@ =viewConfig.contactInfo @>
为了使用这些表达式,我们要在之前声明过:
<@ salesAreaID = "Central District" @>
或者在ViewResourcesConfig对象(viewConfig)的属性在view-resources结点中声明过:
<view-resources
appTitle = "Flash Jacks' Sleek Tab Site"
contactInfo = "flash.jack@jackshost.com"
...
</view-resources>
当使用表达式中的对象时,我们能够写一个对象-方法(object-method)声明在标准的PHP符号或者点风格的符号:
The PhpMVC_Tags Object-Method Notation
PHP Style sales = data->getSales
Dot Style sales = data.getSales
With Method Params staff = data.getValueBean("STAFF")
Retrieve Data Array products = data->getValueBean("PRODUCTS_ARRAY")
在下一个单元我们将看到如何使用模板标签系统将这些结合在一起来构建页面.