纸壳CMS默认包含了许多了的组件(Widget
),正是这些组件组成了ZKEACMS,通过它们,可以让CMS变得更加的多样化,功能化。
组件分为两中,采用哪个方式,应根据实际情况来决定:
WidgetService
组件的业务逻辑,数据准备WidgetEntity
组件实体类WidgetMetaData
组件元数据配置,用于生成组件配置的表单Widget.*.cshtml
前端显示组件的视图
轻量组件因为是用JSON存储,所以要做的事情也比较少,比较简单,继承自SimpleWidgetBase
,SimpleWidgetService
即可,例如评论箱组件:
CommentsWidget
:
namespace ZKEACMS.Message.Models
{
public class CommentsWidget : SimpleWidgetBase
{
}
class CommentsWidgetMetaData : WidgetMetaData<CommentsWidget>
{
}
}
CommentsWidgetService
:
这里重写了Display
方法,是因为Widget.Comments.cshtml
视图里面使用的ViewModel
不是CommentsWidget
,如果ViewModel
是直接使用WidgetEntity
类的(如:CommentsWidget
),可不用重写该方法。
Display
方法返回模板使用的ViewModel
:
namespace ZKEACMS.Message.Service
{
public class CommentsWidgetService : SimpleWidgetService<CommentsWidget>
{
private readonly ICommentsService _commentsService;
public CommentsWidgetService(IWidgetBasePartService widgetBasePartService, IApplicationContext applicationContext, CMSDbContext dbContext, ICommentsService commentsService)
: base(widgetBasePartService, applicationContext, dbContext)
{
_commentsService = commentsService;
}
public override object Display(WidgetBase widget, ActionContext actionContext)
{
var viewModel = _commentsService.Get(m => m.PagePath == actionContext.HttpContext.Request.Path.Value && m.Status == (int)RecordStatus.Active);
return viewModel;
}
}
}
Widget.Comments.cshtml
:
@model IList<Comments>
@{}
...
最后,需要在 Plugin.cs
(每一个插件,都对应有一个XXXPlugin.cs类)类里面进行组件的注册:
public override IEnumerable<WidgetTemplateEntity> WidgetServiceTypes()
{
yield return new WidgetTemplateEntity<CommentsWidgetService>
{
Title = "评论箱",
GroupName = "5.消息",
PartialView = "Widget.Comments",
Thumbnail = "~/Plugins/ZKEACMS.Message/Content/Image/Widget.Comments.png",
Order = 1
};
} public override void ConfigureServices(IServiceCollection serviceCollection) {
serviceCollection.ConfigureMetaData<CommentsWidget, CommentsWidgetMetaData>(); }
普通组件,要求要创建一个数据表与组件的实体对应,数据库表必需包含一个ID字段(NVARCHAR(100))与CMS_WidgetBase表中的ID字段关联,并且是一一对应关系。其它字段应跟据组件情况添加。组件要继承自BasicWidget
,WidgetService<T>
。其它地方与简单组件一致。
以HTML组件为例:
HtmlWidget
:
namespace ZKEACMS.Common.Models
{
[DataTable("HtmlWidget")]
public class HtmlWidget : BasicWidget
{
public string HTML { get; set; }
}
class HtmlWidgetMetaData : WidgetMetaData<HtmlWidget>
{
protected override void ViewConfigure()
{
base.ViewConfigure();
ViewConfig(m => m.PartialView).AsHidden();
ViewConfig(m => m.HTML).AsTextArea().AddClass("html").Order(NextOrder());
}
}
}
HtmlWidgetService
:
namespace ZKEACMS.Common.Service
{
public class HtmlWidgetService : WidgetService<HtmlWidget>
{
public HtmlWidgetService(IWidgetBasePartService widgetService, IApplicationContext applicationContext, CMSDbContext dbContext)
: base(widgetService, applicationContext, dbContext)
{
}
}
}
Widget.HTML.cshtml
:
@model ZKEACMS.Common.Models.HtmlWidget
<div class="html-widget">
@Html.Raw(Model.HTML)
</div>
最后,同样也是组件的注册,元数据:
public static void UseZKEACMS(this IServiceCollection services, IConfigurationRoot configuration)
{
services.ConfigureMetaData<HtmlWidget, HtmlWidgetMetaData>();
}
HTML组件的注册有点不一样,因为是CMS的基础类型,所以直接初始化到了 KnownWidgets 里面。
namespace ZKEACMS.WidgetTemplate
{
public class WidgetTemplateService : IWidgetTemplateService
{
public static List<WidgetTemplateEntity> KnownWidgets = new List<WidgetTemplateEntity>
{
new WidgetTemplateEntity<HtmlWidgetService>
{
Title = "HTML",
GroupName = "1.通用",
PartialView = "Widget.HTML",
Thumbnail = "~/images/Widget.HTML.png",
Order = 1
}
}
}
}