前言
很久没写博客了,今年转行做前端啦。Vue作为前端最火的三大框架之一,不玩儿到WordPress上怎么行呢?但Vue本身就是一个模板引擎,而WordPress作为文章发布系统,前台是需要被浏览器抓取的,要是前台使用模板引擎填充势必对搜索引擎不友好。所以就干脆在后台玩玩儿吧。于是尝试做了一下WordPress的主题设置选项页。传统的主题设置选项页做法已经很成熟并且有框架了,我这里就不再提了,下面简单介绍如何使用Vue这种前端技术来实现。
学习本文需有 Vue.js 的使用经验
技术栈
Vue 2.x – 前端数据绑定与模板引擎(至少需要IE9浏览器)
Element UI – 基于Vue的UI框架
WP REST API – 用于前端与后端的数据传输,WordPress4.7以上自带,老版本WP需插件
新增 REST API
由于我们需要做option的保存与读取,而WordPress并没有这个接口,因此我们需要手动写一个REST API接口用来保存和读取Option。因为vue对数据的保存是{name1:value1,name2:value2}的形式存储的,因此我们将api也写成这样的形式,方便数据提交。
此处需学习WordPress官方文档的REST API相关细节
在functions.php文件中新增下面的代码来手动增加API:
//使用REST API需要的一点点授权工作
wp_register_script( 'pf_restapi', '' );
$pf_api_translation_array = array(
'route' => esc_url_raw( rest_url() ),
'nonce' => wp_create_nonce( 'wp_rest' ),
);
wp_localize_script( 'pf_restapi', 'pandastudio_framework', $pf_api_translation_array );
wp_enqueue_script( 'pf_restapi' );
//注册API地址
add_action( 'rest_api_init', function () {
register_rest_route( 'vue', '/get_option/', array(
'methods' => 'post',
'callback' => 'get_option_by_RestAPI',
));
register_rest_route( 'vue', '/update_option/', array(
'methods' => 'post',
'callback' => 'update_option_by_RestAPI',
));
});
//读取Option
function get_option_by_RestAPI( $data ) {
$dataArray = json_decode($data->get_body(),true);
$return = array();
foreach ($dataArray as $option_name => $value) {
$return[$option_name] = get_option($option_name) ? get_option($option_name) : "";
}
return $return;
}
//保存Option
function update_option_by_RestAPI( $data ) {
if (current_user_can('manage_options')) {
$dataArray = json_decode($data->get_body(),true);
foreach ($dataArray as $option_name => $value) {
update_option($option_name,$value);
}
}
}
新增页面
在functions.php中写增加后台设置页的代码
add_action('admin_menu', 'add_option_rest_page');
function add_option_rest_page(){
add_menu_page( '主题设置', '主题设置', 'manage_options', 'pf_options', 'create_Page', '', 60 );
}
此处需学习 add_menu_page 的使用方法,详见官方文档
接下来写创建页面的函数,由于我们要使用Vue和ElementUI来制作配置页面,因此需要先引入Vue和ElementUI。此处我们引入在线脚本作为示例
function create_Page () {
?>
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-default/index.css">
<div id="vue_rest" class="wrap">
<!-- Vue模板:在这里编写Element-UI的代码 -->
</div>
<script type="text/javascript">
//Vue脚本:在这里编写Vue的对象
</script>
<?php
}
引入在线脚本会影响加载速度,强烈建议用于生产环境时使用主题本地的脚本和样式
写到这里本文就可以结束了(吃瓜群众:你逗我?!),下面只是使用Element UI和调用API的方法,任何一个前端开发者都应该能熟练上手
创建示例文本框
根据Element UI的开发文档,在上面“Vue模板”处做一个Element UI表单并增加两个输入框
<el-form ref="form" :model="form" label-width="100px">
<el-form-item label="第一个输入框">
<el-input v-model="sampleInput1"></el-input>
</el-form-item>
<el-form-item label="第二个输入框">
<el-input v-model="sampleInput2"></el-input>
</el-form-item>
</el-form>
然后在“Vue脚本”中新增一个Vue对象,绑定表单的输入框数据
var vue_rest = new Vue({
el: "#vue_rest",
data() {
return {
sampleInput1 :"",
sampleInput2 :"",
}
},
})
现在,打开后台设置页面,可以看到如下所示的界面了。我们所输入的字段都通过Vue绑定到了脚本的data里面
但是数据要怎么提交到后台呢?还需要一个保存按钮来使用一开始我们写好的API
制作保存按钮
根据Element UI的文档在刚才的表单后面做一个按钮,并绑定一个Vue method
<el-button type="primary" @click="save_config">保存</el-button>
在vue对象中新增这个method,然后用ajax去提交数据
methods: {
save_config() {
_this = this;
jQuery.ajax({
url: pandastudio_framework.route + 'vue/update_option',
type: 'POST',
beforeSend: function ( xhr ) {
xhr.setRequestHeader( 'X-WP-Nonce', pandastudio_framework.nonce );
},
data: JSON.stringify(_this._data),
})
.done(function(data) {
_this.$message.success('保存成功!')
})
.fail(function() {
_this.$notify.error({
title: '保存失败',
message: '连接服务器失败或后台保存出错!'
});
})
}
}
效果如下
读取数据
我们发现,在进入页面的时候,数据仍然是空的,因此需要在vue被挂载的时候去读取一次数据,然后保存到data中。根据vue的生命周期文档,增加挂载时执行的脚本
mounted: function() {
var _this = this;
jQuery.ajax({
url: pandastudio_framework.route + 'vue/get_option',
type: 'POST',
beforeSend: function ( xhr ) {
xhr.setRequestHeader( 'X-WP-Nonce', pandastudio_framework.nonce );
},
data: JSON.stringify(_this._data),
})
.done(function(data) {
for (var key in data) {
_this[key] = data[key];
}
})
.fail(function() {
_this.loading = false;
_this.show = false;
_this.$alert('连接服务器失败或后台读取出错!', '数据读取失败', {
confirmButtonText: '确定',
})
})
}
至此,一个简单的后台页面读取和保存数据的功能就做好了。需要增加数据字段的时候,在Element UI的表单部分增加输入框,将值绑定到data就可以了。
在WordPress主题模板中读取存储字段的方法依旧是
<?php get_option("sampleInput1"); ?>
示例代码
在自带主题Twenty Seventeen中测试有效(粘贴到functions.php最末尾)
wp_register_script( 'pf_restapi', '' );
$pf_api_translation_array = array(
'route' => esc_url_raw( rest_url() ),
'nonce' => wp_create_nonce( 'wp_rest' ),
);
wp_localize_script( 'pf_restapi', 'pandastudio_framework', $pf_api_translation_array );
wp_enqueue_script( 'pf_restapi' );
//新增API地址
add_action( 'rest_api_init', function () {
register_rest_route( 'vue', '/get_option/', array(
'methods' => 'post',
'callback' => 'get_option_by_RestAPI',
));
register_rest_route( 'vue', '/update_option/', array(
'methods' => 'post',
'callback' => 'update_option_by_RestAPI',
));
});
//API方法
function get_option_by_RestAPI( $data ) {
$dataArray = json_decode($data->get_body(),true);
$return = array();
foreach ($dataArray as $option_name => $value) {
$return[$option_name] = get_option($option_name) ? get_option($option_name) : "";
}
return $return;
}
function update_option_by_RestAPI( $data ) {
if (current_user_can('manage_options')) {
$dataArray = json_decode($data->get_body(),true);
foreach ($dataArray as $option_name => $value) {
update_option($option_name,$value);
}
}
}
add_action('admin_menu', 'add_option_rest_page');
function add_option_rest_page(){
add_menu_page( '主题设置', '主题设置', 'manage_options', 'pf_options', 'create_Page', '', 60 );
}
function create_Page () {
?>
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-default/index.css">
<div id="vue_rest" class="wrap">
<!-- 在这里编写element-ui的代码 -->
<el-form ref="form" :model="form" label-width="100px">
<el-form-item label="第一个输入框">
<el-input v-model="sampleInput1"></el-input>
</el-form-item>
<el-form-item label="第二个输入框">
<el-input v-model="sampleInput2"></el-input>
</el-form-item>
</el-form>
<el-button type="primary" @click="save_config">保存</el-button>
</div>
<script type="text/javascript">
//在这里编写vue的对象
var vue_rest = new Vue({
el: "#vue_rest",
data() {
return {
sampleInput1 :"",
sampleInput2 :"",
}
},
mounted: function() {
var _this = this;
jQuery.ajax({
url: pandastudio_framework.route + 'vue/get_option',
type: 'POST',
beforeSend: function ( xhr ) {
xhr.setRequestHeader( 'X-WP-Nonce', pandastudio_framework.nonce );
},
data: JSON.stringify(_this._data),
})
.done(function(data) {
for (var key in data) {
_this[key] = data[key];
}
})
.fail(function() {
_this.loading = false;
_this.show = false;
_this.$alert('连接服务器失败或后台读取出错!', '数据读取失败', {
confirmButtonText: '确定',
})
})
},
methods: {
save_config() {
_this = this;
jQuery.ajax({
url: pandastudio_framework.route + 'vue/update_option',
type: 'POST',
beforeSend: function ( xhr ) {
xhr.setRequestHeader( 'X-WP-Nonce', pandastudio_framework.nonce );
},
data: JSON.stringify(_this._data),
})
.done(function(data) {
_this.$message.success('保存成功!')
})
.fail(function() {
_this.$notify.error({
title: '保存失败',
message: '连接服务器失败或后台保存出错!'
});
})
}
}
})
</script>
<?php
}
拓展
下面提供一些可以发散的思路,可以把这个设置页做得更好。代码较为复杂,不再示例,但都是基于本文实现的:
- 更多组件:本文只是简单描述了使用Vue、Element UI、Rest API来制作主题设置页的简单方法。利用前端技术完全可以扩展成更加复杂的表单,如:下拉菜单、单选框、色彩选择器、开关、slider滑动条等,甚至还可以在顶部加上Element UI做好的“Tab菜单”
- 导入导出:通过浏览器的生成Blob对象接口以及文件读取接口,还可以在无需增加后台PHP代码的前提下,完全用前端来实现option数据的导入导出
- 配色:Element UI的配色是浅蓝色,与WordPress不搭,可以用Element文档的 “在线主题生成工具” 生成适合WP的色彩主题
这是我最终做出来的效果,开开脑洞,可以做出更多功能
本文著作权归本人所有,未经许可谢绝转载!
是个大佬,顶一下!!!!!!!!!!