Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Smarty预渲染功能 #50

Closed
jinzhubaofu opened this issue Mar 9, 2015 · 2 comments
Closed

Smarty预渲染功能 #50

jinzhubaofu opened this issue Mar 9, 2015 · 2 comments

Comments

@jinzhubaofu
Copy link
Contributor

为什么需要预渲染模板?

moye广泛使用在中间页和卡片系统中,这两类页面对于性能要求非常高。在这种情况下,需要在尽可能早的时间点上提供用户正确和稳定的视觉展现。而使用js脚本来完成首屏元素的生成/渲染是不可取的。

因此,我们希望在组件的DOM是直接由smarty模板渲染完成的。我们通过实现一系列smarty函数来提供一种快捷实用的构建首屏控件dom。这样做有几个好处:

  1. 性能更好
  2. moye控件在页面中经常被重复使用多次,依照Don’t Repeat Yourself原则,我们应当把这些代码抽象出来,以减少重复代码,降低维护成本。
  3. moye控件内部结构复杂,手动编写其dom结构对于使用者而言是非常痛苦的。难以记忆的同时,使用者对于控件的内部dom结构的过度关注也违背了开闭原则。对于一个控件来讲,应当支持对它的扩展,而不是去修改它。

如何使用预渲染模板

首先,需要在smarty模板中引入我们提供的函数库,例如

{%include file="path/to/moye/tpl/Button.tpl"%}

其次,生成一个控件配置参数。例如从某个配置文件中读取:

// ui.json.tpl

{
  "btn": {
    "id": "btn",
    "type": "Button",
    "text": "test"
  }
}

// index.tpl
{%include file="path/to/moye/tpl/Button"%}
{%include file="./ui.json.tpl" assign="ui"%}
{%$ui = $ui|json_decode:true%}

由于我们的参数配置文件也是一个smarty模板,所以我们可以在这个文件中尽情使用smarty的各项功能。

例如:

{
  "btn": {
    "id": "btn",
    "type": "Button",
    "text": {%if $a > 100%}"test"{%else%}hello, world{%/if%}
  }
}

最后,通过下边这条语句就可以得到Buttondom结构了:

{%call Button data=$ui.btn%}

渲染的结果:

<button type="button" class="ui-button" data-ui-id="btn">test</button>

如何开发控件的smarty预渲染函数

原则上,我们只生成首屏可视元素,以及必要的属性。首屏不可见的元素(如浮层)可以交由javascript来完成渲染

我们提供了一个base.tpl的基础函数库,提供了一些基础的方法,例如:

  1. getPartClassName()等同于control.helper.getPartClassName()
  2. getStateClassName()等同于control.helper.getStateClassName()

小伙伴可以使用这两个函数来辅助构建自己的控件模板。

示例:Button模板函数

{%function name=Button%}{%strip%}
<button type="{%if isset($data.mode)%}{%$data.mode|escape:html%}{%else%}button{%/if%}"
    class="{%getPartClassName data=$data%}"
    {%if isset($data.id)%}data-ui-id="{%$data.id%}"{%/if%}
    {%if isset($data.disabled) and $data.disabled%}disabled="disabled"{%/if%}>
    {%$data.text|escape:none%}
</button>
{%/strip%}{%/function%}

PS: 目前我们采用的提供模板函数的方式来实现。在编写过程中,操作数据是比较复杂的。同时,如果想要实现与javascript同等复杂逻辑的dom结构,也是比较痛苦的事情 。所幸,强大的smarty也提供了插件机制,我们也可以通过编写smarty插件的方式来实现上述的功能。感兴趣的同学可以调研一下。

@jinzhubaofu
Copy link
Contributor Author

时间安排:

  1. 方案讨论 03/09 - 03/12
  2. 开发阶段 03/13 - 03/22

周四我会提供一个smarty预渲染模板的开发环境。

@jinzhubaofu jinzhubaofu mentioned this issue Mar 9, 2015
@jinzhubaofu
Copy link
Contributor Author

我刚刚提交了预渲染相关的一些代码,稍作说明。

如何使用demo进行开发

  1. 首先,要求大家首先安装php-cgiphp-cgi的安装请自行google。在开发前请保证在terminal中输入php-cgi -v可以看到下面的结果(php版本只要高于5.3即可):

    image

  2. 由于smarty代码库没有纳入git管理,因此在使用demo进行开发前需要手动安装它。从smarty的官网下载到源码后,将源码放置在example/smarty/lib目录中。

    image

  3. 启动edp webserver。我们通过edp-webserverphp-cgi处理器来调用php-cgi,现在已经配置好了。现在在浏览器里输入localhost:8848/example/smarty/index.php即可看到效果:

    image

代码位置与结构

  1. 请将预渲染模板的源代码放置在src/tpl/smarty目录下

  2. 请将example/smarty/index.tpl这个模板中,添加demo相关的代码。

  3. 请在exmaple/smarty/index.less中引入控件样式

    image

  4. 添加控件的配置数据。

    请注意这个文件必须是保持严格的json格式,否则smarty没有办法正确地读取其中的数据。

  5. 我们在src/tpl/smarty/base.tpl中提供了以下几个通用函数,大家可以在自己的控件模板中使用:

    1. getPartClassName() 等同于control.helper.getPartClassName()
    2. getStateClassName() 等同于control.helper.getStateClassName()
    3. getClassName() 等同于上边两个函数
    4. getPartId() 等同于control.helper.getPartId()
    5. dataClick() 生成data-click属性,为moye/log提供点击日志数据

以上,如果遇到任务问题,可以联系我。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant