在網站開發過程中模版引擎是必不可少的,PHP中用的最多的當屬Smarty了。目前公司系統也是用的Smarty,如果要新增一個頁面只需把網站的頭、尾和左側公共部分通過Smarty的include方式引入進來,然后主體部分寫內容即可,用起來也是相當方便。這也是一種比較通用的做法。但維護一段時間后發現有些凌亂了:
1. 公共部分內容越加越多了,不需要用的js、css在一些頁面也被強制引進來了
2.新頁面的css只能寫在網頁的body內,看起來總讓人不爽。
3.左側、頭部、尾部若有特殊顯示,操作起來不方便,只能在公共地方去做判斷了。
當然這些頁面問題在設計的時候可以通過合理的拆分網頁來實現,當然最重要的還在於開發人員,在好的系統也經不起開發人員的折騰,一個項目經過多次轉手后,接下來的維護人員那是相當痛苦的。不扯遠了, 現在要說的是另一種模版開發思路。
在PHP中CLASS用過很多次了,有一個很有用的特性那就是繼承,子類繼承父類后可以直接調用父類的方法,也可以對父類的方法進行重寫,同樣PHP的模版引擎Twig也實現了這一點,模版的書寫方式可以更方便。
Twig是開源框架Symfony2的默認模版引擎,主頁是http://twig.sensiolabs.org/ 當前版本為Stable: 1.12.1 ,其他模版引擎能做的它都能做,這里主要整理下使用Twig的BLOCK方式編寫模版頁面。
以一個常見的排版為例,有三個鏈接,分別是首頁、關於、聯系三個頁面,然后頭部共用,尾部共用,中間部分分成左右兩部分,左邊共用,右邊顯示具體內容,貌似很多后台都是這種布局。
先看看首頁 twig_index.php , 和Smarty差不多,初始化設置,然后設置變量並顯示。
1
2
3
4
5
6
7
8
9
10
11
12
|
<?php
require
'./Twig-1.12.1/lib/Twig/Autoloader.php'
;
Twig_Autoloader::register();
$loader
=
new
Twig_Loader_Filesystem(
'./view/twig/templates'
);
$twig
=
new
Twig_Environment(
$loader
,
array
(
'cache'
=>
'./view/twig/templates_c'
,
'auto_reload'
=> true
));
$twig
->display(
'index.html'
,
array
(
'name'
=>
'Bobby'
));
?>
|
其他頁面的PHP內容除了模版名稱不一樣外,其他內容完全一樣,所以后面的PHP頁面就不寫了。
那接下來的主要工作就是寫模版了,既然支持繼承,那應該有一個父類,其他頁面來繼承這個類。base.html就是模版的父類,其內容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
{# /view/twig/templates/base.html #}
<!DOCTYPE html>
<
html
>
<
head
>
<
title
>{% block title %}Home{% endblock %} - Twig</
title
>
<
style
type
=
"text/css"
>
{% block stylesheet %}
#header, #main, #footer{width:600px; margin:0px auto; border:1px solid #333;}
#main{border:0px;}
#header { height:120px;margin-bottom:10px;}
#footer{ height:80px;clear:both;margin-top:10px;}
#header h1{margin-left:20px;}
#header span{margin-left:20px;}
#leftsider{width:125px; float:left; border:1px solid #333; height:200px;
padding-top:10px;}
#leftsider span{width:100%; height:30px; line-height:30px; clear:both;
padding-left:15px; display:block;}
#rightsider{width:460px; float:right; border:1px solid #333; height:250px;}
.clear{clear:both;}
{% endblock %}
</
style
>
</
head
>
<
body
>
<
div
id
=
"header"
>
<
h1
>Twig Template Test</
h1
>
<
span
><
a
href
=
"twig_index.php"
>Home</
a
></
span
>
<
span
><
a
href
=
"twig_about.php"
>About</
a
></
span
>
<
span
><
a
href
=
"twig_contact.php"
>Contact</
a
></
span
>
</
div
>
<
div
id
=
"main"
>
<
div
id
=
"leftsider"
>
{% block leftsider %}
<
span
>系統模塊1</
span
>
<
span
>系統模塊2</
span
>
{% endblock %}
</
div
>
<
div
id
=
"rightsider"
>
{% block rightsider %}Hello {{name}}{% endblock %}
</
div
>
</
div
>
<
div
class
=
"clear"
></
div
>
<
div
id
=
"footer"
>
{% block footer %}<
h1
>Twig Footer</
h1
>{% endblock %}
</
div
>
</
body
>
</
html
>
|
基本的頁面框架沒太多說的,主要看看中間有5個block - {% block blockname%}{% endblock %} 每個BLOCK代表一個塊, 這里的塊可以理解成PHP父類中的一個方法。
基本的html框架搭好后,index.html該如何來寫呢?首先該繼承base頁面,然后再考慮是否要重寫base頁面的內容,先只做繼承看看效果。
1
2
|
{# /view/twig/templates/index.html #}
{% extends "base.html" %}
|
第一行為注釋部分,可以省去,第二行表示index.html繼承base.html, 未重寫的情況下將直接使用base.html中的內容進行顯示,也就是該頁面將看到如下效果:
效果比較簡單,但是很神奇,index.html只是繼承了base.html,沒寫其他內容呢?對,不用寫了,在未重寫父類方法時。子類是可以直接調用父類方法的。
那接着看看about, 假設about頁面和index頁面除了右邊區域不同外,其他部分完全相同,也就是只需要重寫rightsider這個BLOCK:
1
2
3
4
|
{# /view/twig/templates/about.html #}
{% extends "base.html" %}
{% block title %}About{% endblock %}
{% block rightsider %} {% include 'about_content.html' %} {% endblock %}
|
標題的內容改成了 About, rightsider的內容從about_content.html文件中讀取,其他部分保留原有。也就是除了Hello Bobby的內容不同外,其他部分與首頁都是相同的,是不是覺得很方便了?
再來看一下Contact頁面怎么寫?我么需要在leftsider里增加一個菜單,以及rightsider里顯示其他block的內容。看看下面:
1
2
3
4
5
|
{# /view/twig/templates/contact.html #}
{% extends "base.html" %}
{% block title %}Contact{% endblock %}
{% block leftsider %}{{ parent() }}<
span
>系統模塊3</
span
>{% endblock %}
{% block rightsider %} {{ block('footer') }} {% endblock %}
|
調用parent即可顯示基類的內容,通過block('footer')則可獲取footer中的Twig Footer內容。所以圖片效果如下:
很神奇吧!這種排版方式值得一試,等待機會中...
使用block后子頁面不可以按照html的方式在任意地方加html, 也就是在block外寫任何內容都會報錯,所以需要base里去合理的設置block,block設置的越多就越靈活。具體的還得到實際項目中去嘗試。
至於Twig的具體語法有時間在整理下,不過這種寫模版的方式確實很讓人喜歡,好像Smarty3也支持該功能了,有時間也看看。
看到Twig后聯想到了 lesscss, 動態樣式語言,主頁http://www.lesscss.net 有興趣的朋友可以看看。
--EOF--