模板机制

优势和创新

ShopEx模板机制的优势

  • 面对后端开发人员
    • 模板挂件机制灵活的接口调用让你轻松并且安全的将数据抛向前端,并可方便的构建数据筛选、配置规则和界面。
    • 模板缓存、自定义URL帮你分担后端开发压力,可能你并不需要关心页面静态化。
  • 面对前端开发人员
    • 默认集成强大的前端开发框架和接口调用。
    • 严格的要求前端工程师模块化的设计思想。
  • 面对网店运营人员
    • 运营人员无需懂得前端开发技术,可 以在管理后台进行所见即所得的网店的 布局调整,板块数据展示规则设定。
    • 运营人员可以轻松更换、删减网店板 块,更换挂件板块的内置风格。
    • 挂件机制可以满足你站外嵌入的需 求。

ShopEx模板机制的创新

  • 所见既所得的可视化模板板块编辑机制
  • 将布局、区块、边框、数据 真正细分化

模板机制的名词解释

挂件区域(widgets)

挂件区域用于在某个页面预留挂件(widget)可挂入的区域。也可以理解为“插槽”、“坑”。

每个挂件区域可以挂入多个挂件

挂件(widget)

挂件是ShopEx模板机制中的一个重要角色,它能根据条件从后端取得数据然后根据“挂件级页面模板”来包装成一个小板块。

例如一个“商品板块挂件”,它要先由后端语言(php)来组织数据,然后返回到“挂件级页面模板”。组织数据的条件将会独 立出一个可配置页面。

边框(border)

边框用于包装一个挂件板块,一套模板里面可能由很多个边框风格,这些风格的名称和对应的边框文件 需要定义在模板的描述文件(theme.xml)中,以便可视化编辑时改变一个板块的风格。

例如一个“商品板块挂件”在首页要以三种不同的风格展示(促销、热门、新品......),除了需要在挂件的配置面板中配置数 据的展示范围不同,还需要由边框机制的配合达到颜色风格的区别。特别是一些系统级挂件,为了适应不同模板的展示方 式,默认不会输出标题和边框,边框则可以协助包装一下挂件挂入到挂件区域。

系统级区域(main)

系统级区域用于输出系统的核心交互流程。这些区域的html\javascript是不能在模板包中直接定义的,模板包唯一能影响到这些系统级区域的是 css样式定义,因为模板包的样式表是在系统级样式之后加载。

默认模板页 (default.html)

默认模板页是在模板包中 未定义某个页面的布局时,默认调用的页面布局。例如你的模板包中只包含了两个页面的定义: 首页、默认页,那么其他未定义的页面在访问时将优先使用默认模板页,直到你单独定义它为止。


创建一个模板包

标准模板包必要的文件

创建一个模板包文件夹,例如 fsgw

新模板包文件夹的名称应与描述文件中的 id保持一致,并且应该由数字和英文小写组成。

在模板包文件夹内创建以下文件:3r

    1. theme.xml

      此文件用来描述模板包的基本信息,以及模板可能包含的挂件。还用于模板的备份导出,和导入操作中的模板数据交换。例如:

      <?xml version="1.0" encoding="UTF-8" ?>
      <theme>
        <name>风尚购物</name>
        <id>fsgw</id>
        <version>ECcStore</version>
        <info></info>
        <author>ShopEx-UED</author>
        <site>https://blog.wanxiaohong.cn</site>
        <update_url></update_url>
        <borders>
          <set key="边栏样式" tpl="borders/border1.html" />
          <set key="商品分类" tpl="borders/border2.html" />
          <set key="商品公告" tpl="borders/border3.html" />
          <set key="品牌热卖排行" tpl="borders/border4.html" />
          <set key="热销排行" tpl="borders/border5.html" />
          <set key="首页商品列表" tpl="borders/border6.html" />
          <set key="尾页文章列表" tpl="borders/border9.html" />
          <set key="购买过本商品的顾客还买过" tpl="borders/border10.html" />
        </borders>
        <views></views>
        <config></config>
        <proinstance></proinstance>
      </theme>
      
      xml节点 说明
      name 模板包的名称,将会出现在管理后台模板列表中
      id 首次由开发人员定义,应与模板包名称保持一致,(全英 文)
      version 模板包的版本信息
      info 模板包简介
      author 模板包作者
      site 模板包作者网址
      update_url 升级地址,暂未启用
      borders 模板包包含的边框定义描述
      widgets 模板挂件描述。系统会在模板可视化编辑添加挂件后向 widgets序列化挂件描述
      此表只描述最关键的几个节点项
    2. 每个模板页将用到的公共页面引用 (header.html、footer.html)例如:(header.html)
      <!doctype html>
      <html>
      <head>
      <{header}> <!--将输出系统级 style、javascript、meta-->
      <link rel="stylesheet" type="text/css" href="images/fsgw-style.css" /> 
