介绍
在本教程中,我将逐步向您介绍如何使用最新技术为WordPress网站创建现代的,混合的,移动应用程序(iOS和Android)。 我们将使用Ionic Framework , ECMAScript 6 , npm , webpack和Apache Cordova 。
在本教程的最后,您将获得以下应用程序。 它只有三个模块,一个用于显示最新帖子的“ 主页”模块,一个用于显示特定帖子的“ 帖子”模块,以及一个用于显示菜单的“ 菜单”模块。
![模组](https://cms-assets.tutsplus.com/uploads/users/956/posts/24170/image/devices_all.jpg)
1.工具
离子框架
漂亮的开源前端SDK,用于通过Web技术开发出色的移动应用程序。
Ionic Framework生态系统很大,包括Ionic CLI (命令行工具), Ionic Push (简易推送通知)和Ionic Platform (后端服务)。 目前,它是GitHub上最重要的开源项目之一,拥有超过19,000个星标,创建了超过60万个应用程序。
Ionic满足您所有应用程序的需求。 但是,在本教程中,我将只关注Ionic Framework(或Ionic SDK),它是一组AngularJS指令( Web组件 )和服务。
ECMAScript 6(ES6)
ECMAScript 2015(第6版)是ECMAScript语言规范标准的当前版本。 ES6已于2015年6月17日由ECMA大会正式批准并作为标准发布。
ECMAScript 6使您可以访问许多新功能,其中许多功能受CoffeeScript的启发,包括箭头功能,生成器,类和让作用域。 即使ES6最近获得批准,您现在也可以使用JavaScript编译器(例如Babel)使用它。
节点程序包管理器(npm)
Node Package Manager是世界上最受欢迎的软件包管理器。 软件包的数量增长速度超过了Ruby,Python和Java的总和。 npm在Node.js上运行。
为什么不凉亭?
我们选择npm,因为在同一项目中同时使用Bower和npm会很痛苦,并且Bower对CommonJS的支持并不简单。 CommonJS定义了一种模块格式来解决浏览器外部JavaScript范围,而npm支持此格式。 使用ES5或ES6可能需要CommonJS模块。
// ES5
var angular = require('angular');
// ES6
import angular from "angular";
网络包
在我看来, 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的机器(出于某些依赖性,我们将需要它)
- 在项目文件夹上安装了具有sudo且没有写权限的Git
3.安装
在开始之前,您将需要安装两件东西:
- WordPress插件,可将您的博客转变为RESTFUL API
- 应用程序本身
RESTFUL API
要获取WordPress安装的帖子,您需要安装WP REST API插件 。 确保安装版本1.2.x,因为即将安装版本2.x。
- 在WordPress中,转到插件>添加新内容 。
- 搜索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会忽略它。 将API的基本URL更改为您的WordPress安装的URL 。
{
"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 (用于AngularJS的WordPress WP API客户端)是一组AngularJS服务,允许与您先前安装的REST API插件进行通信。 您可以在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
入口点
使用webpack时,需要一个入口点。 我们的入口是lib / index.js 。 它包含我们应用程序的基本依赖项(例如包含AngularJS的ionic.bundle ),我们的自制模块,并添加了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">
,其中将显示“ 主页”和“ 帖子”模块。
ui-view
指令是Ionic使用的UI路由器的一部分。 它告诉$state
(UI路由器服务)在何处放置模板。 同样,附加到<ion-nav-view>
的name
指令是一个自定义的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>`
}
}
});
}
菜单模块
lib/
├── menu/
│ └── menu.module.js
│ └── menu.html
菜单模块非常简单。 其目的是在<ion-side-menu>
内添加<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
配置使用/home
URL添加一个新状态root.home
,该URL具有一个模板和一个控制器(均位于模块内)。
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
“ 帖子”模块仅显示一个帖子。 它具有一个配置文件,一个控制器,并且依赖于与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模块类似,该配置使用/post/:id
URL添加一个新状态root.post
。 它还注册一个视图和一个控制器。
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
控制器通过$stateParams
服务(UI路由器服务)检索url /post/:id
指定的/post/:id
。
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
指令,可在从WordPress REST API提取数据时显示加载程序。 加载帖子后,我们使用Ionic卡渲染作者的头像,帖子标题和帖子内容。
提示 :使用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>
风格(无礼)
lib/
├── scss/
│ └── _variables.scss
│ └── bootstrap.scss
我们在入口点导入的bootstrap.scss
文件非常简单:
@import "./variables";
@import "~ionic-sdk/scss/ionic";
首先,我们导入变量。 然后,我们导入离子样式。 在Ionic之前导入变量可以使我们覆盖Ionic声明的Sass变量。
例如,如果你想被染红了积极的颜色,而不是蓝色,则可以覆盖它是这样的:
$positive: red !default;
6. Android和iOS
安装
在项目文件夹中运行以下命令,然后选择要构建的平台。
$ cp config.dist.xml config.xml
$ npm run installCordova
Which platforms do you want to build? (android ios):
除了在/platforms
文件夹中安装平台之外,该脚本还将安装一个插件。 对于演示,我们需要cordova-plugin-whitelist
插件。 必须允许应用程序查询我们之前创建的WordPress REST API。
如果打开config.xml ,则会看到我们允许访问任何种类的源( <access origin="*" />
)。 当然,这仅用于演示目的。 如果将应用程序部署到生产环境,请确保按以下方式限制访问:
<access origin="http://example.com" />
安卓系统
先决条件
- Android SDK
- 蚂蚁
运行npm run runAndroid
命令是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网站创建混合移动应用程序有多么容易。 您现在应该能够:
如果您想走得更远,那么请看一下我几个月前创建的一个项目WordPress Hybrid Client 。
WordPress Hybrid Client(WPHC)是GitHub上的一个开源项目,可帮助您免费创建WordPress网站的iOS和Android版本。 WPHC基于我们在本教程中使用的相同技术堆栈。
WPHC包括以下功能: