最近在准备做一个开源项目 Portal-Builder 门户/B2B通用系统  还没有给自己团队说因为框架还在设想阶段,以下框架解释肯定有不足之处,还望各位多多指教:

设计理念: 

1、争取做到最完善的开源,但是开源的东西未必好用,所以Portal-Builder 应该有一套简单易用的API/SDK,方便各种开发者直接获取相关信息 迅速投入开发;

2、最终网站管理者并不需要一个大而全的门户/B2B系统;由于各用户使用系统功能、模块不尽相同,因此需要有一套机制能够允许用户自行定义系统应该包含哪些模块、怎样运作,这样管理起来也更加简洁、方便;

3、目前市面流行的都是采用基于模板开发的系统,但是模板又无法完全与后台代码剥离,所以对于模板开发者还是有一定的技术要求;Portal-Builder 应该有一套完全不需要前台网页设计师懂得PHP/.NET 等编程语言就能够理解的机制,使网站的模板开发最大与后台代码脱离

4、Portal-Builder需要有一套类似于插件管理的功能,但是要更加强大(我称之为应用管理平台);也就是说,最好能够实现把CMS、分类信息、商城这些复杂的功能模块完全独立出来以应用程序的形式来安装,这样Portal-Builder其自身就只需要管理好自己的框架、基础数据并对安装的应用程序进行监管、验证就可以了

5、做到用户权限设定的动态设定,对每项操作不再像市面的网站系统一样预定义,允许开发者自行根据某种机制来动态更新可以进行设定的权限(我在自己的技术文档里把这称作PortalBuilderAction,即通过XML或某种形式对框架、各种应用进行操作/Action的预定义,从而实现动态权限读取、设定)

6、系统能够自动连接到Portal-Builder开源服务中心,进行系统自动更新

 

对上面理念的一些实现方面的简单介绍:

 

框架:门户整站框架后台与前台实现完全剥离,前台互动通过访问服务使用JSON+Javascript来完成;

功能模块:门户的功能按照AppStore方式的应用安装模式来完成,在系统的文件下按照Portal-Builder定义的文件格式来进行安装、管理和卸载;Portal-Builder框架通过定义一系列Interfaces来与这些相对独立的应用进行沟通和数据处理

重点介绍一下我对前台模板概念的阐述(与市面上见到的CMS、门户站之类的模板开发模式几乎完全不同,希望大家品尝和评论!)

前台模板:

模板可以是任意格式的文件,只需要是按照HTML格式编写就可以,(我们采用ASP.NET开发,因此如果使用ASPX保存模板,还可以通过.NET对ASPX进行服务端编译);

系统通过编写的模板标签语法定义表XML (PBTemplateSyntxDefinition.XML)来自动识别系统可以进行编译的标签, 目前我定下来的XML格式如下:(3月15日草稿)

估计有XML和Reflection经验的朋友们看后就知道我要做些什么了  呵呵

<?xml version="1.0" encoding="utf-8" ?>
<WebCiderSyntax_PortalBuilder>
<PBTemplateParser>
<!--
    <SysParams> 用来获取系统自定义的一些参数,这些参数必须通过一个类调用方法来实现,比如在FakeClass.GetCurrentPageNumber("page")里面调用 HttpContext.Current.Request["page"] 来
      调用当前页码 等等
      SysParams里面的代码完全有万赛达商务科技PortalBuilder开发组定义,请勿自行删改

      <SysParams>里面的Param必须在{webcider:  } 标签内进行使用,使用时需要加前缀$

        比如:  {webcider:文库文档  页码=$当前页码  ....}

-->
<SysParams>
<param Name="当前页码" DefaultValue="1" ClassName="WebCider.FakeNamespace.FakeClass" AssemblyName="WebCider.FakeNamespace" MethodParamValue="page"  MethodName="GetCurrentPageNumber" />
</SysParams>
<!--
      <Commands> 用于用户进行自定义开发自己的编译语言
      每一个<Command>代表可以在前台进行调用的一个标签名,比如下方例子编译设置
    <Commands>
      <Command Name="文库文档" Formatter="WebCider.PortalBuilder.Templates.PBTemplateFormatter">
        <Parameters>
          <param Name="创建者" DefaultValue="Null" ValueType="System.String" />
          <param Name="最早时间" DefaultValue="2010-12-26" ValueType="System.DateTime" />
          <param Name="最晚时间" DefaultValue="2015-12-26" ValueType="System.DateTime" />
        </Parameters>
        <Manager ClassName="WebCider.PortalBuilder.Docs.DocManager" AssemblyName="WebCider.PortalBuilder" MethodName="FindDocs" />
        <Result ClassName="WebCider.PortalBuilder.Docs.DocCollection" AssemblyName="WebCider.PortalBuilder" />
      </Command>
    </Commands>

    在前台可以最终实现这样子的调用:
    <div>
      <div>您的查询结果如下:</div>
      <div class="myClassName">
        { webcider:文库文档 创建者="mleader1" 页码=$当前页码 返回数量="10" }
      </div>
    </div>

    您可以在标签外面嵌套其他html标签并进行CSS定义,从而实现对标签编译出的HTML的样式更改
