最近在准备做一个开源项目 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 这个地址,但是内容还没有 一旦项目正式开始,相信大家会一起把内容填充起来了的,呵呵 ...
这两个星期会确定是否去做这一块儿 如果去做了,那么欢迎各位踊跃参与共同开发和讨论.