Статьи

Соединение Angular и WordPress API с помощью wp-api-angular

В этом руководстве вы узнаете, как работать с библиотекой wp-api-angular, которая позволяет взаимодействовать с WordPress API из приложений Angular 2+ . Эта библиотека поддерживает все основные ресурсы WP, включая пользователей, публикации, комментарии, медиа, таксономии и т. Д. Она также довольно проста в использовании, так что вы получите представление в кратчайшие сроки.

Чтобы увидеть библиотеку в действии, мы собираемся кодировать следующие функции:

  • Аутентификация с использованием JWT
  • Список пользователей
  • Список сообщений
  • Создание и редактирование постов
  • Удаление постов

К концу статьи вы познакомитесь с этой библиотекой и будете готовы использовать ее самостоятельно.

Исходный код этого руководства доступен на GitHub .

Я предполагаю, что вы используете Angular 5, но все объясненные концепции должны быть применимы и к Angular 2.

Укладка фундаментов

Настройка WordPress

Прежде чем мы приступим к написанию кода, необходимо кое-что позаботиться. Прежде всего, обратите внимание, что API, который мы собираемся использовать, работает только с собственной версией WordPress . Для веб-версии (которую можно настроить через сайт WordPress ) существует отдельный API, который имеет много схожих концепций, хотя он все же сильно отличается.

Вы также должны включить постоянные ссылки — что необходимо для правильной работы клиента API. Для Nginx вам нужно добавить следующую строку в файл nginx.conf :

try_files $uri $uri/ /index.php?$args; 

Более подробную информацию и объяснения о том, как включить постоянные ссылки, можно найти в этом руководстве по WordPress Codex .

Наконец, мы должны позаботиться о безопасности WordPress, которая, как говорится, превыше всего. Для этого требуется специальный плагин под названием JWT Authentication . Мы собираемся использовать его для аутентификации нашего API-клиента с помощью специальных токенов (этот подход довольно распространен в наши дни).

Вот и все. Если вы хотите узнать больше об API WordPress в целом, просмотрите эту статью . Когда вы будете готовы, перейдите к следующему шагу, и давайте посмотрим на клиент Angular WordPress в действии!

Начальная загрузка углового приложения

Теперь, когда мы подготовили WordPress, создайте новое приложение Angular, запустив:

 ng new wp-api 

Это собирается создать каркас для приложения. Мы не будем подробно обсуждать его структуру, но вы можете найти больше информации в нашей серии Angular .

Затем cd в каталог и установите саму библиотеку:

 cd wp-api npm install -g typings npm install wp-api-angular --save 

Теперь нам нужно импортировать соответствующие компоненты в файл src/app/app.module.ts :

 // ... other imports import { Http } from '@angular/http'; import { HttpClientModule, HttpClient } from '@angular/common/http'; import { WpApiModule, WpApiLoader, WpApiStaticLoader } from 'wp-api-angular'; 

WpApiModule также должен быть добавлен в блок imports . Обратите внимание, что мы должны использовать экспортированную фабрику для компиляции AoT или Ionic :

 // ... imports @NgModule({ declarations: [ // ... omitted ], imports: [ BrowserModule, FormsModule, HttpClientModule, // <--- WpApiModule.forRoot({ // <--- provide: WpApiLoader, useFactory: (WpApiLoaderFactory), deps: [Http] }) ] // ... }) 

Вот сама фабрика:

 export function WpApiLoaderFactory(http: Http) { return new WpApiStaticLoader(http, 'http://YOUR_DOMAIN_HERE/wp-json/wp/v2/', ''); } 

Не забудьте указать здесь свое доменное имя!

Наконец, давайте также добавим несколько импортов в файл app.components.ts :

 import { Component } from '@angular/core'; import { Observable } from 'rxjs'; import { NgForm } from '@angular/forms'; import { HttpClientModule, HttpClient } from '@angular/common/http'; import { Headers } from '@angular/http'; // ... 

Нам понадобится NgForm для создания форм, HTTP-модулей для взаимодействия с API и Headers для аутентификации клиента.

Начальная настройка завершена, и мы можем перейти к следующему разделу.

Аутентификация

