ecshop 模板开发 - 肮脏的语法

更新日期: 2016-10-20 阅读次数: 6381 分类: 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 聊聊。 白天写程序,晚上哄熊孩子,可能回复有点慢,见谅。 查看更多联系方式

相关文章

爱评论不评论

近期节日

2020年04月01日 愚人节
2020年04月02日 国际儿童图书日
2020年04月03日 寒食节
2020年04月04日 清明节
2020年04月07日 世界卫生日
2020年04月11日 世界帕金森病日
2020年04月19日 谷雨
2020年04月21日 复活节
2020年04月22日 世界地球日
2020年04月23日 世界读书日
2020年04月26日 知识产权日
2020年04月30日 佛诞
查看更多节日