Blitz Templates

Blitz Templates-应用于大型互联网项目的非常强大非常快的模板引擎。

 

下载: sourceforge, 源代码 主页win32 二进制文件, 其他语言: 俄罗斯语

Blitz 项目还处于一个十分活跃的发展阶段, 每周都有可能出现新的版本。 如果你想 获取新版本的公告 - 请 在 freashmeat上订阅订阅sourceforge 上的RSS。如果你喜欢这个项目并想提供帮助 - 我们非常乐意为任何建设性的建议开放。我们一直在寻找能够进行国际翻译的人员 (主要是 德语,西班牙语和法语)。如果您能提供帮助,请联系 。

文档编制: Alexey Rybak, Lioubov Vereschagina, Vladimir Krivosheev

文档翻译:Gray

反馈:通过邮件列表联系开发人员和用户(blitz-subscribe@alexeyrybak.com) 或访问 BugTraker

这是一个完整的文档。 Blitz为您准备了一个节省时间的短暂“奇幻之旅”

目录

简介和快速开始

看到该文档的第一时间,你最可能问的问题是: "什么?还有另外一个模板引擎?做什么的?"。 这是一个非常简短的说明。

Blitz 作为一个模板引擎有三个特征:

Ÿ   它是最快的模板引擎之一,它是由C编写的,并被编译为PHP 的扩展模块来使用

Ÿ   它有简洁和清晰的语法

Ÿ   以上二个特点让开发者得以编写紧凑和易读代码来实现非常复杂的逻辑应用

大部分的模板策略并不能阻止开发者写出一塌糊涂的代码,这显然是令人相当不愉快的。而Blitz 项目最主要的目标是帮助开发者开发出简洁而轻快的PHP 项目,并且能迅速解决非常复杂和具有很多用户自定义(比如web2.0)的应用难题。

Blitz的基本概念就是: Web应用视图层基于两部分:视图控制器,自定义的PHP对象封装了大多数的没有HTML代码的视图逻辑,使得模板变简单灵活,此模板内容包括所有的HTML代码、模板变量和简单逻辑,包括 用户的方法请求包括简单有条件输出。这个简单的逻辑思想来自一个非常简单的途径,脱胎于大型互联网开发应用。这种思想可以防止混乱并能够保证变更到你的项目中而没有太大的压力...

Ÿ   你的PHP代码(即使是在视图层) 不应混合使用HTML代码并且你的HTML也不应混合使用PHP代码。 Blitz 使得开发人员能够分离PHP代码到模板控制器文件中。分离HTML代码到模板文件中,不允许有任何PHP代码在模板文件中,在PHP代码中也没有必要加入 HTML代码。

Ÿ   有时候想要在模板中使用逻辑是非常困难的,但是现在你有存在另一种混乱的危险 - 模板逻辑混合着HTML (像Smarty-混乱仍存在于一些项目中) 代替了PHP混乱,这些情形同样的难看。Blitz 允许在模板中使用弱逻辑,但这一逻辑很简单足以令其中的代码保持可读状态。

此外Blitz支持一种基于子模板的Context策略 - 嵌入一个模板到另一个当中,如此使很多功能复杂的模板变简化了。在大多数上下文环境下有助于创造非常快的应用。

解释这一切只是为了 - 让我们深入这些例子,说明我们现在所谈论的是什么。想象我们有一个非常简单的页面, 其中有一个默认的header,footer和一系列因为一些特性而被标记为“new”的新闻。我们将展示两个使用Blitz的实例:一个使用了context一个不使用, 第一个是没有使用context的。我们将使用一个模板控制器和4个模板文件: main template, item template,header 以及 footer。

main template (main.tpl) :

<html>

<head><title>{{ $title }}</title></head>

<body>

{{ include('header.tpl') }}

{{ list_news() }}

{{ include('footer.tpl') }}

</body>

</html>

这里的 {{ $title }} 是一个没实际意义的变量输出,"include"是一个引用操作,假设它们在模板中都是可用的。我们将省略页眉和页脚的细节-只要注意,他们会被解析并且从我们的main模板引用list_news模板控制器提供的自定义方法:

/* controller class */

class View extends Blitz {

var $news = array();

function View($tmpl_name) {

return parent::Blitz($tmpl_name);

}

function set_news($data) {

$this->news = $data;

}

function list_news() {

$result = '';

foreach($this->news as $i_news) {

$result .= $this->include('news_list_item.tpl', $i_news);

}

return $result;

}

}

/* new data, 在实际应用中数据来自数据库或其他地方 */

$news = array(

array('name' => 'My Bonnie lies over the ocean', 'is_new' => 0),

array('name' => 'My Bonnie lies over the sea', 'is_new' => 1)

)

/* 输出 */

$T = new View('main.tpl');

$T->set_news($news);

$T->set(array('title' => 'Blitz Example'));

echo $T->parse();

这里的“View”是main模板的控制器类,继承自Blitz,在Blitz扩展中定义。我们使用父类提供的初始化控制器,设置一组数据和请求解析的方法。 Main template 有一个 用户方法的调用 - {{ list_news() }}。这个方法由一个模板控制器提供。它使用news数据建立一个新闻列表,然后将列表的每一项加入到引用的模板中。请注意你需要使用括号才能使用这个方法 {{ list_news() }},{{ list_news }}相当于{{ $list_news }}。 返回的变量是一个HTML字符串,用于代替在main.tpl中的{{ list_news() }}。Include方法由父类提供。

以下是该实例的模板, new_list_item.tpl:

<b>{{ $name }}</b>{{ if($is_new, '<div class="isNew">NEW!</div>') }}<br>

这里的 $name 和 $is_new 是模板变量, 来自list_news的关联数组 $i_news: $name 只是插入到HTML中,而 $is_new 是一个 条件输出。 如此在这个实例中我们对模板控制器方法的调用引用模板条件输出 有了一个更加直观的了解。

第二个实例演示了使用contexts该如何处理。 让我们重写 main template ,格式如下:

<html>

<head><title>{{ $title }}</title></head>

<body>

{{ include('header.tpl') }}

{{BEGIN news_list_item}}<b>{{ $name }}</b>{{ if($is_new, '<div class="isNew">NEW!</div>') }}<br>{{ END }}

{{ include('footer.tpl') }}

</body>

</html>

我们从 news_list_item.tpl 中获取代码并插入到 main template - 插入到一个名为news_list_item 的context 中。现在我们可以重写控制器。在这里我不需要任何用户自定义方法,这就是为什么我们可以只使用 Blitz 对象:

/* news data, in real applications comes from database or somewhere else */

$news = array(

array('name' => 'My Bonnie lies over the ocean', 'is_new' => 0),

array('name' => 'My Bonnie lies over the sea', 'is_new' => 1)

)

/* the output */

$T = new Blitz('main.tpl');

$T->set(array('title' => 'Blitz Example'));

foreach($news as $i_news) {

$T->block('/news_list_item', $i_news);

}

echo $T->parse();

这里我们使用block 方法去 循环 内容。这些内容通过循环数组的每一项并使用相对路径 '/news_list_item'标识。所有$i_news数组的数据项插入到context中,而且所有的逻辑工作跟上一个实例一样。通常只要你喜欢,你就可以嵌套多层contexts,这个嵌套层次是无限的。从理论上来说,处理任何复杂的逻辑,可能都只需要contexts-只需要从控制器代码中将其中一个context切换到另一个。详细的做法可以在后面的内容中找到。

这是一个快速应用、HTML与PHP分离的简单明晰的模板:

Ÿ   输出变量

Ÿ   呼叫控制器方法并输出结果

Ÿ   引用另外的模板

Ÿ   从控制器定义子模板入口(我们将使用 "iterate  context"组合)

Ÿ   使用简单的“ if ”语句输出一些常数字符串

其实这些例子过于简单,不能让我们发现亮点(没有一个你没有听到过)。但是现在你的项目开始发展,你必须作出很多改变,当你的逻辑变的非常复杂 - 这种分离才起到了真正的帮助。我不喜欢遵循传统和在这里对其他的产品作详细研究。不管怎样说,如果您在一个有效的大项目设法使用纯的PHP而没有任何其他的东西 – 恭喜,你是非常幸运的。如果您的最有效的(从性能角度)途径仍然无法满足您的需求,那么请试试Blitz吧,也许你会感受到惊喜。

警告

Blitz 项目还处于一个半成品状态,但是0.5.7版本还是比较稳定的,可以在您的项目中放心使用。但是100 %的稳定和向后兼容性不能保证到1.0版。

安装

Blitz 是一个PHP的扩展,请下载 源代码, (Win32 用户可以下载 编译了的DLL)。

解压源代码包,并按如下步骤编译:

tar zxvf blitz.tar.gz

cd blitz

phpize

./configure

make

make install

测试Blitz请运行脚本run-tests.sh。

注意! 你需要根据具体环境改变文件中的路径才能进行正常的 运行测试,运行这个测试你可能会得到如下的内容:

fisher@fisher:~/prj/blitz> ./run-tests.sh

=====================================================================

CWD         : /home/fisher/prj/blitz/tests

PHP         : /usr/local/bin/php

PHP_SAPI    : cli

PHP_VERSION : 4.3.10

ZEND_VERSION: 1.3.0

PHP_OS      : Linux - Linux fisher 2.6.11.4-20a-smp #1 SMP Wed Mar 23 21:52:37 UTC 2005 i686

INI actual  : /usr/local/lib/php.ini

More .INIs  :

Extra dirs  :

=====================================================================

Running selected tests.

PASS contexts [context.phpt]

PASS errors and warnings: syntax [errors1.phpt]

PASS errors and warnings: execution [errors2.phpt]

PASS fetch#1 [fetch1.phpt]

PASS fetch#2 [fetch2.phpt]

PASS fetch#3 [fetch3.phpt]

PASS has context [has_context.phpt]

PASS predefined methods: if [if.phpt]

PASS predefined methods: include [include.phpt]

PASS ini-values settings test [ini.phpt]

PASS user-defined methods [method.phpt]

PASS method call from inner include [mfi.phpt]

PASS mix #1 [mix1.phpt]

PASS mix #2 [mix2.phpt]

PASS mix #3 [mix3.phpt]

PASS mix #4 [mix4.phpt]

PASS mix #5 [mix5.phpt]

PASS mix #6 [mix6.phpt]

