Skip to content

2 约定大于配置

Jensyn edited this page Apr 20, 2015 · 7 revisions

本节介绍了CS采用的 约定大于配置 原则,应用在平台上进行开发所要遵循的各类默认约定,包括目录结构、数据库设计、页面渲染方式、页面样式等。

##约定大于配置

约定优于配置(convention over configuration),也称作按约定编程,是一种软件设计范式,旨在减少软件开发人员需做决定的数量,获得简单的好处,而又不失灵活性。 本质是说,开发人员仅需规定应用中不符约定的部分。例如,如果模型中有个名为Sale的类,那么数据库中对应的表就会默认命名为sales。只有在偏离这一约定时,例如将该表命名为"products_sold",才需写有关这个名字的配置。 如果您所用工具的约定与你的期待相符,便可省去配置;反之,你可以配置来达到你所期待的方式。

—— "约定优于配置" From Wikipedia

##应用目录结构约定

  • 为方便说明,文档中所有路径,均以~/为平台根目录。

  • 如无特别说明,应用无需提供平台已包含的jQuery,Bootstrap 3,Smarty等库文件,也无需在代码中包含这些库文件。

一个符合约定的应用,应当具有 应用标题应用名 两个代称。其中:应用标题可由中英文与数字符号等组成,是应用向用户展示的称呼;应用名由小写英文字母与数字组成,是应用为CS平台提供的标识。应用的这两个代称是在应用配置文件中指定的。

应将所有相关文件放置在以应用名命名的文件夹内。所有的应用目录放置在平台的app目录下。

例如:应用标题为“内测反馈”,应用名为“feedback”的应用,其所有文件放置在 ~/app/feedback/ 目录下。

应用应当具有如下目录结构:

┌ .             // 应用目录,以应用名命名 
├ ..            // 平台app目录
├ config        // 应用配置文件  
├ templates     // smarty模板目录  
│   └ *.tpl     // 页面模板文件  
├ function.php  // 应用接口函数  
└ *.*           // 其他应用文件

##应用数据库名约定

CS平台使用约定的数据表命名规范。

  • 对于底层服务框架使用的表,以 cs_ 前缀开头;
  • 对于上层应用使用的表,以 app_应用名_ 前缀开头。

例如:应用名为 feedback 的应用,有一张 reply 表,则该表应命名为 app_feedback_reply

##页面布局与渲染方式约定

在说明应用的页面布局与渲染方式之前,开发者应先了解平台提供的两种布局模式:

  • 平台统一框架

    默认情况下,平台提供了一个与平台高度整合的布局框架。如下图所示:

    统一框架

  • 应用自设计页面

    这种布局模式下,页面布局完全由应用自行实现。但仍需遵循一定的开发约定。