<!--模板包样式的引入,(”images/” 是必须的,因为在页面渲染时,它会被替换为绝对路径)-->
      </head>
      <body>
      <div class=”body”>
        <div class=”top”>
          <div class=”top-bar clearfix”>
            <div class=”span-auto”>Welcome</div>
            <div class=”span-auto login”>
          <{widgets id=”header-login”}> <!--一个挂件区域,(id 是唯一的)-->
            </div>
          </div>
        </div>
        <div class=”header”>
          <{widgets id=”header-nav”}>  <!--一个挂件区域,(id 是唯一的)-->
      
      例如:(footer.html)
        <div class="footer">
          <div class="copyright">
            <{widgets id="footer-copyright"}>
            <!--一个挂件区域,(id 是唯一的)-->
          </div>
          <{footer}> <!--将输出系统级 业务处理javascript\用户自定义的底部信息-->
        </div>
      </body>
      
    3. 首页模板(index.html)例如:
      <{require file="header.html"}>  <!--引入公共的头部(头部的挂件区块会被解析)-->
      
          <div class=”main”>
                     <div class=”banner”>
                  <{widgets id=‘index-banner’}>
                  <!--预留一片广告展示挂件区-->
              </div>
              <div class=”content c-1 clearfix”>
                 <div class=”span-4 m-l”>
              <div class=”mod”>
                  <div class=”t”>商品分类</div>
                  <div class=”b”>
                      <{widgets id=‘index-cat’}>
          <!--预留一片商品分类挂件的挂入区-->
                  </div>
              </div>
              <{widgets id=‘index-m-l’}>
              <!--预留一片首页左侧挂件区-->
                  </div>
                <div class=”span-10 m-r”>
              <{widgets id=‘index-m-r’}>
              <!--预留一片首页右侧挂件区-->
                  </div>
              </div>
          </div>
      
      <{require file="footer.html"}> <!--引入公共的底部(底部的挂件区块会被解析)-->
      
      <{require file="header.html"}>  <!--引入公共的头部(头部的挂件区块会被解析)-->
      
          <div class=”main”>
              <div class=”content clearfix”>
                 <div class=”span-4 m-l”>
              <{widgets id=‘m-l’}>
              <!--预留一片左侧挂件区-->
                  </div>
                <div class=”span-10 m-r”>
              <{main}>
      <!--系统级区域输出(可能会是:会员中心、购物流程、商品搜索结果、商品详情、文章)-->
                  </div>
              </div>
          </div>
      
      <{require file="footer.html"}> <!--引入公共的底部(底部的挂件区块会被解析)-->
      
    4. 默认模板页(default.html)
    5. 边框文件夹 (borders)应该建立 borders文件夹, 来存放 一个个的边框 html,html属性应统一用双引号,防止出现模板解析异常例如:borders/border1.html
      <div class="border1 <{$widgets_classname}>" id="<{$widgets_id}>">
      <!--将输出被包装挂件板块在后台定义的边框 className、id-->
          <h3>
          <{$title}> <!--将输出被包装挂件板块在后台定义的标题-->
          </h3>
          <{$body}> <!--将输出被包装挂件板块内容-->
      </div>
      
    6. 资源文件夹 (images)存放模板资源文件,例如css\js\图片、swf
    7. 一张模板效果图(preview.jpg)模板效果图是一张直观的模板效果图片(120*160 px),可以在管理后台模板列表看到它以区分模板。

标准模板包必要的文件结构


模板包的首次加载

模板开发测试环境

目前模板的开发测试环境比较重要的一个地方就是网店的后台。

如果你在做模板的开发,请先在管理后台应用中心安装一个应用程序:《开发者工具》app.

安装方法:点击管理后台右上 “应用中心入口”,找到“开发者工具”,进行安装;
之后,你将在模板列表上方看到”维护“按钮。


模板包的首次加载

当首次构建好基础模板包。此刻应将模板文件夹复制到网店模板目录


既:/themes下

这时你的模板列表中将出现此模板的记录(如下图)


;

首次的模板加载应通过文件夹复制的方式放置到指定位置(/themes/)下。不应该直接将其以压缩包的形式通过模板上传加载。

完善模板包

为模板添加页面布局

上文提到我们仅构建了标准的模板包。下面我们应为某些页面添加更丰富的布局页面文件

(如下图)

添加页面布局文件时

需要输入名称、文件名、和页面源码

名称可以理解为对文件的备注,文件名会自动追加.html后缀,页面源码会模板复制 默认布局页源码。

在此可以修改html源码页可以只输入 名称和文件名先生成html文件到模板包。统一用其他工具编辑页面源码。

为模板布局页添加挂件

    • 系统级常用挂件表
      分类 名称 简介
      | |
    • 挂件的添加和配置

(下图:版块中心)

(下图:挂件配置面板)

挂件的添加在模板页面可视化编辑中进行。

添加挂件的基本交互:

选择目标版块区域(一个挂件版块区域可以挂入多个挂件版块)-》选择挂件版块类型 -》配置版块标题(版块标题将会在边框中以<{$title}>调用,如果版块边框样式为无边框,则标题不会出现于前台)-》挂件版块模板选择(一个挂件可以由多个对应模板供选择)-》边框样式选择-》边框属性配置(className\ID)-》挂件相关配置(例如商品挂件,可以配置商品显示范围、数量、价格精度等)

挂件添加后可以进行编辑 位置移动等操作。

  • 注意事项


公用头部和底部被挂入的挂件版块将共享于所有引入头部底部文件的页面。
如果要在源码编辑删除 一个<{widgets}>(挂件版块区域)标签,请先在可视化编辑中删除此区域中的所有的挂件实例。
模板可视化编辑结束后,注意保存编辑成果。

创建一个模板级挂件

当系统内置的挂件不能满足你的要求时,你可以自己动手建立一个挂件

创建一个模板级挂件的必备文件结构

  • 配置页(_config.html)配置页是在可视化编辑时用到的配置表单。
  • 配置页拦截器(theme_widget_cfg_widgetname.php)[可选]配置页拦截器用于向配置页输出系统数据,例如输出一个系统当前的商品排序方式数组。供页面 <select>填充选择。[如果配置页不需要从系统内取得数据,则 此拦截器无需制作。]

  • 挂件拦截器(theme_widget_widgetname.php)
挂件拦截器,用于向挂件模板供应后端数据

  • 挂件描述文件(widgets.php)
用于描述挂件基本信息,挂件模板文件、名称对应关系。

  • 挂件渲染模板 (widgettpl1.html....... widgettplN.html)
一个或多个挂件模板,需要在挂件描述文件中被描述,以便可视化编辑时选择挂件使用的模板。
  • 可视化编辑占位模板 (_preview.html)[可选]此页面用于在可视化编辑时占位,例如广告挂件由许多效果和图片资源加载,在可视化编辑时影响效率,可以用此页面来代替挂件的渲染,但是挂件拦截器同样会把数据抛向此页面,你可以只取得一些尺寸信息,用边框和文字代替挂件。
[如果挂件不需要在可视化编辑模式重定义,则无需制作此页]

创建一个模板级挂件-mywidget

mywidget 挂件的目的是实现一个根据管理员的配置在前台显示一组商品信息。

  • 在模板目录建立 widgets文件夹
  • 在widgets文件夹内创建mywidget文件夹,并进入文件夹
  • 创建挂件描述文件

    widgets.php

    <?php
