ecshop 模板开发 - 肮脏的语法

更新日期: 2016-10-20 阅读次数: 11383 分类: ecshop

从头开发一套模板非常不现实。最简单粗暴的方式就是,把现有的模板复制一份,再此基础上逐步修改。

初始化

复制项目根目录下 themes 下的一套模板,就可以开发了,例如要开发一套仿京东网站的模板

cp -R default jd

模板目录结构说明

  • .dwt 文件为模板文件。例如,index.dwt 为首页的模板文件。.dwt 是 Dreamweaver Template 的模板文件。
  • .lbi 文件为库文件。类似 Laravel blade 模板 include 进来的复用模板文件
  • style.css 为样式文件。同时文件头部注明了模板及开发者信息。

踏出第一步

修改 style.css 文件,将模板名、作者信息修改成自己的。然后,登录 ecshop 后台,切换模板至新模板。

ecshop 使用的模板语法

为何既有

<!-- #BeginLibraryItem "/library/xxx.lbi" --><!-- #EndLibraryItem -->

的语法,又有

{include file="/library/xxx.lbi"}

的语法

include 语法可以断定为 smarty 的语法,这个没有问题,但是,BeginLibraryItem 又是啥?

从 ecshop 的 includes/cls_template.php 可以看到,原来这两种语法是等同的。ecshop 会默默地将 BeginLibraryItem 转换成 include。

1073             /* 将模板中所有library替换为链接 */
1074             $pattern     = '/<!--\s#BeginLibraryItem\s\"\/(.*?)\"\s-->.*?<!--\s#EndLibraryItem\s-->/se';
1075             $replacement = "'{include file='.strtolower('\\1'). '}'";
1076             $source      = preg_replace($pattern, $replacement, $source);

诡异的模板语法又出现了

<!-- {if $new_goods} -->

但是,还有这样的

{if $cat_rec[2]}

还是在 cls/template.php 中找到了答案

1136         $pattern = array(
1137             '/<!--[^>|\n]*?({.+?})[^<|{|\n]*?-->/', // 替换smarty注释
1138             '/<!--[^<|>|{|\n]*?-->/',               // 替换不换行的html注释
1139             '/(href=["|\'])\.\.\/(.*?)(["|\'])/i',  // 替换相对链接
1140             '/((?:background|src)\s*=\s*["|\'])(?:\.\/|\.\.\/)?(images\/.*?["|\'])/is', // 在images前加上 $tmp_dir
1141             '/((?:background|background-image):\s*?url\()(?:\.\/|\.\.\/)?(images\/)/is', // 在images前加上 $tmp_dir
1142             '/([\'|"])\.\.\//is', // 以../开头的路径全部修正为空
1143             );
1144         $replace = array(
1145             '\1',
1146             '',
1147             '\1\2\3',
1148             '\1' . $tmp_dir . '\2',
1149             '\1' . $tmp_dir . '\2',
1150             '\1'
1151             );

第一个正则会把第一种注释型变态语法转换成 smarty 语法。

我勒个擦,这肮脏的模板流派,为何还要看下去

因为如果不理解这套奇葩模板,就没法改下去啊。。。

模板中 insert 与 include 的区别是什么

{insert name='ads' id=$ads_id num=$ads_num}

对应 includes/lib_insert.php 文件中的 insert_ads 函数输出。

问题来了,为何这里需要使用 insert, 从我用 laravel 等现代框架的经验来看,完全没有必要呀,同样 include 一个 lbi 文件不也可以么?


234 function insert_member_info()
235 {
236     $need_cache = $GLOBALS['smarty']->caching;
237     $GLOBALS['smarty']->caching = false;
238
239     if ($_SESSION['user_id'] > 0)
240     {
241         $GLOBALS['smarty']->assign('user_info', get_user_info());
242     }
243     else
244     {
245         if (!empty($_COOKIE['ECS']['username']))
246         {
247             $GLOBALS['smarty']->assign('ecs_username', stripslashes($_COOKIE['ECS']['username']));
248         }
249         $captcha = intval($GLOBALS['_CFG']['captcha']);
250         if (($captcha & CAPTCHA_LOGIN) && (!($captcha & CAPTCHA_LOGIN_FAIL) || (($captcha & CAPTCHA_LOGIN_FAIL) && $_SESSION['login_fail'] > 2)) && gd_version() > 0)
251         {
252             $GLOBALS['smarty']->assign('enabled_captcha', 1);
253             $GLOBALS['smarty']->assign('rand', mt_rand());
254         }
255     }
256     $output = $GLOBALS['smarty']->fetch('library/member_info.lbi');
257
258     $GLOBALS['smarty']->caching = $need_cache;
259
260     return $output;
261 }

从 insert_member_info 就很容易理解,这是一种模块化的做法,即获取数据的逻辑执行之后,填充到对应的 lbi 模板中, 而不是在渲染 dwt 模板时一次性将变量都传进去。类似 laravel 中的 view composer 的概念,当然,laravel view composer 要优雅一万倍。

参考

关于作者 🌱

我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式