下面介绍应用页面模板开发约定

  1. 所有使用统一框架的应用模板都必须继承自平台模板中的frame.tpl,不使用统一框架的页面需继承自平台模板中的base.tpl。

  2. 使用统一框架的应用模板,请使用页面主体部分覆盖content区域,即使用<{block name="content"}><{/block}>语句;不适用统一框架但继承自base.tpl的模板,请覆盖frame区域。

  3. 如需更改页面标题,请覆盖page_title区域。

  4. 如需使用平台域名,请使用SiteDomain模板配置变量,即<{#SiteDomain#}>

  5. 模板中需要添加单独的css文件,请追加stylesheet区域,即使用<{block name="stylesheet" append}>...<{/block}>语句;如需添加js文件/代码(js代码如果只在一个文件中使用,尽量不要写在外部文件中),请追加scripts区域。注:添加css/js文件尽量使用网络地址,即使用域名作为前缀。如:src="<{#SiteDomain#}>js/app.js"

下面介绍应用页面模板渲染约定

  1. 为了方便平台的可维护性,应用中不允许出现与平台相关的相对路径或者是绝对路径。涉及到与平台相关的路径,如需要包含平台的config.php文件,请使用require(dirname(dirname(dirname(__FILE__))) . '/config.php'),而非require('../../config.php');涉及到绝对路径请使用平台配置文件中的BASE_PATH作为平台的根目录。

  2. 每个使用统一框架的应用都必须包含~/init.php文件(使用init.php文件进行登录检查,init初始化框架所需的数据,如顶部导航站内信提醒,用户头像、侧栏应用列表、右侧栏用户列表等等),并且请遵守第1条规范。

  3. 如果某个页面只允许管理员操作,请包含~/privilege_ctrl.php文件,无需单独开发权限检查功能。

  4. 应用中坚决不允许出现与平台相关数据表(以cs_开头)操作的SQL语句,如需操作这些数据表,请使用~/includes中的的接口;如果现有的接口不足以满足需求,请联系平台开发人员共同协商解决。此外,应用开发人员也应该注意,非接口文件尽量避免出现直接对数据库进行读取的情况。

##应用与平台整合约定

阅读本节内容前,开发者应先理解平台首页的页面结构:

首页框架

除应用自身的页面外,应用与平台页面整合交互主要存在于两个地方: 左侧栏的 “应用列表” 部分,以及 右侧栏的“应用区块” 部分。

  • 左侧栏"应用列表"

    每个应用拥有一项独立的列表项,由3部分组成,如下图所示:

    应用列表项

    1. 应用图标 :左侧的小图标。支持FontAwesome图标集。在应用配置文件中设定。
    2. 应用标题 :中间的文字。在应用配置文件中设定。
    3. 消息数量 :应用消息数量。在应用配置文件中设定是否启用,在应用接口函数cal_num()中返回数值。

    CS平台通过应用配置文件获取应用图标与应用标题,通过应用接口函数获取消息数量(应用接口函数具体实现方式参见下方)。

  • 右侧栏“应用区块”

    每个应用可以在配置文件中设置是否启用应用区块。每个应用可启用一个或多个区块。通过应用接口函数aside_html()返回完整区块HTML代码。 一个应用区块的HTML代码应遵循如下格式(如需实现多区块,只需重复如下格式构成的HTML即可):

    <h4 class="font-thin">区块标题</h4>
    <section class="panel panel-default">
      <!--区块内容HTML代码-->
    </section>
    

下面我们介绍应用接口函数的写法。

在应用目录下的function.php文件中,应当接收一个get参数func,当$_GET['func'] == 'cal_num'时,调用应用接口函数cal_num()并返回消息数量。当$_GET['func'] == 'aside_html' 时,调用应用接口函数aside_html()并返回应用区块HTML代码。

以下是一个示例function.php的写法:

<?php
    $func = $_GET['func'];
    if ($func == 'cal_num') echo cal_num();
    if ($func == 'aside_html') echo aside_html();

    function cal_num()
    {
        return 1;
    }

    function aside_html()
    {
        return '
        <h4 class="font-thin">区块标题1</h4>
        <section class="panel panel-default">
            <div class="table-responsive">
                <!-- 区块1 HTML代码 -->  
            </div>
        </section>

        <h4 class="font-thin">区块标题2</h4>
        <section class="panel panel-default">
            <div class="table-responsive">
                <!-- 区块2 HTML代码 -->  
            </div>
        </section>
        ';
    }
?>

##自定义浏览器组件

为了统一界面风格、简化应用开发,平台使用一些自定义组件替换了浏览器内置组件,如alert、confirm。因此,在需要的时候,只需一条js语句,即可创建风格统一的组件。

  1. 弹出一个alert消息框

    alert("这是一个消息对话框!");
    
  2. 弹出一个confirm对话框

    confirm("这是一个confirm对话框");
    

由于无法阻塞后续代码的执行,因此,自定义组件在某些方面表现与浏览器内置组件有所不同,具体如下:

  1. 浏览器内置消息对话框会阻塞后续js代码的执行,而自定义组件则需要提供一个回调函数来维持代码执行的时序。

    alert("页面即将自动刷新!");
    location.reload();
    

    以上代码,在使用浏览器内置组件的情况下,需要点击消息框的确定按钮,页面才会刷新;而在使用自定义组件的情况下,页面会自动刷新。为了达到内置组件的阻塞效果,需要将以上代码改为:

    alert("页面将自动刷新", function () {
        location.reload();
    });
    
Clone this wiki locally