与Angular.js框架一起工作是快速而有意义的,并且与WordPress结合使用,可以在很短的时间内创建一个非常好的SPA(单页应用程序)。 借助WordPress提供的所有CMS控件和插件,这是一个有趣的捷径。
设置主题
我们将从开始使用_tk
样板主题开始创建一个新主题。 这是Automattic的_s
下划线主题的实现,但实现了Twitter的Bootstrap。
从GitHub抓取主题,并将文件放在themes
目录中:
$ cd themes
$ wget https://github.com/Themekraft/_tk/archive/master.zip
wp-content/themes/$ unzip master.zip
Archive: master.zip
69acda231e2a2f8914374df81b89a7aa37d594fa
creating: _tk-master/
inflating: _tk-master/404.php
inflating: _tk-master/archive.php
inflating: _tk-master/comments.php
inflating: _tk-master/content-page.php
inflating: _tk-master/content-single.php
...
## Rename The Directory
$ mv _tk-master/ angular-bootstrap
$ rm -f master.zip
现在我们有了_tk
starter主题,我们将需要从主题目录中获取npm
包angular
和angular-route
(我们使用的名称是angular-bootstrap
)。
$ cd wp-angular
$ npm init
#follow the prompts to create your package.json file
...
"author": "",
"license": "ISC"
}
Is this ok? (yes) yes
## Install The Packages
$ $ npm install angular angular-route --save
- 你必须初始化
npm
与themes目录内npm init
,以创造package.json
,该文件npm
用来管理项目。 - 通过在
npm install angular angular-route --save
命令中使用--save
标志,我们告诉npm
将模块作为依赖项添加到我们的项目中。 - 将来,如果我们需要与其他开发人员共享该项目,他们只需要在与
package.json
相同的目录中运行npm install
即可获取软件包。
现在,您将在主题内的node_modules
目录中拥有这些软件包。 看一下目录,您将能够看到几个js文件。 我们将使用angular.min.js
进行开发
初始化Angular
要将angular.min.js
包含在WordPress中,我们需要修改functions.php
文件,以便我们可以在WordPress中加入脚本。
在functions.php中,找到_tk_scripts()
函数,并将以下内容附加到该函数的底部:
//Load angular
wp_enqueue_script('angularjs', get_template_directory_uri() .'/node_modules/angular/angular.min.js');
wp_enqueue_script('angularjs-route', get_template_directory_uri() .'/node_modules/angular-route/angular-route.min.js');
wp_enqueue_script('scripts', get_stylesheet_directory_uri() . '/js/scripts.js', array( 'angularjs', 'angularjs-route' ));
您还需要创建js/scripts.js
现在只需创建一个空白文件。
现在,在浏览器中刷新主题,在开发人员工具中,您将可以看到angular.min.js
包含的angular.min.js
。
使用局部
Angular.js有一个很棒的系统,它只能更新部分HTML。 要利用此功能和angular-route
模块,我们将需要在主题内部创建一个名为partials
的目录。
$ mkdir partials
在partials
目录中,创建一个名为main.html
的文件以进行测试,然后在其中添加任何您喜欢HTML。
本地化WordPress的局部路径
为了使Angular能够加载部分,我们必须提供完整的URL。 使用get_stylesheet_directory_uri()
方法时遇到了一些麻烦,但请自己尝试。 如果不起作用,请使用完整的URL。
将以下内容添加到_tk_scripts
函数中,在该函数中,您在最后一步中添加了angularjs
和angular-route
行:
// With get_stylesheet_directory_uri()
wp_localize_script('scripts', 'localized',
array(
'partials' => get_stylesheet_directory_uri() . '/wp-content/themes/angular-bootstrap/partials/'
)
);
如果失败(在写这篇文章时是给我的),请输入URL,例如
// With hardcoded value
wp_localize_script('scripts', 'localized',
array(
'partials' => 'https://www.mydomaind.com/wp-content/themes/angular-bootstrap/partials/'
)
);
启用WP-API
为了使Angular使用WordPress,我们需要启用WP-API REST插件。 这很简单,因为它只是安装插件。
从git下载并安装插件,然后在plugins
目录中运行以下命令:
git clone git@github.com:WP-API/WP-API.git json-rest-api
然后在您的wp-admin
面板中启用该插件。 启用后,您将可以在your-wordpress.com/wp-json
上看到JSON输出。
建设路线
路由构成了博客的特定页面。 我们现在可以为main.html
部分定义一个,并将其配置为显示在WordPress的索引页上。
首先确保通过ng-app
属性定义了Angular.js应用,然后在header.php
进行以下操作:
<!DOCTYPE html>
<html <?php language_attributes(); ?> ng-app="wp">
<head>
<base href="/">
在这里,我们使用ng-app
属性调用应用wp
。 另外,我们设置base
标记,以便Angular可以找到我们在WP-API
启用的JSON。
将以下内容添加到js/scripts.js
:
angular.module('wp', ['ngRoute'])
.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl: localized.partials + 'main.html',
controller: 'Main'
})
})
.controller('Main', function($scope, $http, $routeParams) {
$http.get('wp-json/posts/').success(function(res){
$scope.posts = res;
});
});
现在在partials/main.html
添加以下内容:
<ul>
<li ng-repeat="post in posts">
<a href="{{post.slug}}">
{{post.title}}
</a>
</li>
</ul>
最后在index.php
,直接在get_header.php()
,在div
标签上添加Angular属性ng-view
。
刷新WordPress的索引,博客文章的项目符号列表现在将显示在主页上。
这是因为ng-controller
从scripts.js
调用了Main
控制器,并且ng-view
属性指定了Angular的渲染位置。
通过子弹显示帖子
现在,我们添加通过URL插件显示WordPress博客的路由。
打开js/scripts.js
并调整文件,使其内容如下:
angular.module('wp', ['ngRoute'])
.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl: localized.partials + 'main.html',
controller: 'Main'
})
.when('/:slug', {
templateUrl: localized.partials + 'content.html',
controller: 'Content'
})
.otherwise({
redirectTo: '/'
});
})
.controller('Main', function($scope, $http, $routeParams) {
$http.get('wp-json/posts/').success(function(res){
$scope.posts = res;
});
})
.controller('Content',
['$scope', '$http', '$routeParams', function($scope, $http, $routeParams) {
$http.get('wp-json/posts/?filter[name]=' + $routeParams.slug).success(function(res){
$scope.post = res[0];
});
}
]
);
通过添加Content
控制器,我们可以为JSON帖子指定$http.get
URI,并指定slug
作为filter参数。
为此,我们使用以下代码: $http.get('wp-json/posts/?filter[name]=' + $routeParams.slug)
。
注意:为了使/:slug
路由正常工作,必须在wp-admin
中将/%postname%/
指定为永久链接结构。
确保使用以下内容设置content.html
:
{{post.title}}
{{post.content}}
现在,如果刷新页面,则可以通过上一步中创建的项目符号列表中的链接导航到博客文章。
在WordPress中使用Angular Services
到目前为止,我们已经看到了如何创建路由并开始使用wp-json
API。 在开始编写任何逻辑之前,我们需要一个地方,它在Angular service
(在本示例中,我们使用Factory
服务)。
创建一个新文件js/services.js
并添加以下代码以检索类别和帖子:
function ThemeService($http) {
var ThemeService = {
categories: [],
posts: [],
pageTitle: 'Latest Posts:',
currentPage: 1,
totalPages: 1,
currentUser: {}
};
//Set the page title in the <title> tag
function _setTitle(documentTitle, pageTitle) {
document.querySelector('title').innerHTML = documentTitle + ' | AngularJS Demo Theme';
ThemeService.pageTitle = pageTitle;
}
//Setup pagination
function _setArchivePage(posts, page, headers) {
ThemeService.posts = posts;
ThemeService.currentPage = page;
ThemeService.totalPages = headers('X-WP-TotalPages');
}
ThemeService.getAllCategories = function() {
//If they are already set, don't need to get them again
if (ThemeService.categories.length) {
return;
}
//Get the category terms from wp-json
return $http.get('wp-json/taxonomies/category/terms').success(function(res){
ThemeService.categories = res;
});
};
ThemeService.getPosts = function(page) {
return $http.get('wp-json/posts/?page=' + page + '&filter[posts_per_page]=1').success(function(res, status, headers){
ThemeService.posts = res;
page = parseInt(page);
// Check page variable for sanity
if ( isNaN(page) || page > headers('X-WP-TotalPages') ) {
_setTitle('Page Not Found', 'Page Not Found');
} else {
//Deal with pagination
if (page>1) {
_setTitle('Posts on Page ' + page, 'Posts on Page ' + page + ':');
} else {
_setTitle('Home', 'Latest Posts:');
}
_setArchivePage(res,page,headers);
}
});
};
return ThemeService;
}
//Finally register the service
app.factory('ThemeService', ['$http', ThemeService]);
这是一个基本的出厂设置,其中有两个内部函数_setTitle
和_setArchivePage
。 从getPosts
和getCategories
调用这些方法以更新当前页面标题,并设置一个内部整数以知道我们正在查看的页面编号。
我们将需要开始使用ngSanitize
模块来解析服务的输入。 使用npm
将其安装在主题目录中:
$ npm install angular-sanitize --save
ThemeService
只是一个基本JavaScript对象,它通过$http.get
和getPosts
方法执行类别查找。 现在,我们将使我们的控制器意识到这项服务。 打开scripts.js
并修改控制器以了解ThemeService
。
//Main controller
app.controller('Main', ['$scope', '$http', 'ThemeService', function($scope, $http, ThemeService) {
//Get Categories from ThemeService
ThemeService.getAllCategories();
//Get the first page of posts from ThemeService
ThemeService.getPosts(1);
$scope.data = ThemeService;
}]);
不要忘了在第一行中通过以下scripts.js
在scripts.js
启用angular-sanitize
模块:
var app = angular.module('wp', ['ngRoute', 'ngSanitize']);
最后,您将需要确保js/services.js
和Angular angular-sanitize
模块已加入WordPress。 wp_localize_script
请修改functions.php
文件,并在wp_localize_script
调用之前附加以下内容:
wp_enqueue_script('angularjs-sanitize', get_stylesheet_directory_uri() . '/node_modules/angular-sanitize/angular-sanitize.min.js');
wp_enqueue_script('theme-service', get_stylesheet_directory_uri() . '/js/services.js');
现在,我们将需要更新main.html
部分,以显示由ThemeService提供的这些类别。
<h1>Categories</h1>
<ul>
<li ng-repeat="category in data.categories">
<span ng-if="current_category_id && category.ID == current_category_id" ng-bind-html="category.name"></span>
<a ng-if="!current_category_id || category.ID != current_category_id" href="category/{{category.slug}}" ng-bind-html="category.name"></a>
</li>
</ul>
<p>{{data.pageTitle}}</p>
<ul>
<li ng-repeat="post in data.posts">
<a href="/{{post.slug}}" ng-bind-html="post.title"></a>
<a href="/{{post.slug}}" ng-if="post.featured_image_thumbnail_url"><img ng-src="{{post.featured_image_thumbnail_url}}" alt="{{post.featured_image.title.rendered}}" /></a>
<div ng-bind-html="post.excerpt.rendered"></div>
</li>
</ul>
现在,您ng-view
使用Angular的factory
服务通过ng-view
显示在主页上的帖子和类别。 这样做的好处是所有组件都可以使用数据。 因此,我们现在可以在路线中的所有控制器之间共享类别对象。
进一步发展
现在我们已经为主题设置了服务,我们可以继续开发数据层并将Bootstrap样式合并到返回HTML中。
现在,在主题中配置Angular的可能性确实是无限的,并且通过签出提供的存储库,您将有一个快速的起点来创建启用Angular和Bootstrap的单页WordPress应用程序。