PASS expect regexp test [regex.phpt]

PASS returning non-strings from user methods [return_non_string.phpt]

PASS set and get [set_and_get.phpt]

PASS variables [var.phpt]

如果Blitz是以共享模块编译的,您可能需要编辑php.ini,将Blitz写入扩展列表:

extension=blitz.so

Blitz已经在 Linux 2.6 (i386) 和 Windows XP上测试通过。

配置

Blitz 需要改变 php.ini 或者调用 ini_set() 配置三个参数:

Ÿ   blitz.tag_open  开始标记, 默认为 "{{"

Ÿ   blitz.tag_close  结束标记, 默认为 "}}"

Ÿ   blitz.var_prefix  变量标识, 默认为 "$"

小例子:如果要输出模板中的变量$test,你需要将以下代码加入你的模板:{{ $test }} 。

额外的配置参数:

Ÿ   blitz.phpt_ctx_left  替换 (旧版 php_templates) 开始标记, 默认为 "<!-- "

Ÿ   blitz.phpt_ctx_right  替换 (旧版 php_templates) 结束标记, 默认为 " -->"

Ÿ   blitz.path - 默认模板路径 (如果应用中的模板路径不是以‘ / ’开始,将使用默认模板路径)

Ÿ   blitz.disable_include - 禁用include ,值域:0或1,默认为 0

Ÿ   blitz.remove_spaces_around_context_tags  - 移除context周围空格,0/1,默认为 0 (即将改变为 1!)

基础: 变量, 方法, contexts

Blitz基于两点建立:模板控制器。模板是包含 Blitz 代码的HTML文件;控制器是由PHP扩展提供的基于Blitz类的控制模板。

变量

下面是一个关于变量如何工作的详细例子:

main.tpl

Variables test: {{ $a }} and {{ $b }}, iteration number: {{ $i }}

test.php

$T = new Blitz('main.tpl');

$i = 0;

$i_max = 10;

for ($i = 0; $i<$i_max; $i++) {

echo $T->parse(

array(

'a' => 'var_'.(2*$i),

'b' => 'var_'.(2*$i+1),

'i' => $i

)

);

}

输出

Variables test: var_0 and var_1, iteration number: 0

Variables test: var_2 and var_3, iteration number: 1

Variables test: var_4 and var_5, iteration number: 2

Variables test: var_6 and var_7, iteration number: 3

Variables test: var_8 and var_9, iteration number: 4

Variables test: var_10 and var_11, iteration number: 5

Variables test: var_12 and var_13, iteration number: 6

Variables test: var_14 and var_15, iteration number: 7

Variables test: var_16 and var_17, iteration number: 8

Variables test: var_18 and var_19, iteration number: 9

你同样可以在模板中使用复杂的变量:

class DummyObjWithSubProperty {

var $sub;

function DummyObjWithSubProperty($val) {

$this->sub = array('key' => $val);

}

}

$data = array(

'hash' => array(

'subhash' => array(

'key' => 'v1'

),

),

'obj' => new DummyObjWithSubProperty('v2')

);

$T = new Blitz();

$T->load('Array: {{ $hash.subhash.key }}, Object: {{ $obj.sub.key }} ');

echo $T->parse($data);

输出

Array: v1, Object: v2

用户方法

用户方法就是 "callbacks"。用户方法是一个很简单的概念:你的控制器类有一些方法,这些方法可以在模板使用。你要做到这些必需扩展Blitz基础类 - 下面有个简单的例子:

main.tpl

user method call test: {{ my_test(); }}

test.php

class View extends Blitz {

function my_test() {

return 'user method called ('.__CLASS__.','.__LINE__.')';

}

}

$T = new View('main.tpl');

echo $T->parse();

 

输出

user method call test: user method called (View,5)

请注意, {{ my_test }} 代码虽然没有圆括号但相当于 {{ $my_test }}, 并且 my_test方法不会被调用。

Contexts

想要理解Blitz,那么你就必须要理解contexts 和 iterations。它们在Blitz中的意义太大了。

Contexts在Blitz v 0.4中加入, 最初的contexts概念来自 php_templates, 但是context logic已经被修订过。在这里做了些简要说明。通常我们有“清晰的”模板。这些模板有一些变量或一些操作符或调用 - 但是在模板中的任何程序代码块都将被执行。Contexts 包含了子模板, 他们的代码是按需求使用的。看如下PHP代码:

variable: <?=$a?>, method: <?=b()?>

all of these pieces of code will be executed. Now look at the following Blitz code

variable: {{ $a }}, method: {{ b(); }}, context: {{ BEGIN ctx }} something inside {{ $something }} {{ END }}

这里的 “ ctx ” 就是 context, 他没有使用默认值 - 这一切输出将以“context:”结束。在控制器中使用context需要对它进行 循环(迭代)

$T = new Blitz('main.tpl');

$T->iterate('ctx');

echo $T->parse();

如果context只是循环一次 - context执行结果将在指定的范围内输出。如果context循环多次 - context执行结果将多次在指定范围内出现。当然,每次循环的变量是可以不同的。因此,我们只需要建立每次循环数据项的简单清单列表:

$T = new Blitz('main.tpl');

while($i++<10) {

$T->iterate('ctx', array('something' => 'something_'.$i));

}

