从头开发一套模板非常不现实。最简单粗暴的方式就是,把现有的模板复制一份,再此基础上逐步修改。
初始化
复制项目根目录下 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 聊聊, 查看更多联系方式