Прежде чем взаимодействовать с API, нам нужно ввести механизм аутентификации . Как я уже упоминал выше, будет использоваться аутентификация на основе токенов, поэтому давайте добавим переменную token в app.components.ts :

 export class AppComponent { token = null; // ... } 

Также app.component.html файл app.component.html , добавив новый блок:

 <div> <app-authentication [(token)]='token'></app-authentication> </div> 

Чтобы это работало, требуется отдельный компонент, поэтому сгенерируйте его сейчас:

 ng generate component authentication 

Импортируйте необходимые модули в файл src/app/authentication/authentication.component.ts :

 import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; import { HttpClientModule, HttpClient } from '@angular/common/http'; // ... 

Процесс аутентификации будет очень простым: пользователь должен ввести свои логин и пароль, отправить форму, и специальный токен будет возвращен, если учетные данные верны. Этот токен будет затем использоваться для выполнения запросов API. Поэтому давайте напишем пользователя и добавим вход и выход для AuthenticationComponent :

 // ... export class AuthenticationComponent implements OnInit { user = { login: '', password: '' } @Input() token; @Output() tokenChange = new EventEmitter<string>(); // ... } 

Конечно, вы можете определить пользователя как модель, но для целей этой демонстрации это не обязательно. Что касается конструктора, передайте ему HttpClient :

 // ... constructor( private http: HttpClient ) { } 

Следующий код метод auth . Это так же просто, как отправка запроса POST на соответствующий URL с учетными данными и ожидание ответа:

 // ... auth() { this.http.post('http://YOUR_DOMAIN/wp-json/jwt-auth/v1/token', { username: this.user.login, password: this.user.password }).subscribe((data) => { if (data['token']) { // if token is returned this.token = data['token']; this.tokenChange.emit(this.token); } }); } 

Еще раз, не забудьте вставить свое доменное имя в URL.

Компонент готов, и последнее, что нужно сделать в этом разделе, — создать соответствующую форму. Он должен отображаться только в том случае, если токен имеет значение null . Когда форма отправлена, метод auth должен быть вызван:

 <form *ngIf='token == null' (ngSubmit)='auth()'> </form> 

Удалите форму, добавив два поля и кнопку « Отправить» :

 <form *ngIf='token == null' (ngSubmit)='auth()'> <div class='form-group'> <label for='login'>Login</label> <input type='text' class='form-control' [(ngModel)]='user.login' name='login' id='login' required> </div> <div class='form-group'> <label for='password'>Password</label> <input type='password' class='form-control' [(ngModel)]='user.password' name='password' id='password' required> </div> <button type="submit" class="btn btn-success">Submit</button> </form> 

Это оно! Функция аутентификации завершена, и мы можем начать играть с самим API.

Список пользователей

Обычно читать через API проще, чем писать, поэтому давайте попробуем составить список пользователей нашего веб-сайта на платформе WordPress. Создайте новый компонент UserList :

 ng generate component user-list 

Внутри src/app/user-list/user-list.component.ts вам нужно будет импортировать модуль WpApiUsers, а также некоторые другие модули:

 import { Component, OnInit, Input } from '@angular/core'; import { WpApiUsers } from 'wp-api-angular'; import { Headers } from '@angular/http'; // ... 

Мы собираемся хранить пользователей внутри массива users , который изначально пуст:

 // ... export class UserListComponent implements OnInit { users = []; } 

Передайте WpApiUsers в конструктор и вызовите метод getUserList :

 // ... constructor( private wpApiUsers: WpApiUsers ) { this.getUserList(); } 

Теперь нам нужно кодировать getUserList . Каждый метод, представленный клиентом API, возвращает наблюдаемую информацию, которую можно преобразовать в обещание с помощью toPromise . Итак, чтобы получить список всех пользователей, мы должны вызвать метод getList , преобразовать его в обещание и назначить переменную users с возвращенным массивом:

 // ... getUserList() { this.wpApiUsers.getList() .toPromise() .then( response => { let json: any = response.json(); this.users = json; }) } 

Как видите, ничего сложного здесь нет. Интересно, что нам даже не нужен токен для выполнения этого метода. Поэтому просто визуализируйте пользователей в цикле:

 <div> <h2>Users:</h2> <div *ngFor="let user of users"> Name: {{user.name}} </div> </div> 

Компонент user-list должен быть добавлен в файл app.component.html :

 <!-- ... --> <div> <user-list></user-list> </div> 

Работа с постами

Создание сообщений

Теперь давайте попробуем реализовать несколько более сложную функцию и позволить пользователям добавлять новые сообщения через API. Создайте отдельный post-new компонент:

 ng generate component post-new 

Импортируйте необходимые модули в filesrc/app/post-new/post-new.component.ts :

 import { Component, OnInit, Input } from '@angular/core'; import { WpApiPosts } from 'wp-api-angular'; import { Headers } from '@angular/http'; // ... 

Модуль WpApiPosts будет главной звездой здесь.

Затем предоставьте token в качестве входных данных и наберите модель post :

 // ... export class PostNewComponent implements OnInit { @Input() token; new_post = { title: '', content: '', status: 'publish' } } 

По крайней мере, каждое сообщение должно содержать заголовок, некоторый контент и статус (который мы жестко кодируем как publish чтобы мгновенно опубликовать новый пост).

Конструктор должен принять WpApiPosts :

 // ... constructor( private wpApiPosts: WpApiPosts ) { } 

Теперь давайте создадим метод добавления поста. Сначала закодируйте логику аутентификации, установив заголовок Authorization :

 // ... createPost() { let headers: Headers = new Headers({ 'Authorization': 'Bearer ' + this.token }); } 

Теперь мы можем просто взять переменную headers и передать ее методу WpApiPosts модуля WpApiPosts :

 // ... createPost() { let headers: Headers = new Headers({ 'Authorization': 'Bearer ' + this.token }); this.wpApiPosts.create(this.new_post, { headers: headers }) .toPromise() .then( response => { console.log(response); }) } 

Как насчет формы? Ну, это действительно очень просто:

 <!-- src/app/post-new/post-new.component.html --> <div> <h2> Post Creation </h2> <form (ngSubmit)='createPost()'> <div class="form-group"> <label for="title">Post title</label> <input type="text" class="form-control" [(ngModel)]='new_post.title' name='title' id="title" required> </div> <div class="form-group"> <label for="content">Post content</label> <textarea class="form-control" id="content" required [(ngModel)]='new_post.content' name='content'></textarea> </div> <button type="submit" class="btn btn-success">Submit</button> </form> </div> 

Когда форма отправлена, мы вызываем метод createPost .

Не забудьте сделать рендеринг post-new компонента:

 <!-- app.component.html --> <!-- ... --> <div> <h3 *ngIf='token == null'> Please, authorize to create a post </h3> <post-new *ngIf='token' [token]='token'></post-new> </div> 

Мы проверяем, что токен установлен, и если нет, мы просим пользователя пройти аутентификацию.

Список сообщений

Хорошо, мы добавили возможность создавать сообщения. Почему бы нам не отобразить их на странице? Создайте еще один компонент:

 ng generate component post-list 

Импортируйте необходимые модули, включая WpApiPosts внутри WpApiPosts src/app/post-list/post-list.component.ts :

 import { Component, OnInit, Input } from '@angular/core'; import { WpApiPosts } from 'wp-api-angular'; import { Headers } from '@angular/http'; // ... 

Укажите вход и массив posts :

 // ... export class PostListComponent implements OnInit { @Input() token; posts = []; } 

Код конструктора, который должен вызывать метод getPosts :

 // ... constructor(private wpApiPosts: WpApiPosts) { this.getPosts(); } 

Нам не нужно проверять подлинность для получения сообщений, поэтому давайте использовать тот же подход, что и раньше:

 // ... getPosts() { this.wpApiPosts.getList() .toPromise() .then( response => { let json: any = response.json(); this.posts = json; }); } 

Теперь визуализируем массив сообщений:

 <!-- src/app/post-list/post-list.component.html --> <div> <h2>Latests Posts:</h2> <hr> <div *ngFor='let post of posts'> <h1 [innerHTML]='post.title.rendered'></h1> <p [innerHTML]='post.content.rendered'></p> <hr> </div> </div> 

Наконец, отобразите компонент:

 <!-- app.component.html --> <!-- ... --> <div> <post-list [token]='token'></post-list> </div> 

Уничтожение постов

Далее я бы хотел добавить возможность уничтожать посты. Эта функция может быть реализована в том же компоненте PostList . Просто добавьте кнопку Удалить рядом с каждым сообщением:

 <!-- src/app/post-list/post-list.component.html --> <div> <h2>Latests Posts:</h2> <hr> <div *ngFor='let post of posts'> <h1 [innerHTML]='post.title.rendered'></h1> <p [innerHTML]='post.content.rendered'></p> <button *ngIf='token' (click)='deletePost(post.id, $index)'>Delete</button> <hr> </div> </div> 

Обратите внимание, что эта кнопка отображается только при наличии токена. Также deletePost компонент, добавив метод deletePost :

 // src/app/post-list/post-list.component.ts // ... deletePost(id: number, index: number) { let headers: Headers = new Headers({ 'Authorization': 'Bearer ' + this.token }); this.wpApiPosts.delete(id, { headers: headers }) .toPromise() .then( response => { if (response['ok'] == true) { this.posts.splice(index,1); } }) } 

В принципе, ничего нового здесь. Мы добавляем токен в заголовки и вызываем метод delete который принимает идентификатор сообщения и его индекс в массиве posts . Если запрос выполнен успешно, удалите сообщение из массива.

Редактирование сообщений

Последняя функция, которую мы собираемся представить сегодня, — это возможность редактировать сообщения. Давайте создадим новый компонент:

 ng generate component post-edit 

На этот компонент будут ссылаться из PostList . В частности, я хотел бы добавить кнопку « Редактировать» рядом с каждым сообщением и отображать шаблон PostEdit при каждом нажатии:

 <!-- src/app/post-list/post-list.component.html --> <div> <h2>Latests Posts:</h2> <hr> <div *ngFor='let post of posts'> <div *ngIf='editingPost != post; else postEdit'> <h1 [innerHTML]='post.title.rendered'></h1> <p [innerHTML]='post.content.rendered'></p> <button *ngIf='token' (click)='deletePost(post.id, $index)'>Delete</button> <button *ngIf='token' (click)='updatePost(post)'>Edit</button> <hr> </div> </div> <ng-template #postEdit> <post-edit [post]='editingPost' [token]='token' (finish)='editingPost = null; getPosts()'></post-edit> </ng-template> 

PostListComponent , введя переменную updatePost метод updatePost , который собирается назначить editingPost с правильным значением:

 // src/app/post-list/post-list.component.ts // ... export class PostListComponent implements OnInit { @Input() token; posts = []; editingPost = null; updatePost(post) { this.editingPost = post; } } 

Перейдите к PostEditComponent и импортируйте все необходимые модули:

 // src/app/post-edit/post-edit.component.ts import { Component, OnInit, Input, EventEmitter, Output } from '@angular/core'; import { WpApiPosts } from 'wp-api-angular'; import { Headers } from '@angular/http'; // ... 

Этот компонент будет иметь два входа: токен и фактическое сообщение для редактирования. Также у нас будет вывод ( EventEmitter ):

 // ... export class PostEditComponent implements OnInit { @Input() token; @Input() post; @Output() finish = new EventEmitter<void>(); post_edit = { title: '', content: '' } } 

Как только компонент будет инициализирован, присвойте переменную post_edit с правильным заголовком и содержимым, взятым из переменной post :

 // ... ngOnInit() { this.post_edit['title'] = this.post.title.rendered; this.post_edit['content'] = this.post.content.rendered; } 

Теперь updatePost метод updatePost , который будет выполнять аутентификацию. Обновите сообщение и отправьте событие:

 // ... updatePost() { let headers: Headers = new Headers({ 'Authorization': 'Bearer ' + this.token }); this.wpApiPosts.update(this.post.id, this.post_edit, { headers: headers }) .toPromise() .then( response => { this.finish.emit(null); }) } 

Обратите внимание, что метод update принимает как идентификатор сообщения, так и новое значение для заголовка и содержимого.

Вот форма для редактирования поста:

 <!-- src/app/post-edit/post-edit.component.html --> <div> <h2> Post Editing </h2> <form (ngSubmit)='updatePost()'> <div class="form-group"> <label for="title">Post title</label> <input type="text" class="form-control" [(ngModel)]='post_edit.title' name='title' id="title" required> </div> <div class="form-group"> <label for="content">Post content</label> <textarea class="form-cont rol" id="content" required [(ngModel)]='post_edit.content' name='content'></textarea> </div> <button type="submit" class="btn btn-success">Submit</button> </form> </div> 

Вот и все: функция редактирования готова! Теперь вы можете загрузить сервер, выполнив:

 ng serve --open 

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

Вывод

В этой статье мы обсудили использование клиента WordPress API для Angular. Мы увидели это в действии, представив функцию аутентификации, перечислив пользователей и сообщения, а также добавив возможность создавать и манипулировать сообщениями. Этот клиент позволяет вам работать с другими ресурсами, такими как медиа и комментарии, но все эти взаимодействия очень похожи на те, о которых мы говорили здесь.

Надеюсь, теперь вы готовы применить представленную здесь информацию на практике, но не стесняйтесь, присылайте мне свои вопросы! Как всегда, спасибо, что остаетесь со мной и до следующего раза.