关于添加后台选项,很多国外主题都有这个功能,不过看起来很复杂的样子,酷剑之前使用的时候都是套用别人的模板,也不明白使用原理和扩展方案,很久之前使用的是wpbus的主题选项,不过由于本人PHP能力有限,无法增加一些需要的功能,比如添加图片,添加数组,添加下拉菜单,添加选择框等。所以现在已经不适用了。
前段时间是使用知更鸟的主题模板后台选项,不过那个UI不太好看,而且修改起来也是比较复杂。如果主题选项很少的话,修改也比较麻烦,所以也不打算使用了。最近在搜索到一个教程,非常清晰的讲述了如何添加后台选项的。
增加一个php文件为option-list.php
<?php
/*wordpress后台设置类文件
Version: 1.0
Author: 树是我的朋友
Author URI: http://www.ashuwp.com
License:http://www.ashuwp.com/courses/optionpage/214.html
update:https://wp.qdkfweb.cn
*/
class ashu_option_class{
var $options;
var $pageinfo;
var $database_options;
var $saved_optionname;
//类的构建函数
function ashu_option_class($options, $pageinfo) {
$this->options = $options;
$this->pageinfo = $pageinfo;
$this->make_data_available(); //准备设置选项数据
add_action( 'admin_menu', array(&$this, 'add_admin_menu') );
if( isset($_GET['page']) && ($_GET['page'] == $this->pageinfo['filename']) ) {
//加载css js
add_action('admin_init', array(&$this, 'enqueue_head'));
}
}
function enqueue_head() {
//加载的js路径
wp_enqueue_script('ashu_options_js', TEMJS_URI.'ashu_options.js');
wp_enqueue_style('ashu_options_css', TEMJS_URI.'ashu_options.css');
wp_enqueue_script('thickbox');
wp_enqueue_style('thickbox');
}
//创建菜单项函数
function add_admin_menu() {
//添加顶级菜单项
$top_level = "主题设置";
if(!$this->pageinfo['child']) {
add_theme_page($top_level, $top_level, 'edit_themes', $this->pageinfo['filename'], array(&$this, 'initialize'));
define('TOP_LEVEL_BASEAME', $this->pageinfo['filename']);
}else{
add_submenu_page(TOP_LEVEL_BASEAME, $this->pageinfo['full_name'], $this->pageinfo['full_name'], 'edit_themes', $this->pageinfo['filename'], array(&$this, 'initialize'));
}
}
function make_data_available() {
global $ashu_option; //申明全局变量
foreach ($this->options as $option) {
if( isset($option['std']) ) {
$ashu_option_std[$this->pageinfo['optionname']][$option['id']] = $option['std'];
}
}
//选项组名称
$this->saved_optionname = 'ashu_'.$this->pageinfo['optionname'];
$ashu_option[$this->pageinfo['optionname']] = get_option($this->saved_optionname);
//合并数组
$ashu_option[$this->pageinfo['optionname']] = array_merge((array)$ashu_option_std[$this->pageinfo['optionname']], (array)$ashu_option[$this->pageinfo['optionname']]);
//html实体转换
$ashu_option[$this->pageinfo['optionname']] = $this->htmlspecialchars_deep($ashu_option[$this->pageinfo['optionname']]);
}
//使用递归将预定义html实体转换为字符
function htmlspecialchars_deep($mixed, $quote_style = ENT_QUOTES, $charset = 'UTF-8') {
if (is_array($mixed) || is_object($mixed)) {
foreach($mixed as $key => $value) {
$mixed[$key] = $this->htmlspecialchars_deep($value, $quote_style, $charset);
}
}
elseif (is_string($mixed)) {
$mixed = htmlspecialchars_decode($mixed, $quote_style);
}
return $mixed;
}
function initialize() {
$this->get_save_options();
$this->display();
}
//显示表单项函数
function display() {
$saveoption = false;
echo '<div class="wrap">';
echo '<div class="icon32" id="icon-options-general"><br/></div>';
echo '<h2>'.$this->pageinfo['full_name'].'</h2>';
echo '<form method="post" action="">';
//根据选项类型执行对应函数
foreach ($this->options as $option) {
if (method_exists($this, $option['type'])) {
$this->$option['type']($option);
$saveoption = true;
}
}
if($saveoption) {
echo '<p class="submit">';
echo '<input type="hidden" value="1" name="save_my_options"/>';
echo '<input type="submit" name="Submit" class="button-primary autowidth" value="Save Changes" /></p>';
}
echo '</form></div>';
}
//更新数据
function get_save_options() {
$options = $newoptions = get_option($this->saved_optionname);
if ( isset( $_POST['save_my_options'] ) ) {
echo '<div class="updated fade" id="message" style=""><p><strong>Settings saved.</strong></p></div>';
$opion_count = 0;
foreach ($_POST as $key => $value) {
if( preg_match("/^(numbers_)/", $key, $result) ){
$numbers = explode( ',', $value );
$newoptions[$key] = $numbers;
}elseif( preg_match("/^(tinymce_)/", $key, $result) ){
$value = stripslashes($value);
$newoptions[$key] = $value;
}elseif( preg_match("/^(checkbox_)/", $key, $result) ){
$newoptions[$key] = $value;
}else{
$value = stripslashes($value);
$newoptions[$key] = htmlspecialchars($value, ENT_QUOTES,"UTF-8");
}
}
}
if ( $options != $newoptions ) {
$options = $newoptions;
update_option($this->saved_optionname, $options);
}
if($options) {
foreach ($options as $key => $value) {
$options[$key] = empty($options[$key]) ? false : $options[$key];
}
}
$this->database_options = $options;
}
/************开头***************/
function open($values) {
if(!isset($values['desc'])) $values['desc'] = "";
echo '<table class="widefat">';
echo '<thead><tr><th colspan="2">'.$values['desc'].' </th></tr></thead>';
}
/***************结尾**************/
function close($values) {
echo '<tfoot><tr><th> </th><th> </th></tr></tfoot></table>';
}
/**********标题***********************/
function title($values) {
echo '<h3>'.$values['name'].'</h3>';
if (isset($values['desc'])) echo '<p>'.$values['desc'].'</p>';
}
/*****************************文本域**********************************/
function textarea($values) {
if(isset($this->database_options[$values['id']]))
$values['std'] = $this->database_options[$values['id']];
echo '<tr valign="top" >';
echo '<th scope="row" width="200px">'.$values['name'].'</th>';
echo '<td>'.$values['desc'].'<br/>';
echo '<textarea name="'.$values['id'].'" cols="60" rows="7" id="'.$values['id'].'" style="width: 80%; font-size: 12px;" class="code">';
echo $values['std'].'</textarea><br/>';
echo '<br/></td>';
echo '</tr>';
}
/*********************文本框**************************/
function text($values) {
if(isset($this->database_options[$values['id']])) $values['std'] = $this->database_options[$values['id']];
echo '<tr valign="top" >';
echo '<th scope="row" width="200px">'.$values['name'].'</th>';
echo '<td>'.$values['desc'].'<br/>';
echo '<input type="text" size="'.$values['size'].'" value="'.$values['std'].'" id="'.$values['id'].'" name="'.$values['id'].'"/>';
echo '<br/><br/></td>';
echo '</tr>';
}
/**************复选框*******************/
function checkbox($values) {
if(isset($this->database_options[$values['id']])) $values['std'] = $this->database_options[$values['id']];
echo '<tr valign="top">';
echo '<th scope="row" width="200px">'.$values['name'].'</th>';
echo '<td>'.$values['desc'].'<br/>';
foreach( $values['buttons'] as $key=>$value ) {
$checked ="";
if( is_array($values['std']) && in_array($key,$values['std'])) {
$checked = 'checked = "checked"';
}
echo '<input '.$checked.' type="checkbox" class="kcheck" value="'.$key.'" name="'.$values['id'].'[]"/>'.$value;
}
echo '<label for="'.$values['id'].'">'.$values['desc'].'</label><br/>';
echo '<br/></td>';
echo '</tr>';
}
/**********************单选框******************************/
function radio($values) {
if(isset($this->database_options[$values['id']])) $values['std'] = $this->database_options[$values['id']];
echo '<tr valign="top" >';
echo '<th scope="row" width="200px">'.$values['name'].'</th>';
echo '<td>'.$values['desc'].'<br/>';
foreach($values['buttons'] as $key=>$value) {
$checked ="";
if(isset($values['std']) && ($values['std'] == $key)) {
$checked = 'checked = "checked"';
}
echo '<p><input '.$checked.' type="radio" class="kcheck" value="'.$key.'" name="'.$values['id'].'"/>';
echo '<label for="'.$values['id'].'">'.$value.'</label></p>';
}
echo '<br/></td>';
echo '</tr>';
}
/*****************数组***********************/
function numbers_array($values){
if(isset($this->database_options[$values['id']]))
$values['std'] = $this->database_options[$values['id']];
else
$values['std']=array();
$nums = implode( ',', $values['std'] );
echo '<tr valign="top" >';
echo '<th scope="row" width="200px">'.$values['name'].'</th>';
echo '<td>'.$values['desc'].'<br/>';
echo '<input type="text" size="'.$values['size'].'" value="'.$nums.'" id="'.$values['id'].'" name="'.$values['id'].'"/>';
echo '<br/><br/></td>';
echo '</tr>';
}
/********************下拉框*********************/
function dropdown($values) {
if(!isset($this->database_options[$values['id']]) && isset($values['std'])) $this->database_options[$values['id']] = $values['std'];
echo '<tr valign="top" >';
echo '<th scope="row" width="200px">'.$values['name'].'</th>';
echo '<td>'.$values['desc'].'<br/>';
if($values['subtype'] == 'page') {
$select = 'Select page';
$entries = get_pages('title_li=&orderby=name');
}else if($values['subtype'] == 'sidebar'){
global $wp_registered_sidebars;
$select = 'Select a special sidebar';
$entries = $wp_registered_sidebars;
}else if($values['subtype'] == 'cat'){
$select = 'Select category';
$entries = get_categories('title_li=&orderby=name&hide_empty=0');
}
else
{
$select = 'Select...';
$entries = $values['subtype'];
}
echo '<select class="postform" id="'. $values['id'] .'" name="'. $values['id'] .'"> ';
echo '<option value="">'.$select .'</option> ';
foreach ($entries as $key => $entry) {
if($values['subtype'] == 'page')
{
$id = $entry->ID;
$title = $entry->post_title;
}else if($values['subtype'] == 'cat'){
$id = $entry->term_id;
$title = $entry->name;
}else if($values['subtype'] == 'sidebar'){
$id = $entry['id'];
$title = $entry['name'];
}
else
{
$id = $key;
$title = $entry;
}
if ($this->database_options[$values['id']] == $id )
{
$selected = "selected='selected'";
}
else
{
$selected = "";
}
echo"<option $selected value='". $id."'>". $title."</option>";
}
echo '</select>';
echo '<br/><br/></td>';
echo '</tr>';
}
/*******************上传*****************************/
function upload($values) {
$prevImg = '';
if(isset($this->database_options[$values['id']])) $values['std'] = $this->database_options[$values['id']];
if($values['std'] != ''){$prevImg = '<img src='.$values['std'].' alt="" />';}
echo '<tr valign="top" >';
echo '<th scope="row" width="200px">'.$values['name'].'</th>';
echo '<td>';
echo '<div class="preview_pic_optionspage" id="'.$values['id'].'_div">'.$prevImg.'</div>';
echo $values['desc'].'<br/>';
echo '<input type="text" size="60" value="'.$values['std'].'" name="'.$values['id'].'" class="upload_pic_input" />';
echo ' <a onclick="return false;" title="" class="k_hijack button thickbox" id="'.$values['id'].'" href="media-upload.php?type=image&hijack_target='.$values['id'].'&TB_iframe=true">Insert Image</a>';
echo '<br/><br/></td>';
echo '</tr>';
}
//编辑器
function tinymce($values){
if(isset($this->database_options[$values['id']]))
$values['std'] = $this->database_options[$values['id']];
echo '<tr valign="top" >';
echo '<th scope="row" width="200px">'.$values['name'].'</th>';
echo '<td>'.$values['desc'].'<br/>';
wp_editor( $values['std'], $values['id'],$settings=array('tinymce'=>1,'media_buttons'=>0,) );
echo '<br/></td>';
echo '</tr>';
}
}
?>
注意类中还加载了一个自定义的js文件:ashu_options.js 这个js文件中的代码为:
jQuery.noConflict();
jQuery(document).ready(function()
{
ashu_media_uploader();
ashu_preview_pic();
});
function ashu_preview_pic()
{
jQuery('.upload_pic_input').each(function()
{
jQuery(this).bind('change focus blur ktrigger', function()
{
$select = '#' + jQuery(this).attr('name') + '_div';
$value = jQuery(this).val();
$image = '<img src ="'+$value+'" />';
var $image = jQuery($select).html('').append($image).find('img');
//set timeout because of safari
window.setTimeout(function()
{
if(parseInt($image.attr('width')) < 20)
{
jQuery($select).html('');
}
},500);
});
});
}
function ashu_media_uploader()
{
$buttons = jQuery('.k_hijack');
$realmediabuttons = jQuery('.media-buttons a');
window.custom_editor = false;
// set a variable depending on what has been clicked, normal media uploader or kriesi hijacked uploader
$buttons.click(function()
{
window.custom_editor = jQuery(this).attr('id');
});
$realmediabuttons.click(function()
{
window.custom_editor = false;
});
window.original_send_to_editor = window.send_to_editor;
window.send_to_editor = function(html)
{
if (custom_editor)
{
$img = jQuery(html).attr('src') || jQuery(html).find('img').attr('src') || jQuery(html).attr('href');
jQuery('input[name='+custom_editor+']').val($img).trigger('ktrigger');
custom_editor = false;
window.tb_remove();
}
else
{
window.original_send_to_editor(html);
}
};
}
使用方法请见下一节