Статьи

Как создать безсерверное угловое приложение на базе CMS

Angular приобрел популярность и широко используется. Angular, разработанный и поддерживаемый инженерами Google, нашел свое место во всех динамических веб-приложениях и становится все более востребованной платформой.

Angular предлагает преимущества большого и увлеченного сообщества и выдающийся MVC, который не требует от разработчиков тратить драгоценное время на написание кода, чтобы снова собрать несколько компонентов MVC. Короче говоря, Angular — это надежная и всеобъемлющая инфраструктура веб-приложений для внешней разработки, готовая к модульному тестированию, что делает ее предпочтительным инструментом для многих разработчиков.

Если вы используете Angular, вам может понадобиться возможность управления контентом — одним из примеров этого является блог. Добавление CMS в приложение Angular может показаться сложным, особенно если вы пытаетесь интегрировать его в традиционную CMS, такую ​​как WordPress, но есть новое поколение CMS на основе API, которое значительно упрощает работу. ButterCMS — это один из примеров безголовой CMS на основе SaaS, которая предоставляет размещенную панель управления CMS и API контента, который вы запрашиваете в своем приложении Angular. Это означает, что вам не нужно раскручивать новую инфраструктуру, чтобы добавить CMS в ваше приложение Angular.

Из этого туториала Вы узнаете, как создать приложение Angular на базе CMS, содержащее маркетинговые страницы (примеры клиентов), блог и часто задаваемые вопросы, все они работают через API. Серверы не нужны!

Установка

Во-первых, вы начнете с установки Angular CLI.

npm install -g @angular/cli</td> 

Настройте новый Angular-проект, используя Angular CLI. По умолчанию Angular CLI использует стили CSS, поэтому добавление --style=scss указывает Angular CLI на использование SCSS:

 ng new hello-buttercms-project --style=scss cd hello-buttercms-project 

Установите угловой материал и угловой материал:

 npm install --save @angular/material @angular/cdk npm install --save @angular/animations 

Установите ButterCMS. Запустите это в командной строке:

 npm install buttercms --save 

Масло также может быть загружено с использованием CDN:

 <script src="https://cdnjs.buttercms.com/buttercms-1.1.1.min.js"></script> 

Быстро приступить к работе

Откройте проект в выбранном вами редакторе кода. В src/app создайте каталог с именем _services .

Мы создаем файл с именем butterCMS.service.js . Это позволяет нам хранить ваш API-токен в одном месте и случайно не изменять его.

 import * as Butter from 'buttercms'; export const butterService = Butter('b60a008584313ed21803780bc9208557b3b49fbb'); 

Вы импортируете этот файл в любой компонент, который мы хотим использовать ButterCMS.

Для src/app/hello-you/hello-you.component.ts butterService перейдите в src/app/hello-you/hello-you.component.ts и импортируйте butterService :

 import {butterService} from '../_services'; 

Внутри HelloYouComponent создайте методы:

 fetchPosts() { butter.post.list({ page: 1, page_size: 10 }) .then((res) => { console.log('Content from ButterCMS') console.log(res) }) } 

Теперь вызовите этот метод, когда компонент загружен, добавив его в ловушку жизненного цикла OnInit :

 ngOnInit() { this.fetchPosts(); } 

Этот запрос API выбирает ваши сообщения в блоге. Ваша учетная запись поставляется с одним примером сообщения, которое вы увидите в ответе.

Затем создайте другой метод для получения поля содержимого заголовка домашней страницы:

 fetchHeadline() { butter.content.retrieve(['homepage_headline']) .then((res) => { console.log('Headline from ButterCMS') console.log(res) }) } 

Добавьте этот метод в ловушку жизненного цикла OnInit .

 ngOnInit() { this.fetchPosts(); this.fetchHeadline(); } 

Этот запрос API извлекает заголовок главной страницы. Вы можете настроить свои собственные поля контента для управления любым видом контента, который вам нужен.

Добавить маркетинговые страницы

Настройка страниц на основе CMS представляет собой простой трехэтапный процесс:

  1. Определите тип страницы
  2. Создать страницу
  3. Интеграция в ваше приложение

Определить страницу

Во-первых, создайте тип страницы для представления ваших страниц изучения клиентов. Затем определите поля, которые вы хотите для своих примеров клиентов. Определив тип страницы, вы можете создать первую страницу с примером. Укажите имя и URL-адрес страницы, а затем заполните содержимое страницы.