echo $T->parse();

最强大的特点是contexts能互相依附(can be enclosed in each other)。每个context都使用它的路径定义 - 如“ /ctx ”在上面的例子中。使用路径 “/root/node/item” 的Contexts依附在路径为 “/root/node”的Context下,而以“/root/node”定义的Context又依附在以“/root”定义的Context下。你可以使用一些参数循环父级, 此时子级使用其他的参数,然后再次循环到父级再到子级。从理论上来讲,任何页面,任何复杂的逻辑都可以使用contexts建立一个简单的模板。某个列表是一组context的循环器。那么子列表则是子context的一组循环器(List is a set of context iterations. Sublists are iterations of subcontexts.)。在控制器中可以用有条件的循环器代替模板中有条件的输出。

这里有两个contexts的基本操作:设置当前的contexts并循环该context。设置意味着所有请求将以默认的设置影响到该context。这是一个很好的处理一类工作的命令:设置当前context到 /root/node/item 实际上就像是对/root/node/item 目录执行了一个“cd”命令,而循环就像是执行了命令“execute” 。

Context的命名是大小写敏感的。你可以使用两种格式设置context的路径:

Ÿ   绝对路径, /root/node/item

Ÿ   相对路径, node/item 或 ../item

所有的Blitz功能,比如 includeif或者method call可以在context中使用而没有任何限制。

最后,这里有几个context的使用例子。接下来代码会输出众所周知的问候,它隐藏在三个嵌套的context里:

main.tpl

{{ BEGIN root }}

{{ BEGIN node }}

{{ BEGIN item }}

hello, world

{{ END }}

{{ END }}

{{ END }}

php code

$T = new Blitz('main.tpl');

$T->iterate('/root/node/item');

echo $T->parse();

输出

hello, world

下一个例子说明如何建立简单的清单列表。

main.tpl

{{ BEGIN row }}row #{{ $i }}

{{ END }}

php code

$T = new Blitz('main.tpl');

$max_num_list = 5;

// use context & iterate

$T->context('row');

for($i=0; $i < $max_num_list ; $i++) {

$T->iterate();

$T->set(array('i' => $i));

}

// or just use block

for($i=0; $i<$max_num_list; $i++) {

$T->block('/row',array('i' => $i));

}

echo $T->parse();

输出

row #0

row #1

row #2

row #3

row #4

row #0

row #1

row #2

row #3

row #4

block()、 iterate() 、set() 都是一些非常有用的嵌套替代语句,他们经常一起使用。Contexts默认设置中,父级context变量在子级中是“看不见”的,所以你需要 “传递” 这些变量到子级context中。或者,您可以使用setGlobals方法将这些变量设置成全局变量,这种设置变量并不是真正的设置为全局模板变量。

下一步例子表明如何建立复杂的清单 :

main.tpl

{{ BEGIN list; }}

list #{{ $list_num }}

{{ BEGIN list_empty; }} this list is empty {{ END }}{{ BEGIN list_item; }} row #{{ $i_row; }}

{{ END }}

{{ END }}

php code

$T = new Blitz('main.tpl');

$max_num_list = 5;

$max_num_item = 5;

$T->context('/list');

for($i=0; $i<$max_num_list; $i++) {

$T->block('',array('list_num' => $i));

$is_empty = $i%2; // emulate empty sub-lists

if($is_empty) {

$T->block('list_empty');

} else {

for($j=0; $j<$max_num_item; $j++) {

$T->block('list_item',array('i_row' => $i.':'.$j));

}

}

}

echo $T->parse();

输出

list #0

row #0:0

row #0:1

row #0:2

row #0:3

row #0:4

list #1

this list is empty

list #2

row #2:0

row #2:1

row #2:2

row #2:3

row #2:4

list #3

this list is empty

list #4

row #4:0

row #4:1

row #4:2

row #4:3

row #4:4

嵌套了contexts的单模板可以适用于任何视图逻辑。Contexts是非常强大的,在复杂的工程项目适用于所有开发人员。

注意:大多数批评意见都基于如下的一些观点:“我们为什么要将我们的一些PHP代码做成模板?这种模式是错误的, 所有的逻辑必须在模板包装”。恕我直言(IMHO), 这一观点是不正确的。让我们回到主要问题:为什么我们要分离。你的视图逻辑必须从代码中分离,你的HTML不应该和PHP代码混合在一起。没有人说你的逻辑必须全部在模板中。contexts语句唯一的缺点就是你虽能把很多的contexts语句嵌套使用,但这会使你的contexts和你的iterations(迭代器)混乱一团。这样会使代码不再简单明了。

IF/UNLESS blocks 提醒 - 此功能需要记载的细节。 Header/footer/empty 模式例子:

{{ IF list }}

<table>

{{ BEGIN list }}

<tr><td>{{ $some }}</td></tr>

{{ END }}

</table>

{{ END }}

{{ UNLESS list }}

Fuck it, Dude, let's go bowling

{{ END }}

模板 API

下面的内部方法可以再模板中使用:

Ÿ   if  条件输出

Ÿ   include  引用其他模板

Ÿ   escape  HTML输出封装(类似htmlspeclalchars)

Ÿ   date  日期输出封装

if

(blitz >= 0.1)

if-根据判断选择性输出

string if (string predicate , string output_true [, string output_false ] )

main.tpl

{{ $num }}. {{ $name }} {{ if($rip,'[R.I.P.]') }}

php code

$T = new Blitz('main.tpl');

$character = array(

array(1,'The Dude',0),

array(2,'Walter Sobchak',0),

array(3,'Donny',1),

array(4,'Maude Lebowski',0),

array(5,'The Big Lebowski',0),

array(6,'Brandt',0),

array(7,'Jesus Quintana',0),

);

foreach ($character as $i => $data) {

echo $T->parse(

array(

'num' => $data[0],

'name' => $data[1],

'rip' => $data[2]

)

);

}

输出

1. The Dude

2. Walter Sobchak

3. Donny [R.I.P.]

4. Maude Lebowski

5. The Big Lebowski

6. Brandt

7. Jesus Quintana

这是if的短格式使用例子.

include

(blitz >= 0.1)

include  引用外部模板

string include ( string template_name)

1.tpl

Where's the {{ include('2.tpl') }} Lebowski?

2.tpl

money

php code

$T = new Blitz('tpl');

echo $T->parse();

echo "\n";

输出

Where's the money Lebowski?

变量的作用域范围非常简单:全局变量可以在引用的所有模板中使用, 本地变量则不能。

escape

(blitz >= 0.4.4)

escape - HTML输出封装

php code

$T = new Blitz();

$T->load('{{ escape($a); }}

{{ escape($b) }}

{{ escape($c,"ENT_COMPAT") }}

');

$T->set(

array(

'a' => "this is 'a' \"test\"",

'b' => '<a href="null">',

'c' => '<>@#$%^&*()_=\'"'

)

);

echo $T->parse();

 

输出

this is 'a' &quot;test&quot;

&lt;a href=&quot;null&quot;&gt;

&lt;&gt;@#$%^&amp;*()_='&quot;

date

(blitz >= 0.4.11)

date - 日期封装

string date(string format [, mixed arg])

{{ date(FORMAT [, ARG]); }} 将返回一个使用指定格式字符串格式过后的日期字符串。当 [ARG] 是数字时, 它被视为UNIX的时间戳整数。此外 [ARG] 被有许多日期格式的PHP内部函数“php_parse_date”解析。 当参数[ARG] 省略时 - 将返回当前日期时间。格式字符串与 PHP 函数“strftime”具有相同的转换效果。

php code

$body = <<<BODY

{{ date("%d %m %Y %H:%M:%S",\$time_num); }}

{{ date("%d %m %Y %H:%M:%S",\$time_str); }}

BODY;

$T = new Blitz();

$T->load($body);

$time_num = mktime(11, 22, 33, 7, 22, 1976);

$time_str = '1976-07-22 01:02:03';

$T->set(array(

'time_num' => $time_num,

'time_str' => $time_str

));

echo $T->parse();

 

输出

22 07 1976 11:22:33

22 07 1976 01:02:03

控制器 API

Blitz class methods:

Ÿ   block  设置当前context并且循环

Ÿ   clean  清除context: 清除iterations和/或变量

Ÿ   context  设置当前context (并返回上一次的设置的内容)

Ÿ   getContext (get_context)  返回当前context

Ÿ   dumpIterations (dump_iterations)  销毁所有模板iterations

Ÿ   getIterations (get_iterations)  获取所有模板iterations,返回一个数组

Ÿ   dumpStruct (dump_struct)  销毁模板structure

Ÿ   getStruct (get_struct)  获取模板structure,返回一个数组

Ÿ   fetch  创建context并获取结果

Ÿ   hasContext (has_context)  检查context是否已经存在

Ÿ   include  引用其他的模板

Ÿ   iterate  循环context

Ÿ   load  从一个PHP字符串加载模板的body

Ÿ   parse  输出并返回结果

Ÿ   set  设置变量或iterations

Ÿ   setGlobals (set_globals)  设置全局变量

Ÿ   getGlobals (get_globals)  获取全局变量,返回一个数组

block

(blitz >= 0.4)

block  设置当前context并且循环

bool block ( string context_path [, array parameters ] )

main.tpl

{{BEGIN welcome}}

Hello, {{$object}}!

{{END}}

php code

$Template = new Blitz('tpl');

$Template->block('welcome', array('object' => 'world'));

echo $Template->parse();

输出

Hello, world!

clean

(blitz >= 0.4.10)

clean  清除context的iterations和变量

bool clean ([string context_path ], [bool warn_notfound])

$Tpl->clean($path) 清除context的iterations和参数。参数 $path 默认为 “root”(‘ / ’);$Tpl->clean() 不带参数时会操作模板的所有变量和iterations。第二个参数告诉Blitz,当在方法执行过程中没有找到iteration时是否报出PHP警告, 默认为true。

php code

$body = <<<BODY

================================

context cleaning ({{ \$var }})

================================

<!-- BEGIN a -->context (a)

{{ \$va }}

<!-- BEGIN b -->context (b)

{{ \$vb }}

<!-- END b -->

<!-- END -->

BODY;

$T = new Blitz();

$T->load($body);

$T->set(array('var' => 'Hello, World!'));

$T->block('/a', array('va' => 'va_value'));

$T->block('/a/b', array('vb' => 'vb_value'));

echo $T->parse();

$T->clean('/a/b');

echo $T->parse();

$T->clean('/a');

echo $T->parse();

$T->block('/a', array('va' => 'va_value_new'));

$T->iterate('/a/b');

echo $T->parse();

$T->clean();

echo $T->parse();

输出

================================

context cleaning (Hello, World!)

================================

context (a)

va_value

context (b)

vb_value

================================

context cleaning (Hello, World!)

================================

context (a)

va_value

================================

context cleaning (Hello, World!)

================================

================================

context cleaning (Hello, World!)

================================

context (a)

va_value_new

context (b)

================================

context cleaning ()

================================

context, getContext

(blitz >= 0.4)

context  设置当前context

bool context (string context_path )

getContext  获取当前context

string getContext (void)

main.tpl

{{BEGIN user}}

{{BEGIN hello}}Hello, user!{{END}}

{{BEGIN goodbye}}Goodbye, user!{{END}}

{{END}}

{{BEGIN world}}Hello, world!{{END}}

php code

$Template = new Blitz('main.tpl');

echo 'previous context was: '$Template->context('user')."\n";

echo 'current context is: '$Template->getContext()."\n";

$Template->block('hello');

$Template->block('goodbye');

$Template->block('../world');

echo $Template->parse();

输出

previous context was: /

current context is: /user

Hello, user!

Goodbye, user!

Hello, world!

dumpIterations (dump_iterations)

(blitz >= 0.4)

dumpIterations(dump_iterations)  卸载iterations, 调试方法

bool dumpIterations

main.tpl

{{BEGIN counter}}

{{$i}},

{{END}}

php code

$Template = new Blitz('main.tpl');

for ($i = 0; $i < 3; $i++)

{

$Template->block('context', array('i' => $i));

}

$Template->dumpIterations();

输出

ITERATION DUMP (4 parts)

(1) iterations:

array(1) {

[0]=>

array(1) {

["context"]=>

array(1) {

[0]=>

array(1) {

["i"]=>

int(0)

}

}

}

}

(2) current path is: /

(3) current node data (current_iteration_parent) is:

array(1) {

[0]=>

array(1) {

["context"]=>

array(1) {

[0]=>

array(1) {

["i"]=>

int(0)

}

}

}

}

(4) current node item data (current_iteration) is:

empty

ITERATION DUMP (4 parts)

(1) iterations:

array(1) {

[0]=>

array(1) {

["context"]=>

array(2) {

[0]=>

array(1) {

["i"]=>

int(0)

}

[1]=>

array(1) {

["i"]=>

int(1)

}

}

}

}

(2) current path is: /

(3) current node data (current_iteration_parent) is:

array(1) {

[0]=>

array(1) {

["context"]=>

array(2) {

[0]=>

array(1) {

["i"]=>

int(0)

}

[1]=>

array(1) {

["i"]=>

int(1)

}

}

}

}

(4) current node item data (current_iteration) is:

empty

ITERATION DUMP (4 parts)

(1) iterations:

array(1) {

[0]=>

array(1) {

["context"]=>

array(3) {

[0]=>

array(1) {

["i"]=>

int(0)

}

[1]=>

array(1) {

["i"]=>

int(1)

}

[2]=>

array(1) {

["i"]=>

int(2)

}

}

}

}

(2) current path is: /

(3) current node data (current_iteration_parent) is:

array(1) {

[0]=>

array(1) {

["context"]=>

array(3) {

[0]=>

array(1) {

["i"]=>

int(0)

}

[1]=>

array(1) {

["i"]=>

int(1)

}

[2]=>

array(1) {

["i"]=>

int(2)

}

}

}

}

(4) current node item data (current_iteration) is:

empty

dumpStruct (dump_struct)

(blitz >= 0.4)

dump_struct  撤销模板structure

bool dumpStruct

main.tpl

{{BEGIN counter}}

{{$i}},

{{END}}

php code

$Template = new Blitz('main.tpl');

for ($i = 0; $i < 3; $i++)

{

$Template->block('context', array('i' => $i));

}

$Template->dumpStruct();

输出

== TREE STRUCT (2 nodes):

^-begin[22] (0(17), 32(27)); ARGS(1): counter(0); CHILDREN(1):

^-i[1] (19(0), 23(0));

== PLAIN STRUCT (2 nodes):

begin[22] (0(17), 32(27)); ARGS(1): counter(0); CHILDREN(1):

i[1] (19(0), 23(0));

fetch

(blitz >= 0.4)

fetch  获取context的结果

string fetch ( string context_path [, array parameters ])

main.tpl

{{ BEGIN online }} online! {{ END }}

{{ BEGIN offline }} was online {{ $n }} {{ BEGIN h }}hours{{ END }}{{ BEGIN d }}days{{ END }}{{ BEGIN m }}months{{ END }} ago {{ END }}

{{ BEGIN away }} away... {{ END }}

php code

$T = new Blitz('main.tpl');

// online

echo $T->fetch('online')."\n";

// away

echo $T->fetch('away')."\n";

$T->context('offline');

// 15 days ago

$T->iterate('d');

echo $T->fetch('offline', array('n' => 15))."\n";

// 2 months ago

$T->iterate('m');

echo $T->fetch('offline', array('n' => 2))."\n";

输出

online!

away...

was online 15 days ago

was online 2 months ago

hasContext (has_context)

(blitz >= 0.4)

hasContext (has_context)  检查context是否已经存在

bool has_context (string context_path)

main.tpl

{{BEGIN foo}}{{END}}

php code

$Template = new Blitz('main.tpl');

var_dump($Template->has_context('foo'));

var_dump($Template->has_context('bar'));

输出

bool(true)

bool(false)

include

(blitz >= 0.1)

include - 引用其他模板

string include(string template_name, [array global_vars])

php code

class View extends Blitz {

var $news = array();

function View($tmpl_name) {

return parent::Blitz($tmpl_name);

}

function set_news($data) {

$this->news = $data;

}

function list_news() {

$result = '';

foreach($this->news as $i_news) {

$result .= $this->include('news_list_item.tpl', $i_news);

}

return $result;

}

}

这里的list_news方法获取由 news_list_item.tpl 模板执行的结果, 在引用模板中将news数据作为全局变量传递。

Blitz 支持在context引用的模板中循环:

php code

$T = new Blitz();

$T->load('{{ include("include_ctx.tpl") }}');

$i = 0;

while ($i<5) {

$T->block('/test1', array('var' => $i), TRUE);

$T->block('/test2', array('var' => $i + 1), TRUE);

$i++;

}

echo $T->parse();

include_ctx.tpl

test1: {{ begin test1 }} v1={{ $var }} {{ end }}

test2: {{ begin test2 }} v2={{ $var }} {{ end }}

输出

test1:  v1=0  v1=1  v1=2  v1=3  v1=4

test2:  v2=1  v2=2  v2=3  v2=4  v2=5

注意, 我们在block方法中使用了额外的第三个参数。这个参数告诉Blitz循环 /test1 和 /test2 块,而不用检查context是否已经存在。“Include”在执行的时候被处理,这就是为什么在设置变量或循环context的时候,Blitz对引用的templates的结构一无所知。

iterate

(blitz >= 0.4)

iterate 循环context

bool iterate ( [ string context_path ] )

main.tpl

{{BEGIN hello}}

Hello, user!

{{END}}

{{BEGIN goodbye}}

Goodbye, user!

{{END}}

php code

$Template = new Blitz('main.tpl');

$Template->iterate('hello');

$Template->context('goodbye');

$Template->iterate();

echo $Template->parse();

输出

Hello, user! Goodbye, user!

load

(blitz >= 0.4)

load  从一个PHP字符串变量中加载模板body

bool load ( string tpl )

php code

$body = <<load($body);

echo $T->parse(array('who' => 'world'));

输出

hello, world!

Have a lot of fun!...

parse

(blitz >= 0.1)

parse  创建并返回结果

string parse ( [ array global_vars ] )

main.tpl

Hello, world!

php code

$Template = new Blitz('main.tpl'); echo $Template->parse();

输出

Hello, world!

在调用parse方法时传递的任何参数都会被加入到模板的全局变量中。

set

(blitz >= 0.1)

set  设置变量或iterations

bool set ( array parameters )

main.tpl

Hello, {{$object}}!

php code

$Template = new Blitz('tpl');

echo $Template->parse(array('object' => 'world'));

输出

Hello, world!

你同样可以使用“set”设置iterations。

main.tpl

{{BEGIN project}}

<project label="{{$url}}" data="{{$id}}"/>

{{END}}

php code

$data = array (

'project' => array(

0 => array('url' => 'a', 'id' => '1'),

1 => array('url' => 'b', 'id' => '2'),

2 => array('url' => 'c', 'id' => '3'),

)

);

$Template = new Blitz('tpl');

$Template->set($data);

echo $Template->parse();

输出

<projects>

<project label="a" data="1"/>

<project label="b" data="2"/>

<project label="c" data="3"/>

</projects>

$data数组中是3个context项目的iterations。该数据结构可以很复杂, 只要遵循如下规则:context迭代器的键名必须是数字,context和变量的名称必须是字符串。您可以编写这样的数据,并将其纳入模板而代替大量的context/iterate/set调用。很多时候非常有用 (参考实例PDO::fetchAll(PDO::FETCH_ASSOC)),并且在很多情况下非常快速敏捷(参考前卖弄的blitz ctx arrays例子).

setGlobals (set_globals), getGlobals (get_globals)

旧名称: setGlobal/set_global - 它们同样还可以使用

(blitz >= 0.4)

setGlobals  设置全局变量

bool setGlobals (array parameters)

getGlobals  获取全局变量,返回一个数组

array getGlobals (void)

main.tpl

I am {{$local}} variable.

I am {{$global}} variable.

{{BEGIN context}}

I am {{$local}} variable.

I am {{$global}} variable.

{{END}}

php code

$Template = new Blitz('main.tpl');

$Template->set(array('local' => 'local (root)'));

$Template->set_globals(array('global' => 'global'));

$Template->block('context', array('local' => 'local (context)'));

echo $Template->parse();

var_dump($Template->getGlobals());

输出

I am local (root) variable.

I am global variable.

I am local (context) variable.

I am global variable.

array(1) {

["global"]=>

string(6) "global"

}

 

getStruct (get_struct), getIterations(get_iterations)

getStruct  获取模板结构,返回数组

array getStruct(void)

getIterations  get template iterations as array

array getIterations(void)

php code

$Template = new Blitz();

$Template->load('{{ $var }} {{ BEGIN root }} {{ $root_var }} {{ END }}');

$Template->set(array('var' => 'value'));

$Template->iterate();//这行代码似乎没起作用

$Template->set(

array(

'root' => array(

'root_var' => 'root_value'

)

)

);

var_dump($Template->getStruct());

var_dump($Template->getIterations());

输出

array(3) {

[0]=>

string(4) "/var"

[1]=>

string(6) "/root/"

[2]=>

string(14) "/root/root_var"

}

array(2) {

[0]=>

array(1) {

["var"]=>

string(5) "value"

}

[1]=>

array(1) {

["root"]=>

array(1) {

["root_var"]=>

string(10) "root_value"

}

}

}

http://alexeyrybak.com/blitz/blitz_ru.html

http://alexeyrybak.com/blitz/win32-binaries/

Blitz Templates介绍的更多相关文章

  1. Android Studio快速开发之道

    概述 现如今开发越来越追求效率和节奏,节省出时间做更多的事情,除了开发技术上的封装等,开发工具的使用技巧也是很重要的,今天就根据自己的经验来给大家介绍一下Android Studio快速开发之道. P ...

  2. Android Studio 快速开发

    概述 现如今开发越来越追求效率和节奏,节省出时间做更多的事情,除了开发技术上的封装等,开发工具的使用技巧也是很重要的,今天就根据自己的经验来给大家介绍一下Android Studio快速开发之道. P ...

  3. Ansible之Playbook详解

    1.Playbook详解 playbook是一个非常简单的配置管理和多主机部署系统,可以定制配置,可以按照指定的操作步骤有序执行,支持同步和异步方式. 核心元素 Hosts:主机 Tasks:任务,由 ...

  4. Django基础配置

    安装djangopip install Django==1.11.4进入pythonimport django查看版本号django.get_version()创建项目,在合适位置创建一个目录进入你要 ...

  5. Django开发简单博客流程

    什么是Django? Django是一个基于python的高级web开发框架 它能够让开发人员进行高效且快速的开发 高度集成(不用自己造轮子), 免费并且开源 当前路径创建工程 django-admi ...

  6. django入门与实践(开)

    1.什么是Django? 基于python的高级web开发框架 高效 快速 免费 开源 正常上网流程 浏览器浏览网页的基本原理 请求响应过程 开发环境搭建 Python Django pip inst ...

  7. 007.OpenShift管理应用部署

    一 REPLICATION CONTROLLERS 1.1 RC概述 RC确保pod指定数量的副本一直运行.如果pod被杀死或被管理员显式删除,复制控制器将自动部署相应的pod.类似地,如果运行的po ...

  8. 1.介绍templates

    我们现在要计算int和double类型数据的平方,我们就需要2个函数: #include <iostream> using namespace std; int square(int x) ...

  9. DotNet Core 介绍

    前言 asp.net core rtm 6月底即将发布,自己也想着为社区做点共享,刚好最近不太忙,看到社区的小伙伴们都在为dotnet core的推广而贡献力量,项目中刚好在用rc2版本,就多写些文章 ...

随机推荐

  1. 重学STM32---(六)DAC+DMA+TIM

    这两天复习了DAC,DMA再加上把基本定时器TIM6和TIM7看了一下,打算写一个综合点的程序,,,就在网上找了一些关于DAC,DMA和定时器相关的程序,最终打算写了输出正弦波的程序... 由于没有示 ...

  2. 转:DateTime的灵活运用

    //2008年4月24日 System.DateTime.Now.ToString("D"); //2008-4-24 System.DateTime.Now.ToString(& ...

  3. Web 数据可视化

    /***************************************************************************************** * Web 数据可 ...

  4. java中replace和replaceAll的区别

    replace和replaceAll是JAVA中常用的替换字符的方法,它们的区别是: 1)replace的参数是char和CharSequence,即可以支持字符的替换,也支持字符串的替换(CharS ...

  5. DataTableToExcel

    public static string CreateExcel(DataTable dt, string FileName, string path, string columns)         ...

  6. 几个有用的SAP安全配置的用户参数配置列表

    转自http://blog.sina.com.cn/s/blog_4f913cf80100mksj.html Parameter Brief Description login/min_passwor ...

  7. html5之我見

    大多數知道html5的國人,不限於IT業內人員,對Html5存在較大誤解. 幾天前在新浪微博看到一個ID為"黑客師"的微博發佈了一張照片,名為"小白與高手的差別" ...

  8. jq 全选/取消效果

    //全选框$('#btnbutton').live('click',function(){ var data = $(this).attr('data'); if(data=='on'){ $(&qu ...

  9. 【转载】.NET(C#): Task.Unwrap扩展方法和async Lambda

    .NET(C#): Task.Unwrap扩展方法和async Lambda 目录 Task.Unwrap基本使用 Task.Factory.StartNew和Task.Run的Unwrap操作 使用 ...

  10. Android 客户端和服务器 json交互

    http://www.cnblogs.com/jyan/articles/2544974.html 1.JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式. ...