@wiser/ng-cms-client
v0.0.1
Published
This is a library implementation of the package [@wiser/cms-pattern](https://www.npmjs.com/package/@wiser/cms-pattern).
Downloads
1
Readme
@wiser/ng-cms-client
This is a library implementation of the package @wiser/cms-pattern.
This package provies an abstraction library for managing CMS page downloads and state in Angular applications.
Table of Contents
Quick Start
Installation
npm install --save @wiser/ng-cms-client
Usage
First define your page model. Be sure to make sure it is defined at a class. This is your contract that should be implemented in the view template. We will ensure that our home page repository always maintains this contract.
export class HomePage {
public title!: string;
public subtitle!: string;
public body!: string;
}
Then implement SinglePageRepository as an @Injectable
service to resolve the HomePage
class.
import { SinglePageRepository } from '@wiser/ng-cms-client';
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { HomePage } from '../models/pages/home-page';
@Injectable({
providedIn: 'root'
})
export class DemoHomePageRepository implements SinglePageRepository<HomePage, undefined> {
constructor(
private readonly http: HttpClient,
) { }
public async read(): Promise<ContactPageData> {
const data = await this.http.get<any>('/assets/data/home.json').toPromise();
const page = new HomePage();
page.title = page_data.title;
page.subtitle = page_data.subtitle;
page.body = page_data.body;
return page;
}
}
Note
We can also have implemented MultiPageRepository to resolve a set of pages that are instantiations of the same class.
Import the CmsModule into the AppModule
and provide all single page and multip page repository registrations using the static forRoot
method using an object implementing CmsConfig interface.
import { NgModule } from '@angular/core';
import { CmsModule } from '@wiser/ng-cms-client';
import { HomePage } from './models/pages/home-page';
import { DemoHomePageRepository } from './repositories/demo-homep-page-repository';
@NgModule({
declarations: [ ... ],
imports: [
CmsModule.forRoot({
singlepage: [
...
{
Data: HomePage,
Repository: DemoHomePageRepository,
}
...
],
multipage: [
...
],
}),
],
providers: [ ... ],
bootstrap: [ ... ]
})
export class AppModule { }
Now we need to tell the DownloaderService when to download a specific page. Let's create a Resolver
to do this.
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Router } from '@angular/router';
import { DownloaderService } from '@wiser/ng-cms-client';
import { HomePage } from '../models/pages/home-page';
@Injectable({
providedIn: 'root'
})
export class HomePageResolver {
constructor(
private readonly downloader: DownloaderService,
private readonly router: Router,
) { }
public async resolve(route: ActivatedRouteSnapshot): Promise<void> {
this.downloader.downloadPage(HomePage, null).catch(e => {
console.error(e);
this.router.navigate(['/', 'error']);
});
}
}
And, of course, the resolver must be registered to a route.
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './pages/home/home.component';
import { ContactPageResolver } from './resolvers/home-page-resolver';
const routes: Routes = [
...
{
path: '',
component: HomeComponent,
resolve: {
_body: HomePageResolver,
},
}
...
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Finally, we can use the CmsService class to retreive the data by simply subscribing to the observable on the page(...)
method.
import { Component, OnInit } from '@angular/core';
import { CmsService } from '@wiser/ng-cms-client';
import { HomePage } from '../../models/pages/home-page';
@Component({
selector: 'app-contact',
templateUrl: './contact.component.html',
styleUrls: ['./contact.component.scss']
})
export class HomeComponent implements OnInit {
public page: HomePage;
constructor(
private cms: CmsService,
) { }
public ngOnInit(): void {
this.cms.page(HomePage).subscribe(
page => this.page = page,
);
}
}
Public Exports
SinglePageRepository
<<interface>> SinglePageRepository<T, S>
A subset of ReadonlyRepository<T, S>
omiting list. Data of type T
can be accessed by id of type S
.
Implement this interface with the logic for accessing data and resolving an instantiation of the target model when there exists a single upstream instance of the model.
MultiPageRepository
<<interface>> MultiPageRepository<T, S>
A mirror of ReadonlyRepository<T, S>
. Data of type T
can be accessed by id of type S
.
Implement this interface with the logic for accessing data and resolving an instantiation of the target model when there exists multiple upstream instances of the model.
CmsPageFilter
<<type>> CmsPageFilter<T, S>
A filter to be applied on an instance of type T, where a key of T is provided and value of unknown type must be matched.
CmsConfig
<<interface>> CmsConfig
Provides the registrations required by the CmsModule to match a SinglePageRepository or MultiPageRepository to a data model class.
CmsModule
@NgModule CmsModule
Encapsulation of the library. Provides two services: CmsService and DownloaderService.
CmsService
@Injectable CmsModule
Provides access to CMS state through Observables
to specific page instantiations resolved by calling DownloaderService. The page
and streamPage
methods can take optional CmsPageFilters.
DownloaderService
@Injectable CmsModule
Exposes two methods: downloadPage
and downloadPages
.
The downloadPage
method is used for downloading a single matching page instance from either the registered SinglePageRepository or possibly from a matching registered MultiPageRepository.
The downloadPages
method will download a set of page partials where the instance matches the registered MultiPageRepository.