После определения вашей страницы API-интерфейс ButterCMS вернет ее в формате JSON, например:

 { "data": { "slug": "acme-co", "fields": { "facebook_open_graph_title": "Acme Co loves ButterCMS", "seo_title": "Acme Co Customer Case Study", "headline": "Acme Co saved 200% on Anvil costs with ButterCMS", "testimonial": "<p>We've been able to make anvils faster than ever before! - <em>Chief Anvil Maker</em></p>\r\n<p><img src=\"https://cdn.buttercms.com/NiA3IIP3Ssurz5eNJ15a\" alt=\"\" caption=\"false\" width=\"249\" height=\"249\" /></p>", "customer_logo": "https://cdn.buttercms.com/c8oSTGcwQDC5I58km5WV", } } } 

Это руководство использует Angular Framework и Angular CLI для создания всех наших компонентов и упаковки нашего приложения.

Давайте перейдем к коду.

Создать новый проект

 ng new buttercms-project --style=scss cd buttercms-project npm install --save @angular/material @angular/cdk npm install --save @angular/animations npm install -S buttercms ng serve 

Ваш localhost: 4200 должен быть готов обслуживать вашу угловую страницу.

Создание TypeScript для экспорта службы ButterCMS

В src/app создайте каталог с именем _services . Создайте файл с именем butterCMS.service.js .

 import * as Butter from 'buttercms'; export const butterService = Butter('your_api_token'); 

Обновите маршруты компонентов

Эти компоненты генерируются Angular CLI с использованием:

 ng g component <my-new-component> 

В src/app создайте файл с именем app-routing.module.ts :

 import {NgModule} from '@angular/core'; import {RouterModule, Routes} from '@angular/router'; import {CustomerComponent} from './customer/listing/customer.listing.component'; import {FaqComponent} from './faq/faq.component'; import {BlogPostComponent} from './blog-post/listing/blog-post.component'; import {HomeComponent} from './home/home.component'; import {CustomerDetailsComponent} from './customer/details/customer.details.component'; import {BlogPostDetailsComponent} from './blog-post/details/blog-post.details.component'; import {FeedComponent} from './feed/feed.component'; import {HelloYouComponent} from './hello-you/hello-you.component'; const appRoutes: Routes = [ {path: 'customer', component: CustomerComponent}, {path: 'customer/:slug', component: CustomerDetailsComponent}, {path: 'faq', component: FaqComponent}, {path: 'blog', component: BlogPostComponent}, {path: 'blog/:slug', component: BlogPostDetailsComponent}, {path: 'rss', component: FeedComponent}, {path: 'hello-you', component: HelloYouComponent}, {path: 'home', component: HomeComponent}, {path: '**', redirectTo: 'home'} ]; @NgModule({ imports: [RouterModule.forRoot(appRoutes)], exports: [RouterModule] }) export class AppRoutingModule { } 

Настройте страницу списка клиентов

Под apps/customer тип apps/customer :

 ng g component listing 

В файле apps/customer/listing/customer.listing.component.ts :

  1. Импортное butterService
  2. В хуке OnInit используйте butterService чтобы получить список клиентов
  3. Сохраните результаты в переменной страниц, и разметка (HTML) будет обновлена ​​данными.
 import {Component, OnInit} from '@angular/core'; import {butterService} from '../../_services'; @Component({ selector: 'app-customer', templateUrl: './customer.listing.component.html', styleUrls: ['./customer.listing.component.scss'] }) export class CustomerComponent implements OnInit { public pages: any[]; constructor() { } ngOnInit() { butterService.page.list('customer_case_study') .then((res) => { this.pages = res.data.data; }); } } 

Отобразить результаты в customer.listing.component.html :

 <mat-card> <mat-card-title class="page-title">Customers</mat-card-title> <mat-divider></mat-divider> <mat-card-content class="page-body"> <mat-card *ngFor="let page of pages"> <mat-card-title> <div class="container"> <a [routerLink]="[page.slug]"> <div fxLayout="row" fxLayout.xs="column" fxFlex class="content"> <div class="blocks"> <img src="{{page.fields.customer_logo}}" alt="{{page.fields.seotitle}}" height="64" width="64"/> </div> <div class="blocks"> {{page.fields.headline}} </div> </div> </a> </div> </mat-card-title> </mat-card> </mat-card-content> <mat-divider></mat-divider> <mat-card-footer> <div class="page-footer"> <mat-icon>whatshot</mat-icon> </div> </mat-card-footer> </mat-card> 

Настройте страницу сведений о клиенте

В apps/customer введите ng g component details .

 apps/customer/details/customer.details.component.ts 