-->
<Commands>
<Command Name="文库文档" Formatter="WebCider.PortalBuilder.Templates.PBTemplateFormatter">
<Parameters>
<param Name="创建者" DefaultValue="Null" ValueType="System.String" />
<param Name="最早时间" DefaultValue="2010-12-26" ValueType="System.DateTime" />
<param Name="最晚时间" DefaultValue="2015-12-26" ValueType="System.DateTime" />
</Parameters>
<Manager ClassName="WebCider.PortalBuilder.Docs.DocManager" AssemblyName="WebCider.PortalBuilder" MethodName="FindDocs" />
<Result ClassName="WebCider.PortalBuilder.Docs.DocCollection" AssemblyName="WebCider.PortalBuilder" />
</Command>
</Commands>
</PBTemplateParser>
</WebCiderSyntax_PortalBuilder>

这里面有一点技术难度的就是 如果方法里面涉及到 out params 可能反射方面要写的代码就需要多一些

 

在这个XML的基础上,我们通过写一个PBTemplateParser.cs 就可以完全的实现HTML标签的识别、解析和编译,然后通过PBFormatter.cs 来进行二次格式化 (具体代码暂时不公开,不过其实很简单的)

那么在这种设想下,前台需要写的 比如 index.html 模板也的代码可能是这样子的:

<div id="docList">
    {webcider:文库文档 创建者="mleader1" 页码=$当前页 数量="10" cssClass="abcClass"}
</div>

 

然后在具体调用PBTemplateParser 和PBFormatter 完毕后,他的最终代码应该是这种结果:

<div id="docList">
<div class="abcClass">
<!---注:下面代码仅供参考,个人比较憎恨Table的,不过为方便解释我这里暂时写成table-->
<table class="webcider_table">
<tr>
<td>文档ID</td>
<td>文档标题</td>
<td>创建时间</td>
<td>创建者</td>
</tr>
<tr>
<td>101</td>
<td>asdf</td>
<td>2012/12/12</td>
<td>mleader1</td>
</tr>
<tr>
<td>101</td>
<td>asdf</td>
<td>2012/12/12</td>
<td>mleader1</td>
</tr>
            ...
</table>
<table class="webcider_pagination">
<tr>
<td>当前页:2/11</td>
<td>每页数量: 10</td>
                ...
</tr>
</table>
</div>
</div>

也就是说,也就是说这样子我们也就实现了传统意义上的页面模板重写,甚至连标签语言也是用户自己定义的一套自己的语法。 至于样式,只要PBFormatter编译的时候全部使用 div &css 格式,我们便能够轻易重定义样式和布局。 —— 前台工作就能够全部交给前台网页设计师了。 (注:互动性的比如登录验证、表单提交等都可以通过JSON数据、AJAX提交到Web服务来实现)

最后:由于每个应用程序开发都有自己的不同点,框架写一个TemplateParser哪怕功能再强也有可能不包含开发者自己想做的事情,所以Portal-Builder应该同时提供ITemplateParser 和ITempalteFormatter 来方便开发者来进行自己的模板编译器的开发

 

模板和URL的编译应用:  模板编译一旦实现,就要看怎么调用了,模板调用的具体实现方式目前暂时保密,但是理念很简单:Url重写定义了,那么每个Url肯定需要有一个页面落脚点,我们的概念就是网站、子站肯定有至少一个Url,每个Url必须指定一个模板编译页,每个网站、子站应该至少有一个模板编译页。  例如网站首页 {abc}.localhost/ 我们就可以指定他的访问地址模板是 root/Templates/System/index.html  那么至于这个 index.html 如何页面链接是什么样子的、怎么跳转,就完全是前台页面开发者的责任了,只要他做这张模板的时候页面Url是根据Poral-Builder的Url编译规则来的就可以了

 

系统站点管理和Url重写模块今天就来不及阐述我的概念了   上面的实现方式基本上大家可以看出来我打算让团队去做的Portal-Builder 系统的基本框架会是什么样子,欢迎大家讨论! 我把开源Wiki建立起来了,放在 http://www.portal-builder.com 这个地址,但是内容还没有  一旦项目正式开始,相信大家会一起把内容填充起来了的,呵呵 ...

 

这两个星期会确定是否去做这一块儿  如果去做了,那么欢迎各位踊跃参与共同开发和讨论.