PHP模版引擎 – Twig


在網站開發過程中模版引擎是必不可少的,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中的內容進行顯示,也就是該頁面將看到如下效果:
twig-1

效果比較簡單,但是很神奇,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內容。所以圖片效果如下:

twig-2

很神奇吧!這種排版方式值得一試,等待機會中...
使用block后子頁面不可以按照html的方式在任意地方加html, 也就是在block外寫任何內容都會報錯,所以需要base里去合理的設置block,block設置的越多就越靈活。具體的還得到實際項目中去嘗試。

至於Twig的具體語法有時間在整理下,不過這種寫模版的方式確實很讓人喜歡,好像Smarty3也支持該功能了,有時間也看看。

看到Twig后聯想到了 lesscss, 動態樣式語言,主頁http://www.lesscss.net 有興趣的朋友可以看看。

 

--EOF--


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM