Russian (Pусский) translation by Alex Grigorovich (you can also view the original English article)



Введение
В этом уроке я расскажу вам шаг за шагом, как создать современное, гибридное, мобильное (iOS и Android) приложение для вашего сайта на WordPress с использованием новейших технологий. Мы будем использовать Ionic Framework, ECMAScript 6, npm, webpack и Apache Cordova.
В конце этого урока вы получите готовое приложение. Оно будет иметь только три модуля. Модуль, который отображает последние сообщения - Home, и модуль, который отображает сообщения - Post и и модуль, который отображает меню - Menu.



1. Инструменты
Ionic Framework
Красивый SDK с открытым исходным кодом для разработки фронтэнда потрясающих мобильных приложений с использованием веб-технологий.
Экосистема фреймворка Ionic велика, включает Ionic CLI (командную строку), Ionic Push (push-уведомления) и Ionic Platform (бэкэнд). В настоящее время это один из лучших проектов с открытым исходным кодом на GitHub,набравший более 19 000 звезд и с помощью которого создано более 600 000 приложений.
Ionic способен реализовать все потребности вашего приложения. Однако в этом уроке мы сосредоточимся только на Ionic Framework (или Ionic SDK), который представляет собой набор директив AngularJS (веб-компонентов) и сервисах.
ECMAScript 6 (ES6)
ECMAScript 2015 (6-е издание) - это текущая версия стандарта спецификации языка ECMAScript. ES6 официально утвержден и опубликован в качестве стандарта 17 июня 2015 года Генеральной Ассамблеей ECMA.
ECMAScript 6 дает вам доступ к множеству новых функций, многие из которых созданы по примеру CoffeeScript, в том числе использование стрелок в функциях, генераторы, классы и конструкции let. Хотя ES6 одобрен совсем недавно, вы можете использовать его уже сейчас, используя компилятор JavaScript, такой как Babel.
Диспетчер пакетов Node (npm)
Node Package Manager - самый популярный менеджер пакетов в мире. Количество пакетов в нем растет быстрее, чем в Ruby, Python и Javа вместе взятых. npm работает на Node.js.
Почему не Bower?
Мы выбираем npm, потому что использовать Bower и npm в одном проекте сложно, а поддержка CommonJS в Bower не проста. CommonJS определяет формат модуля для разрешения области JavaScript вне браузера, а npm поддерживает это. Модули COMMОJS могут потребоваться при использовании ES5 или ES6.
// ES5 var angular = require('angular');
// ES6 import angular from "angular";
webpack
На мой взгляд, webpack является новым словом в игровой индустрии, обходя сложные сценарии Grunt или Gulp, которые вам нужны для обслуживания webpack позволяет вам запрашивать файлы любого типа (.js, .coffee, .css, .scss, .png , .jpg, .svg и т. д.) и направлять их через загрузчики для создания статических файлов, доступных вашему приложению.
Разница между Grunt и Gulp заключается в том, что большинство ваших потребностей (минимизация и компиляция) может быть выполнена, в виде добавления некоторой конфигурации, нет необходимости создавать полноценные скрипты. Например, запрос файл Sass, его компиляция, создание приставок и вставка полученного миниатюрного CSS в ваше приложение будет так же легко, как написать строчку кода ниже:
{ test: /\.scss$/, loader: "style!css!autoprefixer!sass" }
Я не думаю, что мне нужно демонстрировать пример, используя Gulp или Grunt. Думаю, вы понимаете, о чем я говорю.
2. Нам понадобится
Работа над этим уроком предполагается, что у вас есть:
- базовое знание AngularJS и Ionic
- веб-сайт на WordPress, готовый к работе (с завершенной установкой)
- сервер с Node.js, npm, Bower (они нам понадобятся в некоторых случаях)
- И установленный Git с возможностью записи в папку проекта без sudo.
3 Установка
Прежде чем мы начнем, вам нужно будет установить две штуки:
- плагин WordPress, который превращает ваш блог в RESTFUL API
- и само приложение
RESTFUL API
Чтобы обрабатывать записи установленного сайта на WordPress, необходимо установить плагин WP REST API. Убедитесь, что вы установили версию 1.2.x, поскольку версия 2.x находится в процессе разработки.
- В WordPress перейдите в раздел Плагины> Добавить новый/Plugins > Add New.
- Найдите WP REST API (WP API).
- Нажмите Установить сейчас , чтобы установить плагин.
- Если установка прошла успешно, нажмите «Активировать плагин», чтобы активировать его.
Если установка прошла успешно, откройте браузер и введите http://example.com/wp-json. Вы должны будете увидеть результат, подобный приведенному ниже.
{ "name": "Lorem Ipsum blog", "description": "Just another WordPress site", "URL": "http://yourDomainName.com/wp-json", "routes": {}, "authentication": {}, "meta": {} }
Приложение
Чтобы установить приложение, скопируйте репозиторий, используйте следующие команды.
# Clone the repository and give it a name (here myTutorial) $ git clone https://github.com/tutsplus/Hybrid-WordPressIonicAngularJS.git myTutorial # Open the project $ cd myTutorial
Затем создайте файл конфигурации и установите все требуемые компоненты.
# Copy the default config to your personal config $ cp config/default.config.json config/config.json # Install dependencies $ npm install
Чтобы убедиться, что приложение и REST API работают вместе, откройте config/config.json. Это ваш файл конфигурации, который игнорирует Git. Затем измените базовый URL-адрес API на тот, который подходит для вашего сайта на WordPress.
{ "api": { "baseUrl": "http://yourDomainName.com/wp-json" } }
Запустите npm run devserver
и откройте ссылку http:// localhost:8080/webpack-dev-server/ в браузере. Если все работает правильно, вы увидите запущенное приложение , которое отображает ваши записи из WordPress. Я создал демонстрационное приложение, чтобы показать вам, чего можно ожидать.
Теперь, когда вы видите результат , позвольте рассказать о деталях. Обратите внимание на то, что этот код упрощен. Вы можете найти исходный код на GitHub.
4. Зависимости
Команда npm install
установила несколько библиотек. Некоторые из них являются необходимыми сразу, а остальные – будут необходимы в процессе разработки.
Необходимые компоненты
Необходимые компоненты- это компоненты, которые требуется вашему приложению для правильной работы при сборке.
"dependencies": { "ionic-sdk": "^1.0.0", "wp-api-angularjs": "^1.0.0" }
Обратите внимание, что ваше приложение напрямую не зависит от AngularJS, потому что ionic-sdk уже включает в себя файлы angular. Js, angular-animate.js, angular-sanitize.js и angular-ui-router.js.
wp-api-angularjs (Клиент WordPress WP API для AngularJS) представляет собой набор сервисов AngularJS, которые позволяют связываться с плагином API REST, установленному ранее. Вы можете увидеть полный список необходимых компонентов на GitHub.
Компоненты необходимые при разработке
Компонентами необходимыми при разработке в основном являются загрузчики webpack. Загрузчики - это функции, которые берут исходный код из файла, проводят некоторые изменения и возвращают новый исходный код в источник. Нам нужны загрузчики, которые обрабатывают файл ы типа .scss, .js (ES6), .html и .json. Вы можете увидеть полный список необходимых компонентов для разработки на GitHub.
5 Архитектура приложения
Я разрабатываю приложения, используя AngularJS, в течение длительного времени, и после многих экспериментов я выбрал для себя понравившуюся архитектуру:
- файлы, которые можно редактировать в находятся в папке
src/
или/lib
- каждому модулю AngularJS нужна отдельная папка
- каждый файл модуля
*.module.js
должен содержать уникальное имя (и быть единственным местом, где оно используется) - каждый файл модуля
*.module.js
должен обозначать все свои необходимые компоненты (даже если эти компоненты уже встроены в приложение)
- каждый файл модуля
*.module.js
должен содержать свои настройки, контроллеры, службы, фильтры и т.д.
- каждая конфигурация, контроллер, сервис, фильтр и т. Д. Должен экспортировать функцию (CommonJS)
- если модуль нуждается в определенном стиле, файл .scss должен находиться вместе с этим модулем.
Эти рекомендации являются очень полезными, т.к. они гарантируют, что в случае, если у вас есть слабо связанные модули, они могут использоваться несколькими приложениями без проблем.
Вот как выглядит структура папок приложения:
lib/ ├── menu/ │ └── menu.module.js │ └── menu.html ├── home/ │ └── home.module.js │ └── home.config.js │ └── home.controller.js │ └── home.html ├── post/ │ └── post.module.js │ └── post.config.js │ └── post.controller.js │ └── post.html ├── scss/ │ └── _variables.scss │ └── bootstrap.scss ├── index.js ├── index.html
Точка входа
При использовании веб-пакета необходима точка входа. Наша точка входа - lib/index.js. Она содержит основные зависимости приложения (например, ionic.bundle, который содержит AngularJS), наши произвольные модули и добавляет точку входа для Sass.
// Ionic, Angular & WP-API client import 'ionic-sdk/release/js/ionic.bundle'; import 'wp-api-angularjs/dist/wp-api-angularjs.bundle'; // Our modules import modHome from './home/home.module.js'; import modPost from './post/post.module.js'; import modMenu from './menu/menu.module.js'; // Style entry point import './scss/bootstrap';
Теперь, когда мы импортировали компоненты, мы можем создать модуль приложения. Давайте дадим имя прототипу нашего приложения. У него есть компоненты ionic
,wp-api-angularjs
и наши самописные модули в качестве необходимых для работы.
// Create our prototype module let mod = angular.module('prototype', [ 'ionic', 'wp-api-angularjs', modHome, modMenu, modPost ]);
После создания модуля мы можем экспортировать его в качестве стандартного модуля CommonJS.
export default mod = mod.name;
Здесь вы увидите отличный пример того, как должен выглядеть модуль AngularJS.
Маршрутизация
Наше приложение имеет боковое меню <ion-side-menu ui-view="menu">
, в котором будет отображаться модуль меню. В нем также есть раздел содержимого <ion-nav-view name="content">
, в котором будут отображаться модули Home и Post.
Директива ui-view
является частью UI-маршрутизатора, используемого Ionic. Он сообщает переменной $state
(услуга UI-router), где размещать ваши шаблоны. Аналогично, директива name
, прикрепленная к тегу <ion-nav-view>
, представляет собой настраиваемую Ionic-директиву, которая использует ui-view
в нижней части. Вы можете считать обе директивы одинаковыми.
Вот упрощенная версия статуса root
, статуса, в котором все модули распределены:
export default function($stateProvider) { 'ngInject'; return $stateProvider.state('root', { abstract: true, views: { '@': { template: `<ion-side-menus> <ion-side-menu-content> <ion-nav-bar class="bar-positive"></ion-nav-bar> <ion-nav-view name="content"></ion-nav-view> </ion-side-menu-content> <ion-side-menu side="left" ui-view="menu"></ion-side-menu> </ion-side-menus>` } } }); }
Дополнительные сведения о названиях представлений смотрите в документации на GitHub.
Модуль меню



lib/ ├── menu/ │ └── menu.module.js │ └── menu.html
Модуль меню очень прост. Его цель - добавить меню внутри тега <ion-side-menu>
. Без этого модуля боковое меню будет пустым. Модуль меню добавляет только файл конфигурации, который содержит компоненты ionic
и ui.router
.
import modConfig from './menu.config'; let mod = angular.module('prototype.menu', [ 'ionic', 'ui.router' ]); mod.config(modConfig); export default mod = mod.name;
Самая интересная часть - это конфигурация. Мы не будем создавать отдельное состояние для модуля меню, поскольку оно всегда доступно. Вместо этого мы добавим состояние root
для его содержания. Когда тег ui-view = "menu"
будет определён в состоянии root
, нам нужно будет использовать конструкцию menu@root
для ссылки на него.
export default function($stateProvider) { 'ngInject'; $stateProvider.decorator('views', (state, parent) => { let views = parent(state); if (state.name === 'root') { views['menu@root'] = { template: require("./menu.html") }; } return views; }); }
Модуль домашней страницы



lib/ ├── home/ │ └── home.module.js │ └── home.config.js │ └── home.controller.js │ └── home.html
home.module.js
В модуле домашней страницы отображаются последние записи на вашем сайте WordPress. У него есть конфигурационный файл, контроллер и ему нужны компоненты следующих библиотек:
ionic
ui.router
wp-api-angularjs
import modConfig from './home.config'; import modController from './home.controller'; let mod = angular.module('prototype.home', [ 'ionic', 'ui.router', 'wp-api-angularjs' ]); mod.config(modConfig); mod.controller('HomeController', modController); export default mod = mod.name
home.config.js
Конфигурация добавляет новое состояние root.home
с URL-адресом /home
, в котором есть шаблон и контроллер (оба находятся внутри модуля).
export default function($stateProvider) { 'ngInject'; $stateProvider.state('root.home', { url: "/home", views: { 'content@root': { template: require("./home.html"), controller: "HomeController as homeCtrl" } } }); }
home.controller.js
Это упрощенная версия логики контроллера Home. Он содержит две функции:
-
loadMore
: Эта функция заполняет даннымиvm.posts
. Она использует службу$wpApiPosts
, которая является частью библиотеки wp-api-angularjs. -
refresh
: Эта функция снова удаляет записи и вызывает функциюloadmore
.
export default function($scope, $log, $q, $wpApiPosts) { 'ngInject'; var vm = this; vm.posts = []; vm.loadMore = loadMore; vm.refresh = refresh; function refresh() { vm.posts = null; loadMore().finally(() => $scope.$broadcast('scroll.refreshComplete')); } function loadMore() { return $wpApiPosts.$getList().then((response) => { vm.posts = (vm.posts) ? vm.posts.concat(response.data) : response.data; $scope.$broadcast('scroll.infiniteScrollComplete'); }); } }
home.html
В шаблоне есть директива ion-refresher
, которая позволяет пользователям перезагружать страницу, потянув её на экране вниз. А также есть директива ion-infinite-scroll
, которая вызывает функцию loadMore
по завершению. Сообщения отображаются с помощью директивы ng-repeat
.
Совет. Используйте выражение track by
для лучшей производительности. Он минимизирует манипуляции с DOM, когда сообщение обновляется.
<ion-view> <ion-nav-title>Home</ion-nav-title> <ion-content> <ion-refresher pulling-text="Pull to refresh" on-refresh="homeCtrl.refresh()"></ion-refresher> <div class="list card" ng-repeat="post in homeCtrl.posts track by post.ID"> <!-- THE POST DETAILS --> </div> <ion-infinite-scroll immediate-check="true" on-infinite="homeCtrl.loadMore()"></ion-infinite-scroll> </ion-content> </ion-view>
Почтовый модуль



