使用Lynicon CMS管理ASP.NET Core单页应用内容

在构建交互式Web应用时,如果需要管理Web应用的内容,通常的选择是使用无头CMS服务。但对于小型Web应用来说,这可能过于复杂,并且不允许轻松预览内容变更。Lynicon CMS为ASP.NET Core提供了单页应用(SPA)的内容管理与预览功能,与常见的无头CMS设置不同,它允许立即查看内容变更的效果。它轻量级且设置快速,允许内容存储在文件而非数据库中。

本文将演示如何在Visual Studio 2017中将Lynicon CMS内容管理添加到ASP.NET Core/Angular模板。

后端设置

打开Visual Studio,选择“文件”/“新建项目”。在左侧选择“Visual C#/.NET Core”,在右侧选择“ASP.NET Core Web应用程序”。

然后选择Angular模板。接下来按照以下指南操作: 从“Install Lynicon”小标题开始,因为已经创建了项目。按照可选步骤安装Storeless模块,并继续到最后。这仅仅是安装几个Nuget包并运行3个命令的问题。

现在项目中已经安装了CMS,但它还没有做任何事情。Lynicon使用C#类来定义内容类型,所以第一步是创建一个内容类来保存在首页上看到的内容。

在项目根目录下创建一个名为Models的文件夹,并在其中创建一个名为HomeContent.cs的文件。将以下代码粘贴到该文件中:

using Lynicon.Attributes; using Lynicon.Models; public class HomeContent : PageContent { [Summary] public string Title { get; set; } public MedHtml Body { get; set; } = new MedHtml(); }

Startup.csConfigureServices方法中,修改对services.AddLynicon的调用,如下所示,添加SetDiverter调用:

services.AddLynicon(options => options.UseConfiguration(Configuration.GetSection("Lynicon:Core")) .UseModule<CoreModule>() .UseModule<Storeless>(Configuration.GetSection("Lynicon:Storeless:Cache")) ).AddLyniconIdentity().SetDiverter(new SpaDataDiverter());

这改变了CMS路由内容请求的方式,使其能够正确地与SPA路由一起工作。

再次在Startup.cs中,添加带有MapDataRoute<HomeContent>的行,如下所示:

routes.MapLyniconRoutes(); routes.MapDataRoute<HomeContent>("home", "");

这在/ url上创建了一个内容管理路由。这意味着,如果以内容编辑者的身份登录并访问这个url,Lynicon将向展示页面内容的编辑器以及页面本身。如果使用带有‘Accept: application/json’头部的请求访问这个页面,它将以JSON格式提供该页面的内容数据。

这就是在服务器端设置内容管理所需的全部,现在需要关注前端!

下载文件lyniconcontent.zip,解压其中的lynicon-content.ts并将其放入ClientApp/src/app文件夹。这包含一些可以使用的类,以便将Angular应用程序转换为与Lynicon CMS一起工作。

Angular路由

首先,需要更新SPA路由,以便在更改路由到内容管理路由时拉取内容数据。

首先,创建一个与服务器端HomeContent类相对应的类。在包含首页组件的home/文件夹中创建一个home.content.ts文件。

export class HomeContent { title: string; body: string; }

这很简单,但请注意在前端使用JS驼峰命名:ASP.NET Core内置的JSON格式化程序会自动将属性名称更改为以小写字母开头。

在Angular中声明路由的地方,按如下方式编辑/路由:

RouterModule.forRoot([ { path: '', component: HomeComponent, pathMatch: 'full', resolve: { content: ContentResolver }, data: { contentType: HomeContent } }, // ...其他路由... ])

在这里添加了两个额外的属性:resolve告诉路由在导航到它时要运行ContentResolver。这个类从后端获取内容。data.contentType属性用于指定内容类型,以便ContentResolver在当前路由没有内容时返回一个空类型实例。

现在进入HomeComponent,使其能够接收内容。

export class HomeComponent implements IContentAwareComponent { @FromContent() content: HomeContent; constructor(public injector: Injector) { } }

通过将Injector依赖项引入一个自动public属性来使类实现IContentAwareComponent。然后添加了一个带有类型HomeContent的属性。在这个属性上有一个装饰器:@FromContent(),它安排属性用路由期间获取的内容数据进行初始化。

在标记文件home.component.html中,现在可以将内容插入到渲染的组件中:

<h1>{{content.title}}</h1> <div [innerHtml]="content.body"></div>

现在添加一个额外的调整,使得在预览页面中的导航能够工作,以便可以看到移动到的url的适当内容编辑器。

在路由位置,这样做:

RouterModule.forRoot([ { path: '', canActivateChild: [ BypassActivate ], children: [ { path: '', component: HomeComponent, pathMatch: 'full', resolve: { content: ContentResolver }, data: { contentType: HomeContent } }, // ...其他路由... ]} ])

将所有路由作为父路由的子路由包装起来,将canActivateChild属性设置为BypassActivate。这个路由守卫检查正在导航的路由是否应该显示编辑器,如果是的话,它跳出Angular路由并执行正常的浏览器导航到所需路由。这返回到服务器以获取内容编辑器以及在适当URL处重新加载前端。如果没有这个,路由将在预览页面内全部发生,而无法更改内容编辑器。

添加内容

现在已经设置了SPA从后端读取首页的内容,但目前没有内容记录。如果运行站点,首页组件不会在右侧区域渲染任何内容。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485