В этом руководстве вы узнаете, как работать с библиотекой 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. Мы увидели это в действии, представив функцию аутентификации, перечислив пользователей и сообщения, а также добавив возможность создавать и манипулировать сообщениями. Этот клиент позволяет вам работать с другими ресурсами, такими как медиа и комментарии, но все эти взаимодействия очень похожи на те, о которых мы говорили здесь.
Надеюсь, теперь вы готовы применить представленную здесь информацию на практике, но не стесняйтесь, присылайте мне свои вопросы! Как всегда, спасибо, что остаетесь со мной и до следующего раза.