iT邦幫忙

DAY 24
12

逐步提昇PHP技術能力系列 第 24

逐步提昇PHP技術能力 - 逐步改善軟體架構 - 使用樣板引擎

今天的大事是:PHP官網(www.php.net)被認為有malware,所以一些瀏覽器上不去。不過據Rasmus Lerndorf在twitter上發的消息看來,這很可能是一個false alert。(我上去看了據稱有問題的網頁,並沒有google webmaster工具上說的問題耶???)

廢話不多說,今天來嘗試一下,怎樣使用樣板引擎,以及他可以帶來怎樣的方便性。
參考:http://twig.sensiolabs.org/

其實PHP本身也可以算是一個樣板語言,而且不需要像樣板語言那樣還需要經過一次編譯才能使用(通常還是編譯成PHP)。那為什麼還要使用樣板語言呢?

首先,還是要讓操作介面的構成方式進一步抽象化。以twig來說,他可以利用樣板的繼承,讓頁面layout與內容的呈現更有組織。通常在設計頁面時,都會規劃好各個區塊的用途,有一些是共通的,有一些會隨著功能而有變化,有些地方則是做內容的呈現。規劃好這些部分以後,就可以根據這些區塊,做出頁面的layout模版。之後各個頁面則繼承這個模版,填入各個部分的內容。如果外觀有調整而功能區塊不變,也可以直接修改layout,不需要動到各個頁面的樣板。

其實是語法上,樣板引擎會提供比PHP更簡潔的樣板語言,可以直接插入在html中,不需要像php這樣切出一些程式區塊,從html加工也比較快。(其實見仁見智)另外,針對頁面資料的一些格式轉換等,樣板語言可以用更簡潔的語法達成,節省一些開發時間。

在套用twig之前,先來觀察一下之前做出來的layout:

首頁:

進入論壇:

可以看出,layout大概可以分成幾個部分:

  1. 標題與導覽(麵包屑),會隨著進入不同地方而有變化
  2. 登入登出,這是共用的
  3. 內容
  4. 頁尾

由於不能簡單地切成頁首、內容、頁尾,如果是用像smarty這樣的樣板引擎,處理起來會有點麻煩...如果要使用twig來做,在layout中就可以切出麵包屑與內容這兩個區塊,然後在各頁面的樣板中填入這兩個區塊的內容。

twig可以使用composer來安裝,所以就先加入composer.json:

{
    "require": {
        "twig/twig":"1.*"
    }
}

然後用composer install指令來安裝twig。安裝完twig之後,在程式中把vendor/autoload.php引入,就可以使用twig了。

在使用前,先把index.php會使用到的layout以及內容樣板做出來:

樣板名稱叫做base.html吧:

	<table width="800" border="1" cellpadding="0" cellspacing="0" align="center">
		<!-- header start -->
		<tr>
			<th align="left">{% block navbar %}{% endblock %}</th>
		</tr>
		<tr>
			<td style="text-align:right" bgcolor="#336699">
				<table align="right">
					<tr>
{% if member %}
						<td>Welcome [{{name}}] <button onclick='document.location.href="logout.php"'>登出</button></td>
{% else %}
						<form method="post" action="login.php">
							<td>登入後可留言  </td>
							<td>帳號</td>
							<td><input type="text" name="account"></td>
							<td>密碼</td><td><input type="password" name="password"></td>
							<td><input type="submit" value="登入"></td>
						</form>
{% endif %}
					</tr>
				</table>
			</td>  
		</tr>
		<!-- header end -->
		<!-- content start-->
		<tr height="600">
			<td valign="top">
				{% block content %}{% endblock %}
			</td>
		</tr>
		<!-- content end -->
		<!-- footer start -->
		<tr bgcolor="#336699">
			<td align="center">
				<font color="#EFEFEF">Copyright 1899  by Fillano</font>
			</td>
		</tr>
		<!-- footer end -->
	</table>
<script>
{% if message %}
	alert('{{message}}');
{% endif %}
</script>

然後index.php用到的樣板,就是index.html了:

{% extends "base.html" %}
{% block navbar %}我的論壇{% endblock %}
{% block content %}
				<table width="100%" border="1" cellspacing="0" cellpadding="5">
					<tr bgcolor="#DDEEFF">
						<th>論壇名稱</th>
						<th>文章數</th>
						<th>最新文章</th>
						<th>操作</th>
					</tr>
{% for row in data %}
					<tr bgcolor="{{row.style}}">
						<td>{{row.name}}</td>
						<td>{{row.count}}</td>
						<td>{{row.title}}</td>
						<td>
							<button onclick="document.location.href='forum.php?id={{row.id}}'">進入</button>
						</td>
					</tr>
{% endfor %}
				</table>
{% endblock %}

index.php也要調整,首先還是include 'vendor/autoload.php',然後就可以使用twig來載入樣板:

<?php
session_start();
include 'vendor/autoload.php';
if(isset($_SESSION['user']['account'])) {
	$member = true;
	$name = $_SESSION['user']['name'];
} else $member = false;
$conn = mysql_connect('localhost', 'root', '');
if(!$conn)
	die('mysql connection error.');

mysql_select_db('myforum');
if(isset($_SESSION['msg'])) {
	$message = mysql_real_escape_string($_SESSION['msg']);
	unset($_SESSION['msg']);
}
$sql = "SELECT f.*,count(a.forums_id) AS count  FROM forums f LEFT JOIN articles a ON a.forums_id = f.id GROUP BY a.forums_id ORDER BY f.id";
$result = mysql_query($sql, $conn);
$count = 0;
$data = array();
while($row = mysql_fetch_array($result)) {
	if($count%2==0) {
		$style = "#EEFFEE";
	} else {
		$style = "#FFFFFF";
	}
	$sql = "SELECT * FROM articles WHERE forums_id=".$row['id']." ORDER BY id DESC LIMIT 1";
	$result1 = mysql_query($sql, $conn);
	$row1 = mysql_fetch_array($result1);
	$data[] = array('id'=>$row['id'], 'name'=>$row['name'], 'count'=>$row['count'], 'title'=>$row1['title'], 'style'=>$style);
	$count++;
}
#include 'views/index.php';
Twig_Autoloader::register();
$loader = new Twig_Loader_Filesystem('views');
$twig = new Twig_Environment($loader, array('cache'=>'cache'));
$template = $twig->loadTemplate('index.html');
echo $template->render(array(
	'member'=>$member,
	'data'=>$data,
	'name'=>$name,
	'message'=>$message
));
?>

基本上程式除了開始時加入autload,然後註解掉include 'views/index.php',之後就是從twig的範例中稍微抄一下載入樣板的程式碼。

回到瀏覽器,打開首頁操作一下:頁面看起來跟之前一樣,登入、登出、進入論壇都可以正常操作,這樣就順利完成把首頁套用twig的工作了。

其他頁面,就慢慢再來修改。即使還沒改,目前也完全不影響操作跟功能,所以可以一小步一小步前進。


上一篇
逐步提昇PHP技術能力 - 逐步改善軟體架構 - 分離出頁面的邏輯
下一篇
逐步提昇PHP技術能力 - 逐步改善軟體架構 - 建立簡單的View
系列文
逐步提昇PHP技術能力30

1 則留言

我要留言

立即登入留言