/*挂件的描述文件*/
    $setting['author']='挂件作者';
    $setting['version']='v1.0';
    $setting['name']=”我的第一个挂件”;
    $setting['stime']='2010-12-12';
    $setting['catalog']=“风尚购物模板的挂件”;
    $setting['description']    =”我的第一个挂件的描述”;
    $setting['usual']    = '1';  //是否出现在挂件中心首页.(1\0)
    $setting['template'] = array(
                                
    'default.html'=>’HTML展示’,
                  
    'flash.html'=>’用flash展示’
                            
    ); //挂件包含的模板文件和名称
    ?>
  • 创建挂件配置页_config.html (命名规则定死_config)
    <!--
        编写挂件配置页html时候,不需要body \title\ form等 html标签  。
    此代码块共享 管理后台的 资源(javascript\css\)。
        _config.html代码块只是挂件配置对话框中的一部分。
               下列代码中的 $data 数组 由挂件配置页拦截器返回, smarty 协助抛向页面。
    $setting数组 是被保存在数据库中的配置信息由系统取出,smarty协助抛向页面。
     -->
      <div class="division">
        <h4>商品展示规则</h4>
        <label>排序规则:</label>
        <select name="orderby">
            <{foreach from=$data item=orderby key=key}>
                <option value="<{$key}>" <{if $setting.goods_orderby==$key}>selected<{/if}>>
                <{$orderby.label}>
                 </option>
            <{/foreach}>
        </select>
        <label>展示数量:</label>
        <input name=”limit” value=”<{$setting.limit}>” />
      </div>
    
  • 创建挂件配置页拦截器(用于取得系统相关数据)theme_widget_cfg_mywidget.php (命名应于内部代码函数名保持一致)
    <?php
    /*
        命名规范 以“theme_widget_cfg_”开头,挂件包名结尾。
        运行时系统会传入一个参数,方便创建 model 等实例 ,用于取得数据
 */
    function theme_widget_cfg_mywidget(){
        
    $app app::get(‘b2c’); //创建app实例,这里要用到b2c这个app下的goods model所有创建b2c app实例
        
    $model_goods=$app->model('goods');  //创建goods model实例
        
    return $model_goods->orderBy();  //返回商品排序规则datemap,在挂件配置模板smarty标签中,统一用 $date 获得
    }
    ?>
  • 创建挂件模板default.html (命名规则应与widget.php挂件描述文件中 $setting['template'] 保持一致)
    <!--
        挂件模板同挂件配置模板页一样,都是一个代码片段,无需加入body\title\等html标签。
        挂件模板中的 <style></style>中定义将会合并到一个css文件中被引入到<head>头部
    (例如一个模板布局页面同时挂了两个 mywidget)。
        挂件模板中的 ‘image/‘  将会被替换为绝对路径,你可以在挂件包中创建一个images文件夹用来存放挂件相关的资源。例如 <style>#<{widgets_id}>_mywidge{ background:url(‘images/bg.png’)} </style>,在渲染到前台时,系统将自动替换images/为绝对路径。
    -->
    <div class="GoodsListWrap GoodsList GoodsShow"  id=’<{$widgets_id}>_mywidget’>
    <{if count($data.goods) > 0}>
    <dl>
          <{foreach from=$data.goods item=product name=goodslist}>
          <dd>
                商品名称:<{$product.name}><br />
                商品价格:<i><{$product.price|default:'0'}></i>元
          </dd>
          <{/foreach}>
    </dl>
    <{else}>
      <div class='notice'>暂无商品数据</div>
    <{/if}>
    </div>
    
  • 创建挂件拦截器
theme_widget_mywidget.php (命名应于内部代码函数名保持一致)
    <?php
    /*
        命名规范 以“theme_widget_”开头,挂件包名结尾。
        运行时系统会传入挂件配置信息
 */
    function theme_widget_mywidget(&$setting,&$render)
    {
         
    $app app::get(‘b2c’);
         
    $o = &app->model('goods');

        
    $limit = (intval($setting['limit'])>0)?intval($setting['limit']):6;

        
    $orderby=$setting['goods_orderby']?$o->orderBy($setting['goods_orderby']):null;

        
    $filter = array();

        
    $data['goods'] = $o->getList('*',$filter,0,$limit,$orderby['sql']);

         return 
    $data;   //根据挂件配置信息,取出数据 返回给挂件模板
    }

    ?>
  • 创建可视化编辑占位模板_preview.html (命名规则定死_preview)
    <!--
        这个文件只用于模板可视化编辑时,如某些情况不方便直接将挂件呈现于可视化编辑视图。

        则可以创建此文件在可视化编辑中代替挂件真实显示
    -->
    <div class="note">
        我的第一个挂件
    </div>

    

模板级挂件绑定到模板

当创建好一个模板级挂件。可以在管理后台通过模板列表上面的 “维护” 按钮绑定挂件到模板。

(如下图,经过绑定维护后)


挂件中心可以看到了

测试我的第一个挂件

下图为挂件配置对话框,上文提到,_config.html正式挂件版块配置时的一部分,在挂入到模板挂件区域时,你还可以包装挂件所使用的边框,挂件版块所使用的挂件模板等信息。

可视化编辑中被挂入到挂件版块后。(由于我的第一个挂件定义了_preview.html)所以可视化编辑时和前台真实效果有区别。


做一下模板编辑保存,看一下前台的效果吧


j选择其他边框和挂件配置


保存,再看一下效果。


系统资源的重用

重用脚本框架

在制作模板、挂件 的过程中,你可以随时使用 脚本框架 Mootools 的公开接口,它提供了强大的节点寻找、强化了javascript数组、封装了异步交互。

重用系统级样式表

我们在前台引入了一个简单的 样式表封装(frameworks.css)、里面有常用的布局、浮动、字体、内外补丁 等class定义。

重用前端效果库封装

前台有一个 强大的效果库封装(switchable.js),它提供了大部分广告效果的轻松实现机制。还提供了区块、图片延迟加载等机制。

系统级区域<{main}>的修改

site站点

站点管理

  • 系统模块

以b2c为例,它是根据b2c中的site.xml里面定义的生成对应的列表

在默认的情况下不介意修改里面的参数,

其中的参数默认的是在site.xml设置的参数,扩展名为html

  • 导航菜单

导航菜单也是在site.xml中定义的

其中的编辑可以从新定义 导航标题,是否是显示在导航栏上,是否在新窗口打开。

新建导航有两种方式,一种是在系统(site.xml)中定义过的,这样只要显示出来就可以咯,

还有一种方式所自定义链接,可以导入一个链接导航

  • 站点配置

基本信息配置 可配置站点名称,备案号,和网页底部信息

高级配置可以配置是否启用全页缓存,URL参数分割符(规定死了就一个没得选择),

是否使用扩展名 和 扩展名是什么对应于系统全局,最后决定的还是后面那个是否检查url扩展名

  • 自定义URL

能够添加一个url规则,能够把url改变成自定义的一个链接名

  • seo 优化
  • sitemap

这是提供一个生成的sitemap,能够直接下载下来

页面管理

这是在content下的一个文章管理系统

  • 页面列表

显示的是所有的文章列表,可以编辑是否发布.

另外有三个添加文章的方式,

1. 添加文章

添加文章就只能对应的添加文章,它使用的模板对应的也是文章的模板,编辑的是文章的样式。

2. 添加单独页

添加单独页可以自定义布局,添加挂件。它就可以不必须是标题,文章的样式.可以自己设计。

3. 添加自定义页

添加自定义页就是页面所有的东西都要自己手动去写。

  • 文章栏目

这是管理的文章分类,可以对节点进行添加,删除,编辑等操作。

  • 异常页面管理

页面异常管理是管理据注册的service site_display_errorpage.conf 来获取到定义的异常页面,在对其进行管理重新定义

异常页面是把这些提示信息以kvstore存储上,在对其进行获取调用。

友情链接

显示的是友情链接的列表,可以对其进行添加,删除,编辑操作。数据存放在sdb_site_link 表中。

在b2c中是以广告相关/友情链接的挂件 对其进行调用。

site controller

系统级区域<{main}>的修改

创建一个模板级的系统区域

  • 当系统内置的挂件不能满足你的要求时,你可以自己动手建立一个模板级的系统级区域。
    1. 在模板目录建立customsite文件夹。
    2. 在customsite文件夹内创建你你想拦截以及重写的系统级页面。

      (如下图,创建了商品详情页product1.html和规格页spec1.html.)

    3. 修改模板级商品详情页(product1.html)配置
      <!---购物面板--->
          <div class='hightline'>
          <div class='hightbox'>
          <!---规格开始--->
          <{if $goods.spec }>
          <{include file='theme:customsite/spec1.html'}>
           //将系统级规格页面路径修改为模板级 theme: 路径下的customsite文件夹下的spec1.html
          <{/if}>
          <!---规格结束--->
      
      (注:不能直接拦截功能区块页面任何调用方法<{include file='theme:spec1.html'}>的子页面,只支持直接拦截父级页面)
      
    4. 修改模板文件夹的theme.xml。
      <?xml version="1.0" encoding="UTF-8" ?>
      <theme>
          <name>风尚购物</name>
          <id>fsgw</id>
          <version>ECStore</version>
          <info></info>
          <author>ShopEx</author>
          <site>https://blog.wanxiaohong.cn</site>
          <update_url></update_url>
          <borders>
                      <set key="边栏样式" tpl="borders/border1.html" />
                      <set key="商品分类" tpl="borders/border2.html" />
                      <set key="商店公告" tpl="borders/border3.html" />
          </borders>
          <views>
               <set app="b2c"  view="site/product/index.html"   tpl="customsite/product1.html" />
          //将根目录b2c的view文件夹内的site站点文件夹下的view系统级路径下的商品详情页product/index.html替换为tpl模板级路径下的商品详情页customsite/product1.html
          </views>
          <config></config>
          <widgets></widgets>
          <proinstances></proinstances>
      </theme>
      
    5. 在管理后台通过模板列表上的 “模板还原” 至“默认” (因上步骤修改的是theme.xml文件),如下图:
    • 商品详情页和商品规格字段已被更改。