ZKEACMS简介。Core是基于。Net核心MVC。ZKEACMS允许用户自由规划页面布局,通过可视化编辑设计“所见即所得”,直接在页面上拖拽添加内容。
ZKEACMS采用插件式设计,模块分离,横向扩展,丰富了CMS的功能。
响应性设计
ZKEACMS利用Bootstrap3网格系统实现响应式设计,使其可以在不同设备上正常访问。同时,站在Bootstrap巨头的肩膀上,有丰富的主题资源可以利用。
简单介绍
接下来,看看程序设计和原理
项目结构
EasyFrameWork底层框架zkeacms核心ZKEACMS。文章文章插件ZKEACMS。产品插件ZKEACMS。SectionWidget模板组件插件ZKEACMS。网络主机原则-访问请求流
路由在ZKEACMS中起着关键作用,访问的流向由路由的优先级决定。如果找到匹配的路线,则优先选择该路线对应的控制器-操作-视图;如果没有匹配的路由,用户的请求由优先级最低的“完全捕获”路由处理,最后返回响应。
优先级最低的“完全捕获”路径用于处理用户自己创建的页面。当请求进来时,首先去数据库找出页面是否存在,否则,返回404。找到页面后,找出页面的所有组件和内容,然后调用每个组件的“Display”方法,得到对应的“ViewModel”和“View”视图,最后根据页面的布局进行显示。
ZKEACMS请求流程图
驱动页面组件:
widgetService。GetAllByPage(filterContext。HttpContext.RequestServices,第页)。每个(widget={ if (widget!=null){ IWidgetPartDriver partDriver=widget。CreateServiceInstance(filterContext。HttpContext . RequestSerVices);widgetview model part part=part driver。显示(小部件、过滤器上下文);锁定(布局。ZoneWidgets) { if(布局。区域小部件。包含密钥(部分。Widget.ZoneID)) {布局。ZoneWidgets[部分。Widget.ZoneID]。TryAdd(部分);} else {布局。添加(部分。Widget.ZoneID,new WidgetCollection { part });} } partDriver。dispose();}});页面呈现:
模型中的foreach (var widgetPart)。区域部件[区域标识]。OrderBy(m=m.Widget.Position)。then by(m=m . Widgetname)){ div style=' @ WidgetPart。widget . custom style ' div class=' widget @ WidgetPart。widget . custom class ' @ if(WidgetPart。widget . title . isnotnullandhitespace()){ div class=' panel panel-default ' div class=' panel-heading ' @ WidgetPat。widget . Title/div div class=' panel-body ' @ Html。display WidgetPart(WidgetPart)/Div/Div } else { @ html。display widget(widget art)}/div/div }插件基础,插件的“最关键”类
每个插件/模块都必须有一个类来继承PluginBase,它被用作插件初始化的入口。当程序启动时,它会加载这些类并做一些关键的初始化工作。
公共抽象类PluginBase : ResourceManager,IRouteRegister,IPluginStartup{公共抽象IEnumerableRouteDescriptor registore();//注册插件所需的路由可以返回一个空的公共抽象ienumerableleadminmenuadminmenu//后端插件提供的菜单可以返回空的公共抽象ienumerablepermission descriptor registpermission();//注册插件公共抽象ienumerabletype widgetservicetypes()的权限;//返回插件公共抽象void configure services(is ervicecollection service collection)中提供的所有组件的类型;//IOC注册对应的接口,实现公共虚拟void InitPlug();//初始化插件,程序启动时调用此方法。}具体实现请参考文章插件ArticlePlug.cs或产品插件ProductPlug.cs
加载插件启动
public void ConfigureServices(IServiceCollection services){ services .使用简易框架(配置)。LoadEnablePlugins(plugin={ var Cmsplugin=plugin as PluginBase;if(CmPlugin!=null){ CmPlugin .InitPlug();} },null);}组件构成
一个页面,由许多的组件构成,每个组件都可以包含不同的内容(内容),像文字,图片,视频等,内容由组件决定,呈现方式由组件的模板(视图)决定。
关系与呈现方式大致如下图所示:
实体尼蒂
每个组件都会对应一个实体,用于存储与该组件相关的一些信息。实体必需继承于基本信息获取类。
例如超文本标记语言组件的实体类:
[查看配置(类型(HTML widgetdata))、表格(‘HTML小部件’)]公共类HTML小部件: BasicWidget {公共字符串HTML { get设置;} }类html widget metadata : widget widget widget { protected override void ViewConfigure(){ base .查看配置();视图配置AsTextArea().AddClass('html ').order(下一个订单());}}实体类里面使用到了元数据配置[视图配置(类型为(html widgettmetadata))],通过简单的设置来控制表单页面、列表页面的显示。假如设置为文本或下拉框;必填,长度等的验证。
这里实现方式是向手动音量调节里面添加一个新的ModelMetadataDetailsProviderProvider,这个供应者的作用就是抓取这些元数据的配置信息并提交给MVC。
服务AddMvc(选项={选项.模型元数据详细信息提供程序。添加(新的数据注释元数据提供程序());})服务服务
WidgetService是数据与模板的桥梁,通过服务抓取数据并送给页面模板服务必需继承自WidgetServiceWidgetBase,CMSDbContext。如果业务复杂,则重写(覆盖)基类的对应方法来实现。
例如超文本标记语言组件的服务:
公共类HTMlWidgetServiCe : WidgetServiCe HTMlWidget,CMSDbContext {公共html widgettservice(iwidGetBasePartServiCe widgettservice,Iappapplication context应用程序上下文): base(widgettservice,applicationContext) { }公共重写DBsetHTMlWidget当前bset { get { return DBcontext } .HtmlWidget} }}视图实体视图模型
视图模型不是必需的,当实体(实体)作为视图模型传到视图不足以满足要求时,可以新建一个视图模型,并将这个视图模型传过去,这将要求重写显示方法
公共覆盖widgetview model part Display(WidgetBase小部件,动作上下文动作上下文){//做一些事情返回小部件ToWidgetViewModelPart(新视图模型());}视图/模板Widget.cshtml
模板(模板)用于显示内容。通过了服务收集到了模板所要的"模型",最后模板把它们显示出来。
动态编译分散的模板
插件的资源都在各自的文件夹下面,默认的视图引擎(视图引擎)并不能找到这些视图并进行编译MVC4。版本的ZKEACMS是通过重写了视图引擎来得以实现。网络核心手动音量调节可以更方便实现了,实现自己的configureoptions srazorviewcenengineoptions,然后通过依赖注入就行。
公共类pluginrazorviewengineoptions setp : configureoptions srazorviewpunginoptions { public pluginrazorviewengineoptions setp(IHostingEnvironment HostingEnvironment,IPluginLoader): base(options=ConfigureRazor(options,HostingEnvironment,loader)) { }私有静态void ConfigureRazor(razooverview pengine options,IHostingEnvironment hosting environment,IPluginLoader){ if(hosting environment).IsDevelopment()) { options .文件提供程序。添加(新的developer viewpileprovider());}装载机GetPluginAssemblies().每个(程序集={变量引用=元数据引用.CreateFromFile(程序集。位置);选项附加编译引用。添加(引用);});装载机GetPlugins().其中(m=m .启用m . id。isnotnullandhitespace()).每个(m={ var directory=new directory info(m .相对路径);if (hostingEnvironment .IsDevelopment()) { options .视图位置格式。添加($ '/项目RootPath/目录。名称} ' '/视图/{1}/{0}' RazorViewEngine .视图扩展);选项。视图位置格式。添加($ '/项目RootPath/目录。名称} ' '/视图/共享/{0}' RazorViewEngine .视图扩展);选项。视图位置格式。添加($ '/项目RootPath/目录。名称} ' '/视图/{0}' RazorViewEngine .视图扩展);} else { options .视图位置格式。添加($ '/{加载器插头信息夹}/{ 0目录。名称} ' '/视图/{1}/{0}' RazorViewEngine .视图扩展);选项。视图位置格式。添加($ '/{加载器插头信息夹}/{ 0目录。名称} ' '/视图/共享/{0}' RazorViewEngine .视图扩展);选项。视图位置格式。添加($ '/{加载器插头信息夹}/{ 0目录。名称} ' '/视图/{0}' RazorViewEngine .视图扩展);} });选项。视图位置格式。添加('/视图/{0} '剃刀视图引擎视图扩展);}}看上面代码您可能会产生疑惑,为什么要分开发环境。这是因为ZKEACMS发布和开发的时候的文件夹目录结构不同造成的。为了方便开发,所以加入了开发环境的特别处理。接下来就是注入这个配置:
服务TryAddEnumerable(服务描述符.transition figure options srazorviewcenengineoptions,pluginrazorviveengineoptions setup());
EntityFrameWork
ZKEACMS适用于.净芯使用EntityFrameWork作为数据库访问。数据库相关配置实体框架工作配置
公共类entityframeworkconfiguration : ionconfiguration { public void onconfiguration(dbcontextoptions builder选项生成器){ options builder } .使用SqlServer(简单建筑商。配置。get section(' ConnectionStrings ')[' DefaultConnection ']);}}对实体的配置依然可以直接写在对应的类或属性上。如果想使用实体框架流畅原料药,那么请创建一个类,并继承自ionmodel创建
类实体框架模型创建: ionmodel创建{公共void on model creating(模型构建器模型构建器){模型构建器} .EntityLayoutHtml().忽略(m=m。描述)。忽略(m=m。状态)。忽略(m=m .标题);}}主题
ZKEACMS使用Bootstrap3作为基础,使用更少,定议了许多的变量,像边距,颜色,背景等等,可以通过简单的修改变量就能"编译"出一个自己的主题。
或者也可以直接使用已经有的Bootstrap3的主题作为基础,然后快速创建主题。
最后
关于ZKEACMS还有很多,如果您也感兴趣,欢迎加入我们。
ZKEACMS适用于.净芯就是要让建网站变得更简单,快速。页面的修改与改版也变得更轻松,便捷。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。