ZKEACMS默认包含了许多了的组件(Widget),正是这些组件组成了ZKEACMS,通过它们,可以让CMS变得更加的多样化,功能化。

 

组件分为两中,采用哪个方式,应根据实际情况来决定:

  1. 轻量组件。可以不用添加新的数据库表,采用JSON格式来存储数据。
  2. 普通组件。必需要创建一个对应的数据表用来存储数据。
 
无论是哪种组件,都由四部分构成:
  1. WidgetService 组件的业务逻辑,数据准备
  2. WidgetEntity 组件实体类
  3. WidgetMetaData 组件元数据配置,用于生成组件配置的表单
  4. Widget.*.cshtml 前端显示组件的视图

 

轻量组件

轻量组件因为是用JSON存储,所以要做的事情也比较少,比较简单,继承自SimpleWidgetBaseSimpleWidgetService即可,例如评论箱组件:

CommentsWidget:

public class CommentsWidget : SimpleWidgetBase
{
}

class CommentsWidgetMetaData : WidgetMetaData
{

}

CommentsWidgetService:

这里重写了Display方法,是因为Widget.Comments.cshtml视图里面使用的ViewModel不是CommentsWidget,如果ViewModel是直接使用WidgetEntity类的(如:CommentsWidget),可不用重写该方法

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 WidgetViewModelPart Display(WidgetBase widget, ActionContext actionContext)
{
return widget.ToWidgetViewModelPart(_commentsService.Get(m => m.PagePath == actionContext.HttpContext.Request.Path.Value && m.Status == (int)RecordStatus.Active));
}
}
}

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字段关联,并且是一一对应关系。其它字段应跟据组件情况添加。组件要继承自BasicWidgetWidgetService<T>。其它地方与简单组件一致。

以HTML组件为例:

HtmlWidget:

namespace ZKEACMS.Common.Models
{
    [Table("HtmlWidget")]
    public class HtmlWidget : BasicWidget
    {
        public string HTML { get; set; }
    }
    class HtmlWidgetMetaData : WidgetMetaData
    {
        protected override void ViewConfigure()
        {
            base.ViewConfigure();
            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
           }
        }
    }
}