詳細介紹ZKEACMS for .Net Core

來源:互聯網
上載者:User
ZKEACMS.Core 是基於 .Net Core MVC 開發的開源CMS,這篇文章主要為大家深度解析了ZKEACMS for .Net Core,具有一定的參考價值,感興趣的小夥伴們可以參考一下

ZKEACMS 簡介
ZKEACMS.Core 是基於 .Net Core MVC 開發的開源CMS。ZKEACMS可以讓使用者自由規劃頁面配置,使用可視化編輯設計“所見即所得 (WYSIWYG)”,直接在頁面上進行拖放新增內容。

ZKEACMS使用外掛程式式設計,模組分離,通過橫向擴充來豐富CMS的功能。

響應式設計

ZKEACMS使用Bootstrap3的柵格系統來實現響應式設計,從而實現在不同的裝置上都可以正常訪問。同時站在Bootstrap巨人的肩膀上,有豐富的佈景主題資源可以使用。

簡單示範

接下來看看程式設計及原理

項目結構

  • EasyFrameWork  底層架構

  • ZKEACMS   CMS核心

  • ZKEACMS.Article   文章外掛程式

  • ZKEACMS.Product  產品外掛程式

  • ZKEACMS.SectionWidget  模板組件外掛程式

  • ZKEACMS.WebHost

原理 - 訪問請求流程

路由在ZKEACMS裡面起到了關鍵性的作用,通過路由的優先順序來決定訪問的流程走向,如果找到匹配的路由,則優先走該路由對應的 Controller -> Action -> View,如果沒有匹配的路由,則走路由優先權最低的“全捕捉”路由來處理使用者的請求,最後返迴響應。

優先順序最低的“全捕捉”路由是用來處理使用者自行建立的頁面的。當請求進來時,先去資料庫中尋找是否存在該頁面,不存在則返回404。找到頁面之後,再找出這個頁面所有的組件、內容,然後統一調用各個組件的“Display"方法來來得到對應的“ViewModel"和視圖"View",最後按照頁面的布局來顯示。

ZKEACMS 請求流程圖

驅動頁面組件:

widgetService.GetAllByPage(filterContext.HttpContext.RequestServices, page).Each(widget =>{  if (widget != null)  {    IWidgetPartDriver partDriver = widget.CreateServiceInstance(filterContext.HttpContext.RequestServices);    WidgetViewModelPart part = partDriver.Display(widget, filterContext);    lock (layout.ZoneWidgets)    {      if (layout.ZoneWidgets.ContainsKey(part.Widget.ZoneID))      {        layout.ZoneWidgets[part.Widget.ZoneID].TryAdd(part);      }      else      {        layout.ZoneWidgets.Add(part.Widget.ZoneID, new WidgetCollection { part });      }    }    partDriver.Dispose();  }});

頁面呈現:

foreach (var widgetPart in Model.ZoneWidgets[zoneId].OrderBy(m => m.Widget.Position).ThenBy(m => m.Widget.WidgetName)){  <p style="@widgetPart.Widget.CustomStyle">    <p class="widget @widgetPart.Widget.CustomClass">      @if (widgetPart.Widget.Title.IsNotNullAndWhiteSpace())      {        <p class="panel panel-default">          <p class="panel-heading">            @widgetPart.Widget.Title          </p>          <p class="panel-body">            @Html.DisPlayWidget(widgetPart)          </p>        </p>      }      else      {        @Html.DisPlayWidget(widgetPart)      }    </p>  </p>}

外掛程式“最關鍵”的類 PluginBase

每一個外掛程式/模組都必需要一個類繼承PluginBase,作為外掛程式初始化的入口,程式在啟動的時候,會載入這些類並作一些關鍵的初始化工作。

