php 原生 实现模板继承,谈谈模板继承思想的实现(以freemarker为例)

一、什么是模板继承

模板继承不同于模板布局,甚至来说,应该在模板布局的上层。模板继承其实并不难理解,就好比类的继承一样,模板也可以定义一个基础模板(或者是布局),并且其中定义相关的区块(block),然后继承(extend)该基础模板的子模板中就可以对基础模板中定义的区块进行重载。

或者更确切的比喻,模板继承更像是java中的implement,而不是extent,尽管在大量php、python、ruby框架中称之为:template extend。

因此,模板继承的优势其实是设计基础模板中的区块(block)和子模板中替换这些区块。每个区块由标签组成(thinkphp为例),并且不支持block标签的嵌套。

模板继承,已广泛使用于诸如php、python、ruby等web框架中,但早先的模板如jst、ftl等并不原生支持模板继承。

二、为什么要考虑模板继承

首先对比一下几乎所有渲染模板都有的,模板布局。用流行性语言描绘,模板布局的思想,是一种不带交互的组件化思想。

模板布局应用最为广泛,譬如php中的require、freemarker中的macro - 、django中的{% include };用前端的模板加以对比,则如jst、regular中的。其核心思想即将大部分页面的公共部分进行拆分,通过在不同页面中组装,达到模板复用的目的。

例如:

6f4661a62c3daa1aa4f9984606509694.png

这种模板布局的思想,可以解决大多数的问题,但是如果有大量同类页面,但每个页面又有些许差异时,这种模板组件的组装就逐渐体现成一种体力活。

首先各个组件是耦合在最终生成的模板页面中的,譬如以下的代码逻辑:

内容 。。。。。。

内容 。。。。。。

那么每修改内容部分就需要格外小心,不要误动了include组件。当然也可以把内容部分抽离出来单独封装成模板组件,组合载入。

另一个可以体现大量复用思想的场景(仅举例而已):业务有多个子应用,每个应用的首页基本结构相近,但是又各有差异。另外每个应用会有不同变化位置的广告位

70e0d49b2bdee8d967bfaa07743febb6.png

那么使用常规思路就是分别为应用设计A、B、C三个页面(每个相互独立,引入组件),每个页面分别要include各自所需的组件(如图1号页面、2号页面等),当有广告活动时,需要再在A、B、C三个页面中添加对应的广告(可能是在页面中加入广告锚点),然后定义广告组件include进去。等到活动结束再把对应的广告锚点撤销。

那么再来对比使用模板继承的情形:

首先需要定义基类模板,诸如base.html

A、B、C三个页面继承于base.html,只需要重新定义A、B、C的差异部分

如A模板(只需引入差异部分,无需引入1号页面、3号页面等):

{% extend base.html %}

{% block %}

A页面逻辑

{% block %}

{% include 2号页面组件 %}

同时A、B、C的带广告页面又继承于A、B、C,如A的活动模板:

{% extend A.html %}

{% block %}

{% include广告1 %}

{% block %}

将广告逻辑与A页面逻辑剥离开,且切换方便,代码复用性强。对比于原来可能需要在A页面基础上添加广告位置(撤掉又需要在A页面上删除)或者拷贝A页面在改写(大量的代码冗余),相当便利。

模板继承的思想并不是抛弃原有的模板组件的使用,而是在其上做了加强,对于有大量同构页面,将模板继承和模板组合的思想灵活应用,必定事半功倍。

三、Thinkphp、django(python)中的模板继承

1.Thinkphp中的模板继承

例如基模板:

1.

2.

3.

4.标题

5.

6.

7.菜单

8.左边分栏

9.主内容

10.右边分栏

11.底部

12.

13.

对应继承模板:

1.

2.{$title}

3.

4.首页

5.资讯

6.论坛

7.

8.

9.

10.

11.{$vo.title}

12.{$vo.content}

13.

14.

15.

16.最新资讯:

17.

18.{$new.title}

19.

20.

21.

22.@ThinkPHP2012版权所有

23.

2.Django中的模板继承使用

{%extends"base.html"%}

{%blocktitle%}Articles for{{year}}{%endblock%}

{%blockcontent%}

Articles for{{year}}

{%forarticleinarticle_list%}

{{article.headline}}

By{{article.reporter.full_name}}

Published{{article.pub_date|date:"F j, Y"}}

{%endfor%}

{%endblock%}

四、Freemarker实现模板继承

Freemarker并不原生支持模板继承,但他具有完善的模板组件,称之为宏(macro)。而我们可以基于宏来实现模板继承。

首先,我们探究一下什么是继承的核心?

我理解的继承就是子类拥有父类所以的方法、特性,同时子类又可以重写父类的这些特性与方法,并拥有自己独特的方法。

那么如果freemark的“基模板”本身就是一个宏,且可以同时内嵌组件化的宏呢?

诸如:

#macro>

那么子类继承父类只需要重写其所不同的部分,如

#macro>

那么即实现了对base的继承,同时定义了子模板自己的差异。其他不原生支持模板继承思想的模板体系,也可以参考。

注意:模板继承的思想并不是抛弃原有的模板组件的使用,而是在其上做了加强,对于有大量同构页面,将模板继承和模板组合的思想灵活应用,必定事半功倍!

参考示例:

django模板继承:http://python.usyiyi.cn/django/intro/overview.html#design-your-templates

thinkphp模板继承:http://www.thinkphp.cn/info/178.html

本文来自网易实践者社区,经作者陈盛授权发布。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值