lib/ ├── post/ │ └── post.module.js │ └── post.config.js │ └── post.controller.js │ └── post.html
В модуле Post отображается только одно сообщение. Он содержит конфигурационный файл, контроллер, и зависит от тех же библиотек, что и модуль Home.
post.module.js
import modConfig from './post.config'; import modController from './post.controller'; let mod = angular.module('prototype.post', [ 'ionic', 'ui.router', 'wp-api-angularjs' ]); mod.config(modConfig); mod.controller('PostController', modController); export default mod = mod.name
Подобно модулю Home, конфигурация добавляет новое состояние root.post
с URL /post/: id
. Он также регистрирует вид и контроллер.
post.config.js
export default function($stateProvider) { 'ngInject'; $stateProvider.state('root.post', { url: "/post/:id", views: { 'content@root': { template: require("./post.html"), controller: "PostController as postCtrl" } } }); }
post.controller.js
Контроллер получает сообщение, указанное в ссылке /post/:id
через переменную $stateParams
(услуга маршрутизатора UI).
export default function ($scope, $log, $wpApiPosts, $stateParams) { 'ngInject'; var vm = this; vm.post = null; $scope.$on('$ionicView.loaded', init); function init() { $wpApiPosts.$get($stateParams.id).then((response) => { vm.post = response.data; }); } }
post.html
В шаблоне есть директива ion-spinner
, которая отображает загрузчик, в то время как данные извлекаются через API из WordPress. Когда сообщение загружается, мы используем карточку для рендеринга аватара автора, заголовка и содержимого сообщения.
Совет. Используйте выражение bindOnce
,::
(введенное в Angular 1.3), чтобы избежать проверки данных, которые не будет меняться.
<ion-view> <ion-nav-title>{{postCtrl.post.title}}</ion-nav-title> <ion-content> <ion-spinner ng-if="!postCtrl.post"></ion-spinner> <div class="list card" ng-if="postCtrl.post"> <div class="item item-avatar"> <img ng-src="{{::postCtrl.post.author.avatar}}"> <h2>{{::postCtrl.post.author.name}}</h2> <p>{{::postCtrl.post.date | date:'medium'}}</p> </div> <div class="item item-body"> <img class="full-image" ng-src="{{::postCtrl.post.featured_image.attachment_meta.sizes.medium.url}}"> <h2>{{::postCtrl.post.title}}</h2> <p ng-bind-html="::postCtrl.post.content"></p> </div> </div> </ion-content> </ion-view>
Стиль оформления (Sass)
lib/ ├── scss/ │ └── _variables.scss │ └── bootstrap.scss
Файл bootstrap.scss
, который мы импортировали в нашей точке входа, прост:
@import "./variables"; @import "~ionic-sdk/scss/ionic";
Во-первых, мы импортируем наши переменные. Затем мы импортируем стили Ionic. Импорт наших переменных, перед стилями Ionic позволяет нам перезаписать любые переменные Sass, которые объявлены в Ionic.
Например, если вы хотите, чтобы цвет positive был красным, а не синим, вы можете перезаписать его следующим образом:
$positive: red !default;
6. Android and iOS
Установка
Выполните следующие команды внутри папки проекта и выберите платформу, на которой хотите собрать приложение.
$ cp config.dist.xml config.xml $ npm run installCordova Which platforms do you want to build? (android ios):
Помимо установки платформ в папке /platform
, скрипт установит еще один плагин. Для демонстрации нам нужен плагин cordova-plugin-whitelist
. Необходимо разрешить приложению отправлять запросы через API-интерфейс WordPress, который мы создали ранее.
Если вы откроете файл config.xml, вы увидите, что мы открываем доступ из любого источника (<access origin="*" />
). Конечно, это только для демонстрационных целей. Если вы разрабатываете приложение для публикации, убедитесь, что вы ограничиваете доступ следующим образом:
<access origin="http://example.com" />
Android
Необходимые компоненты
- Android SDK
- Ant
Запуск команды npm run Android
- это ярлык для команд rm -rf www/* && webpack && cordova run android
. Это удаляет всё в папке www, выгружает в него не сжатую версию приложения и запускает команду android
. Если Android-устройство подключено (запустите adb devices
чтобы убедиться в этом), команда загрузит приложение на устройство, в другом случае будет использован эмулятор Android.
# Run Android $ npm run runAndroid
iOS
Необходимые компоненты
- OS X
- Xcode
Если у вас нет устройства Apple, вам нужно установить iOS Simulator. Он хорош и лучше, чем эмулятор Android.
$ sudo npm install -g ios-sim
Запуск команды npm run runIosEmulator
– это ярлык для команд rm -rf www/* && webpack && cordova run ios
. Команда npm run runIosDevice
- это ярлык для команд rm -rf www/* && webpack && cordova run ios
-device.
# Run iOS $ npm run runIosEmulator $ npm run runIosDevice
Заключение
В этом уроке я попытался показать вам, как легко создать гибридное мобильное приложение для сайта на WordPress. Теперь у вас будет возможность:
- создавать слабосвязанные модули, которые соответствуют спецификациям CommonJS
- импортировать модули CommonJS для ECMAScript 6
- использовать REST API WordPress (с wp-api-angularjs)
- использовать Ionic Framework для создания отличного пользовательского интерфейса
- использовать webpack для сборки приложения
- использовать программу Cordova для запуска приложения на iOS и Android
Если вы хотите развиваться дальше, взгляните на проект, который я создал несколько месяцев назад, WordPress Hybrid Client.
Гибридный клиент WordPress
Гибридный клиент WordPress (WPHC) - это проект с открытым исходным кодом, доступным на GitHub, который позволяет бесплатно создавать версии вашего сайта WordPress на iOS и Android. WPHC основан на том же наборе технологий, что и в этом уроке.
WPHC включает в себя следующие функции:
- всплывающие уведомления
- закладки (автономный режим)
- поддержку Google Analytics
- автоматическое обновление контента
- кнопки для социальных сетей
- настройки чтения (размер пост-шрифта)
- поддержку нескольких языков (английский, французский, китайский)
- бесконечную прокрутку
- подсветку кода для технических блогов
- кэширование изображений
- рейтинг приложений