Создать страницу клиента

  1. Импортное butterService
  2. В хуке OnInit используйте butterService чтобы получить страницу клиента с указанным butterService в пути URL
  3. Сохраните результаты в переменной страницы, и разметка (HTML) будет обновлена ​​с данными клиента.
 import {Component, OnInit} from '@angular/core'; import {Observable} from 'rxjs/Observable'; import {ActivatedRoute} from '@angular/router'; import {butterService} from '../../_services'; import {map, take} from 'rxjs/operators'; @Component({ selector: 'app-customer-details', templateUrl: './customer.details.component.html', styleUrls: ['./customer.details.component.scss'] }) export class CustomerDetailsComponent implements OnInit { constructor(protected route: ActivatedRoute) { } protected slug$: Observable<string>; public page: any; ngOnInit() { this.slug$ = this.route.paramMap .pipe( map(params => (params.get('slug'))) ); this.slug$.pipe( take(1)) .subscribe(slug => { butterService.page.retrieve('customer_case_study', slug) .then((res) => { this.page = res.data.data; }).catch((res) => { console.log(res); }); }); } } 

Отобразите результаты в customer.details.component.html .

 <mat-card> <div class="container"> <div fxLayout="column" class="details"> <div class="blocks"> <img src="{{page.fields.customer_logo}}" alt="" height="124" width="124"/> </div> <h1 class="blocks"> {{page.fields.headline}} </h1> <h3 class="is-size-3">Testimonials</h3> <div [innerHTML]="page.fields.testimonial"></div> <div [innerHTML]="page.fields.body"></div> </div> </div> </mat-card> 

Теперь вы можете перейти на страницу клиента через список всех страниц клиента или напрямую через URL.

Добавить базу знаний

Настройте поля содержимого

Предположим, вы хотите добавить CMS на статическую страницу часто задаваемых вопросов с заголовком и списком вопросов с ответами.

Создание динамического контента с помощью Butter двухэтапный процесс:

  1. Настройка пользовательских полей содержимого в Butter
  2. Интегрируйте поля в свое приложение.

Чтобы настроить пользовательские поля содержимого, сначала войдите в панель управления Butter.

Создайте новое рабочее пространство или нажмите на существующее. Рабочие пространства позволяют упорядочивать поля контента для редакторов контента и не влияют на разработку или API. Например, веб-сайт недвижимости может иметь рабочее пространство под названием « Свойства», а другое — « О странице» .

Как только вы окажетесь в рабочей области, нажмите кнопку, чтобы создать новое поле содержимого. Выберите тип объекта и назовите поле заголовка FAQ.

После сохранения добавьте еще одно поле, но на этот раз выберите тип коллекции и назовите поле « Вопросы и ответы» .

На следующем экране настройте два свойства для элементов в коллекции.

Теперь вернитесь в рабочее пространство и обновите заголовки и часто задаваемые вопросы.

Интегрировать ваше приложение

Создать FAQ FAQ

Под apps введите ng g component faq .

 apps/faq/faq.component.ts 

Установите хук onInit для загрузки FAQ

 import {Component, OnInit} from '@angular/core'; import {butterService} from '../_services'; @Component({ selector: 'app-faq', templateUrl: './faq.component.html', styleUrls: ['./faq.component.scss'] }) export class FaqComponent implements OnInit { constructor() {} public faq: any = { items: [], title: 'FAQ' }; ngOnInit() { butterService.content.retrieve(['faq_headline', 'faq_items']) .then((res) => { console.log(res.data.data); this.faq.title = res.data.data.faq_headline; this.faq.items = res.data.data.faq_items; }); } } 

Показать результат

 <mat-card> <mat-card-title class="page-title"></mat-card-title> <mat-divider></mat-divider> <mat-card-content class="page-body"> <mat-card *ngFor="let item of faq.items"> <mat-card-content> <h3> {{item.question}} </h3> <div> {{item.answer}} </div> </mat-card-content> </mat-card> </mat-card-content> <mat-divider></mat-divider> <mat-card-footer> <div class="page-footer"> <mat-icon>whatshot</mat-icon> </div> </mat-card-footer> </mat-card> 

Значения, введенные на панели инструментов Butter, сразу обновят содержимое нашего приложения.

Ведение блога

Для отображения сообщений мы создаем простой маршрут /blog в вашем приложении и извлекаем сообщения из блога из API-интерфейса Butter, а также маршрут /blog/:slug для обработки отдельных сообщений.

Смотрите нашу ссылку API для дополнительных опций, таких как фильтрация по категории или автору. Ответ также включает некоторые метаданные, которые мы будем использовать для нумерации страниц.

Настройте домашнюю страницу блога

Под apps/blog-post введите ng g component listing .

 apps/blog-post/listing/blog-post.listing.component.ts 

Обновите компонент, чтобы получить все сообщения:

  1. импорт butterService
  2. получить все сообщения на сайте
 import {Component, OnInit} from '@angular/core'; import {butterService} from '../../_services'; @Component({ selector: 'app-blog-post', templateUrl: './blog-post.component.html', styleUrls: ['./blog-post.component.scss'] }) export class BlogPostComponent implements OnInit { public posts: any[]; constructor() { } ngOnInit() { butterService.post.list({ page: 1, page_size: 10 }).then((res) => { console.log(res.data) this.posts = res.data.data; }); } } 

Показать результат:

 <mat-card> <mat-card-title class="page-title">Blog Posts</mat-card-title> <mat-divider></mat-divider> <mat-card-content class="page-body"> <mat-card *ngFor="let post of posts"> <mat-card-title> <a [routerLink]="[post.slug]"> <div class="container"> <div fxLayout="row" fxLayout.xs="column" fxFlex class="content"> <div class="blocks"> <img *ngIf="post.featured_image" src="{{post.featured_image}}" height="64" width="64"/> </div> <div class="blocks"> {{post.title}} </div> </div> </div> <div class="container"> <div fxLayout="column" class="summary"> <div [innerHTML]="post.summary"></div> </div> </div> </a> </mat-card-title> </mat-card> </mat-card-content> <mat-divider></mat-divider> <mat-card-footer> <div class="page-footer"> <mat-icon>whatshot</mat-icon> </div> </mat-card-footer> </mat-card> 

Настройка страницы блога

Под apps/blog-post введите ng g component details .

 apps/blog-post/details/blog-post.details.component.ts 

Чтобы показать один пост:

  1. Импортное butterService
  2. В хуке OnInit используйте butterService чтобы получить сообщение в блоге с указанным слагом в пути URL
  3. Сохраните результаты в переменной post, и разметка (HTML) будет обновлена ​​с данными клиента.
 import {Component, OnInit, ViewEncapsulation} from '@angular/core'; import {Observable} from 'rxjs/Observable'; import {ActivatedRoute} from '@angular/router'; import {butterService} from '../../_services'; import {map, take} from 'rxjs/operators'; @Component({ selector: 'app-blog-post-details', templateUrl: './blog-post.details.component.html', styleUrls: ['./blog-post.details.component.scss'], encapsulation: ViewEncapsulation.None }) export class BlogPostDetailsComponent implements OnInit { constructor(protected route: ActivatedRoute) { } protected slug$: Observable<string>; public post = { meta: null, data: null }; ngOnInit() { this.slug$ = this.route.paramMap .pipe( map(params => (params.get('slug'))) ); this.slug$.pipe( take(1)) .subscribe(slug => { butterService.post.retrieve(slug) .then((res) => { this.post = res.data; }).catch((res) => { console.log(res); }); }); } } 

Показать результат:

 <mat-card> <div class="container"> <div fxLayout="column" class="blog-details"> <div class="container"> <div fxLayout="row"> <h1 class="blocks"> {{post.data.title}} </h1> <div *ngIf="post.meta.previous_post"><a [routerLink]="post.meta.previous_post"><</a></div> <div *ngIf="post.meta.next_post"><a [routerLink]="post.meta.next_post">></a></div> </div> <h4> {{post.data.author.first_name}} {{post.data.author.last_name}} </h4> <div class="post-body" [innerHTML]="post.data.body"></div> </div> </div> </div> </mat-card> 

Теперь у вашего приложения есть рабочий блог, который можно легко обновить на панели управления ButterCMS.

Категории, теги и авторы

Используйте API-интерфейсы Butter для категорий, тегов и авторов, чтобы добавлять и фильтровать контент в своем блоге.

Список всех категорий и получать сообщения по категориям

Вызовите эти методы на onInit() жизненного цикла onInit() :

 methods: { ... getCategories() { butter.category.list() .then((res) => { console.log('List of Categories:') console.log(res.data.data) }) }, getPostsByCategory() { butter.category.retrieve('example-category', { include: 'recent_posts' }) .then((res) => { console.log('Posts with specific category:') console.log(res) }) } }, created() { ... this.getCategories() this.getPostsByCategory() } 

Завершение

Congrats! Вы успешно превратили свое статическое приложение Angular в приложение на базе CMS с использованием API контента, тем самым поддерживая безсерверную архитектуру. Ваша команда разработчиков может воспользоваться аспектами Angular, позволяющими сэкономить время, а вы сэкономили еще больше времени благодаря использованию CMS без сервера.