在网站开发过程中模版引擎是必不可少的,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--

PHP模版引擎 – Twig的更多相关文章

  1. PHP模版引擎twig wordpress中调用文章第一张图片

    wordpress当文章没有添加Featured media的时候, 就调用文章第一张图片, 调用的wordpress代码函数为: <?php echo catch_that_image(); ...

  2. 构建自己的PHP框架--构建模版引擎(1)

    前段时间太忙,导致好久都没有更新博客了,今天抽出点时间来写一篇. 其实这个系列的博客很久没有更新了,之前想好好规划一下,再继续写,然后就放下了,今天再捡起来继续更新. 今天我们来说一下,如何构建自己的 ...

  3. Symfony2模版引擎使用说明手册

    一.基本使用 {{ demo }}输出一个demo变量; {% func %}通常是包含一个twig函数例如 for; 举个for循环的例子: {% for i in 0..10 %} <em& ...

  4. Smarty模版引擎的原理

    Smarty是一个使用php写出来的模版引擎,用来将原本与html代码混杂在一起PHP代码逻辑分离,实现前后端分离. Smarty模板优点: 1. 速度:采用Smarty编写的程序可以获得最大速度的提 ...

  5. js模版引擎handlebars.js实用教程——为什么选择Handlebars.js

    返回目录 据小菜了解,对于java开发,涉及到页面展示时,比较主流的有两种解决方案: 1. struts2+vo+el表达式. 这种方式,重点不在于struts2,而是vo和el表达式,其基本思想是: ...

  6. 简单JavaScript模版引擎优化

    在上篇博客最简单的JavaScript模板引擎 说了一下一个最简单的JavaScript模版引擎的原理与实现,作出了一个简陋的版本,今天优化一下,使之能够胜任日常拼接html工作,先把上次写的模版函数 ...

  7. Asp.net NVelocity 模版引擎

    NVelocity.dll是Java中常用的一个模版,下面是常用的模版引擎 1,返回string类型的html代码 /// <summary> /// 获取html模版 /// </ ...

  8. Nodejs学习笔记(五)--- Express安装入门与模版引擎ejs

    目录 前言 Express简介和安装 运行第一个基于express框架的Web 模版引擎 ejs express项目结构 express项目分析 app.set(name,value) app.use ...

  9. T4教程1 T4模版引擎之基础入门

    T4模版引擎之基础入门   额,T4好陌生的名字,和NuGet一样很悲催,不为世人所熟知,却又在背后默默无闻的奉献着,直到现在我们项目组的人除了我之外,其它人还是对其豪无兴趣,基本上是连看一眼都懒得看 ...

随机推荐

  1. java实现httpclient 访问

    package com.test; import java.io.File; import java.io.FileInputStream; import java.io.IOException; i ...

  2. Web前端入门了解

    Web就是指万维网,网站,Web开发的方向包括Web前端,Web后台. Web前端又分为  静态Web 和 动态Web, 静态Web就是用HTML实现的. 动态Web的实现方式有多种. 动态Web的实 ...

  3. matlab实现感知机算法--统计学习小灶

    clear all; clc; %% %算法 %输入:训练数据集T = {(x1,y1),(x2,y2),...,(xn,yn)};学习率η %输出:w,b;感知机模型f(x) = sign(w*x+ ...

  4. C#预编译指令之#region

    #region和#endregion是一个区域注释(注释一段话.但是不是AU3内置的语法.内置的注释是 ";" 和 "#cs" 与 "#ce" ...

  5. ssm(spring,springmvc,mybatis)

    1.配置web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app version=&qu ...

  6. 在POM 4中,<dependency>中还引入了<scope>可以使用5个值

     在POM 4中,<dependency>中还引入了<scope>,它主要管理依赖的部署.目前<scope>可以使用5个值: * compile,缺省值,适用于所有 ...

  7. Intellij快捷键

  8. 为什么高手离不了Linux系统?这就是我的理由

    摘要: 通过本文来记录下我在Linux系统的学习经历,聊聊我为什么离不了Linuxx系统,同时也为那些想要尝试Linux而又有所顾忌的用户答疑解惑,下面将为你介绍我所喜欢的Linux系统,这里有一些你 ...

  9. Java设计模式系列1--原型模式(Prototype Method)

    2014-02-14 11:27:33 声明:本文不仅是本人自己的成果,有些东西取自网上各位大神的思想,虽不能一一列出,但在此一并感谢! 原型模式,从名字即可看出,该模式的思想就是将一个对象作为原型, ...

  10. HTML新增属性

    1.<input type="text" required必填  placeholder="默认显示内容"  autofocus自动获取焦点 /> ...