public abstract class PluginBase : ResourceManager, IRouteRegister, IPluginStartup{  public abstract IEnumerable<RouteDescriptor> RegistRoute(); //註冊該外掛程式所需要的路由 可返回空  public abstract IEnumerable<AdminMenu> AdminMenu(); //外掛程式在後端提供的菜單 可返回空  public abstract IEnumerable<PermissionDescriptor> RegistPermission(); //註冊外掛程式的許可權  public abstract IEnumerable<Type> WidgetServiceTypes(); //返回該外掛程式中提供的所有組件的類型  public abstract void ConfigureServices(IServiceCollection serviceCollection); //IOC 註冊對應的介面與實現  public virtual void InitPlug(); //初始化外掛程式,在程式啟動時調用該方法}

具體實現可以參考“文章”外掛程式 ArticlePlug.cs 或者“產品”外掛程式 ProductPlug.cs

載入外掛程式 Startup.cs

public void ConfigureServices(IServiceCollection services){  services.UseEasyFrameWork(Configuration).LoadEnablePlugins(plugin =>  {    var cmsPlugin = plugin as PluginBase;    if (cmsPlugin != null)    {      cmsPlugin.InitPlug();    }  }, null);      }

組件構成

一個頁面,由許多的組件構成,每個組件都可以包含不同的內容(Content),像文字,圖片,視頻等,內容由組件決定,呈現方式由組件的模板(View)決定。

關係與呈現方式大致如所示:

實體 Enity

每個組件都會對應一個實體,用於儲存與該組件相關的一些資訊。實體必需繼承於 BasicWidget 類。

例如HTML組件的實體類:

[ViewConfigure(typeof(HtmlWidgetMetaData)), Table("HtmlWidget")]public class HtmlWidget : BasicWidget{  public string HTML { get; set; }}class HtmlWidgetMetaData : WidgetMetaData<HtmlWidget>{  protected override void ViewConfigure()  {    base.ViewConfigure();    ViewConfig(m => m.HTML).AsTextArea().AddClass("html").Order(NextOrder());  }}

實體類裡面使用到了中繼資料配置[ViewConfigure(typeof(HtmlWidgetMetaData))],通過簡單的設定來控製表單頁面、列表頁面的顯示。假如設定為文本或下拉框;必填,長度等的驗證。

這裡實現方式是向MVC裡面添加一個新的ModelMetadataDetailsProviderProvider,這個Provider的作用就是抓取這些中繼資料的配置資訊並提交給MVC。

services.AddMvc(option =>  {    option.ModelMetadataDetailsProviders.Add(new DataAnnotationsMetadataProvider());  })

服務 Service

WidgetService 是資料與模板的橋樑,通過Service抓取資料並送給頁面模板。 Service 必需繼承自 WidgetService<WidgetBase, CMSDbContext>。如果業務複雜,則重寫(override)基類的對應方法來實現。

例如HTML組件的Service:

public class HtmlWidgetService : WidgetService<HtmlWidget, CMSDbContext>{  public HtmlWidgetService(IWidgetBasePartService widgetService, IApplicationContext applicationContext)    : base(widgetService, applicationContext)  {  }   public override DbSet<HtmlWidget> CurrentDbSet  {    get    {      return DbContext.HtmlWidget;    }  }}

視圖實體 ViewModel

ViewModel 不是必需的,當實體(Entity)作為ViewModel傳到視圖不足以滿足要求時,可以建立一個ViewModel,並將這個ViewModel傳過去,這將要求重寫 Display 方法

public override WidgetViewModelPart Display(WidgetBase widget, ActionContext actionContext){  //do some thing  return widget.ToWidgetViewModelPart(new ViewModel());}

視圖 / 模板 Widget.cshtml

模板 (Template) 用於顯示內容。通過了Service收集到了模板所要的“Model”,最後模板把它們顯示出來。

動態編譯分散的模板

外掛程式的資源都在各自的檔案夾下面,預設的視圖引擎(ViewEngine)並不能找到這些視圖並進行編譯。MVC4版本的ZKEACMS是通過重寫了ViewEngine來得以實現。.net core mvc 可以更方便實現了,實現自己的 ConfigureOptions<RazorViewEngineOptions> ,然後通過依賴注入就行。

public class PluginRazorViewEngineOptionsSetup : ConfigureOptions<RazorViewEngineOptions>{  public PluginRazorViewEngineOptionsSetup(IHostingEnvironment hostingEnvironment, IPluginLoader loader) :    base(options => ConfigureRazor(options, hostingEnvironment, loader))  {   }  private static void ConfigureRazor(RazorViewEngineOptions options, IHostingEnvironment hostingEnvironment, IPluginLoader loader)  {    if (hostingEnvironment.IsDevelopment())    {      options.FileProviders.Add(new DeveloperViewFileProvider());    }    loader.GetPluginAssemblies().Each(assembly =>    {      var reference = MetadataReference.CreateFromFile(assembly.Location);      options.AdditionalCompilationReferences.Add(reference);            });    loader.GetPlugins().Where(m => m.Enable && m.ID.IsNotNullAndWhiteSpace()).Each(m =>    {      var directory = new DirectoryInfo(m.RelativePath);      if (hostingEnvironment.IsDevelopment())      {        options.ViewLocationFormats.Add($"/Porject.RootPath/{directory.Name}" + "/Views/{1}/{0}" + RazorViewEngine.ViewExtension);        options.ViewLocationFormats.Add($"/Porject.RootPath/{directory.Name}" + "/Views/Shared/{0}" + RazorViewEngine.ViewExtension);        options.ViewLocationFormats.Add($"/Porject.RootPath/{directory.Name}" + "/Views/{0}" + RazorViewEngine.ViewExtension);      }      else      {        options.ViewLocationFormats.Add($"/{Loader.PluginFolder}/{directory.Name}" + "/Views/{1}/{0}" + RazorViewEngine.ViewExtension);        options.ViewLocationFormats.Add($"/{Loader.PluginFolder}/{directory.Name}" + "/Views/Shared/{0}" + RazorViewEngine.ViewExtension);        options.ViewLocationFormats.Add($"/{Loader.PluginFolder}/{directory.Name}" + "/Views/{0}" + RazorViewEngine.ViewExtension);      }    });    options.ViewLocationFormats.Add("/Views/{0}" + RazorViewEngine.ViewExtension);  }}

看上面代碼您可能會產生疑惑,為什麼要分開發環境。這是因為ZKEACMS發布和開發的時候的檔案夾目錄結構不同造成的。為了方便開發,所以加入了開發環境的特別處理。接下來就是注入這個配置:

services.TryAddEnumerable(ServiceDescriptor.Transient<IConfigureOptions<RazorViewEngineOptions>, PluginRazorViewEngineOptionsSetup>());   

EntityFrameWork

ZKEACMS for .net core 使用EntityFrameWork作為資料庫訪問。資料庫相關配置 EntityFrameWorkConfigure

public class EntityFrameWorkConfigure : IOnConfiguring{  public void OnConfiguring(DbContextOptionsBuilder optionsBuilder)  {    optionsBuilder.UseSqlServer(Easy.Builder.Configuration.GetSection("ConnectionStrings")["DefaultConnection"]);  }}

對Entity的配置依然可以直接寫在對應的類或屬性上。如果想使用 Entity Framework Fluent API,那麼請建立一個類,並繼承自 IOnModelCreating

class EntityFrameWorkModelCreating : IOnModelCreating{  public void OnModelCreating(ModelBuilder modelBuilder)  {    modelBuilder.Entity<LayoutHtml>().Ignore(m => m.Description).Ignore(m => m.Status).Ignore(m => m.Title);  }}

主題

ZKEACMS 使用Bootstrap3作為基礎,使用LESS,定議了許多的變數,像邊距,顏色,背景等等,可以通過簡單的修改變數就能“編譯”出一個自己的主題。

或者也可以直接使用已經有的Bootstrap3的主題作為基礎,然後快速建立主題。

最後

關於ZKEACMS還有很多,如果您也感興趣,歡迎加入我們。

ZKEACMS for .net core 就是要讓建網站變得更簡單,快速。頁面的修改與改版也變得更輕鬆,便捷。

【相關推薦】

1. .Net Core 之 圖形驗證碼

2. .NET Core設定檔載入與DI注入配置資料

3. .NET Core CLI工具文檔dotnet-publish

4. 分享.net MVC中使用forms驗證執行個體代碼

5. 在.net core 下如何進行http請求?

6. CentOS上運行ZKEACMS的執行個體教程

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.