丢了这么多天没更新教程了,自己写到哪里都快忘了。。
前面几篇教程演示了如何在 WordPress 后台文章编辑页面添加自定义面板,今天的这篇文章不能算教程,和 WordPress 后台教程的结尾一样,直接放出一个便于使用的类文件,实际使用的时候只需要包含这个类文件,然后加载配置文件即可使用。
使用该类文件可以创建标题、文本框、文本域、下拉框、复选框、图片实时预览上传。不过少了单选框 (radio) 和文本编辑器,因为个人很少用到这两个,所以就没加上,如果有需要的,完全可以参照我们前面几篇教程自己添加上。
说实话,这个类文件也不完全是我写的,我也是从一个主题上弄来的,然后修改。
文件下载 (压缩包内功四个文件,分别是类文件、配置文件、 js 文件、 css 文件)
懒人下载
版本控制
2013.07.08,版本 1.0
- 修改复选框功能
- 增加编辑器功能
类文件metaboxclass.php:
- <?php
- /*
- WordPress 文章自定义字段类文件
- Version: 1.0
- Author: 树是我的朋友
- Author URI: http://www.ashuwp.com
- License: http://www.ashuwp.com/courses/highgrade/298.html
- */
- class ashu_meta_box{
- var $options;
- var $boxinfo;
- //构造函数
- function ashu_meta_box($options,$boxinfo){
- $this->options = $options;
- $this->boxinfo = $boxinfo;
- add_action('admin_menu', array(&$this, 'init_boxes'));
- add_action('save_post', array(&$this, 'save_postdata'));
- }
- //初始化
- function init_boxes(){
- $this->add_script_and_styles();
- $this->create_meta_box();
- }
- //加载 css 和 js 脚本
- function add_script_and_styles(){
- if(basename( $_SERVER['PHP_SELF']) == "page.php"
- || basename( $_SERVER['PHP_SELF']) == "page-new.php"
- || basename( $_SERVER['PHP_SELF']) == "post-new.php"
- || basename( $_SERVER['PHP_SELF']) == "post.php"
- || basename( $_SERVER['PHP_SELF']) == "media-upload.php")
- {
- //注意加载的脚本的 url
- wp_enqueue_style('metabox_fields_css', TEMJS_URI. 'metabox_fields.css');
- wp_enqueue_script('metabox_fields_js',TEMJS_URI. 'metabox_fields.js');
- wp_enqueue_style('thickbox');
- wp_enqueue_script('media-upload');
- wp_enqueue_script('thickbox');
- if(isset($_GET['hijack_target']))
- {
- add_action('admin_head', array(&$this,'add_hijack_var'));
- }
- }
- }
- /*************************/
- function add_hijack_var()
- {
- echo "<meta name='hijack_target' content='".$_GET['hijack_target']."' />
"; - }
- //创建自定义面板
- function create_meta_box(){
- if ( function_exists('add_meta_box') && is_array($this->boxinfo['page']) )
- {
- foreach ($this->boxinfo['page'] as $area)
- {
- if ($this->boxinfo['callback'] == '') $this->boxinfo['callback'] = 'new_meta_boxes';
- add_meta_box(
- $this->boxinfo['id'],
- $this->boxinfo['title'],
- array(&$this, $this->boxinfo['callback']),
- $area, $this->boxinfo['context'],
- $this->boxinfo['priority']
- );
- }
- }
- }
- //创建自定义面板的显示函数
- function new_meta_boxes(){
- global $post;
- //根据类型调用显示函数
- foreach ($this->options as $option)
- {
- if (method_exists($this, $option['type']))
- {
- $meta_box_value = get_post_meta($post->ID, $option['id'], true);
- if($meta_box_value != "") $option['std'] = $meta_box_value;
- echo '<div class="alt kriesi_meta_box_alt meta_box_'.$option['type'].' meta_box_'.$this->boxinfo['context'].'">';
- $this->$option['type']($option);
- echo '</div>';
- }
- }
- //隐藏域
- echo'<input type="hidden" name="'.$this->boxinfo['id'].'_noncename" id="'.$this->boxinfo['id'].'_noncename" value="'.wp_create_nonce( 'ashumetabox' ).'" />';
- }
- //保存字段数据
- function save_postdata() {
- if( isset( $_POST['post_type'] ) && in_array($_POST['post_type'],$this->boxinfo['page'] ) && (isset($_POST['save']) || isset($_POST['publish']) ) ){
- $post_id = $_POST['post_ID'];
- foreach ($this->options as $option) {
- if (!wp_verify_nonce($_POST[$this->boxinfo['id'].'_noncename'], 'ashumetabox')) {
- return $post_id ;
- }
- //判断权限
- if ( 'page' == $_POST['post_type'] ) {
- if ( !current_user_can( 'edit_page', $post_id ))
- return $post_id ;
- } else {
- if ( !current_user_can( 'edit_post', $post_id ))
- return $post_id ;
- }
- //将预定义字符转换为 html 实体
- if( $option['type'] == 'tinymce' ){
- $data = stripslashes($_POST[$option['id']]);
- }elseif( $option['type'] == 'checkbox' ){
- $data = $_POST[$option['id']];
- }else{
- $data = htmlspecialchars($_POST[$option['id']], ENT_QUOTES,"UTF-8");
- }
- if(get_post_meta($post_id , $option['id']) == "")
- add_post_meta($post_id , $option['id'], $data, true);
- elseif($data != get_post_meta($post_id , $option['id'], true))
- update_post_meta($post_id , $option['id'], $data);
- elseif($data == "")
- delete_post_meta($post_id , $option['id'], get_post_meta($post_id , $option['id'], true));
- }
- }
- }
- //显示标题
- function title($values){
- echo '<p>'.$values['name'].'</p>';
- }
- //文本框
- function text($values){
- if(isset($this->database_options[$values['id']])) $values['std'] = $this->database_options[$values['id']];
- echo '<p>'.$values['name'].'</p>';
- echo '<p><input type="text" size="'.$values['size'].'" value="'.$values['std'].'" id="'.$values['id'].'" name="'.$values['id'].'"/>';
- echo $values['desc'].'<br/></p>';
- echo '<br/>';
- }
- //文本域
- function textarea($values){
- if(isset($this->database_options[$values['id']])) $values['std'] = $this->database_options[$values['id']];
- echo '<p>'.$values['name'].'</p>';
- echo '<p><textarea class="kriesi_textarea" cols="60" rows="5" id="'.$values['id'].'" name="'.$values['id'].'">'.$values['std'].'</textarea>';
- echo $values['desc'].'<br/></p>';
- echo '<br/>';
- }
- //媒体上传
- function media($values){
- if(isset($this->database_options[$values['id']])) $values['std'] = $this->database_options[$values['id']];
- //图片上传按钮
- global $post_ID, $temp_ID;
- $uploading_iframe_ID = (int) (0 == $post_ID ? $temp_ID : $post_ID);
- $media_upload_iframe_src = "media-upload.php?post_id=$uploading_iframe_ID";
- $image_upload_iframe_src = apply_filters('image_upload_iframe_src', "$media_upload_iframe_src&type=image");
- $button = '<a href="'.$image_upload_iframe_src.'&hijack_target='.$values['id'].'&TB_iframe=true" id="'.$values['id'].'" class="k_hijack button thickbox" onclick="return false;" > 上传</a>';
- //判断图片格式, 图片预览
- $image = '';
- if($values['std'] != '') {
- $fileextension = substr($values['std'], strrpos($values['std'], '.') + 1);
- $extensions = array('png','gif','jpeg','jpg','pdf','tif');
- if(in_array($fileextension, $extensions))
- {
- $image = '<img src="'.$values['std'].'" />';
- }
- }
- echo '<div id="'.$values['id'].'_div" class="kriesi_preview_pic">'.$image .'</div>';
- echo '<p>'.$values['name'].'</p><p>';
- if($values['desc'] != "") echo '<p>'.$values['desc'].'<br/>';
- echo '<input class="kriesi_preview_pic_input" type="text" size="'.$values['size'].'" value="'.$values['std'].'" name="'.$values['id'].'"/>'.$button;
- echo '</p>';
- echo '<br/>';
- }
- //单选框
- function radio( $values ){
- if(isset($this->database_options[$values['id']]))
- $values['std'] = $this->database_options[$values['id']];
- echo '<p>'.$values['name'].'</p>';
- foreach( $values['buttons'] as $key=>$value ) {
- $checked ="";
- if($values['std'] == $key) {
- $checked = 'checked = "checked"';
- }
- echo '<input '.$checked.' type="radio" class="kcheck" value="'.$key.'" name="'.$values['id'].'"/>'.$value;
- }
- }
- //复选框
- function checkbox($values){
- echo '<p>'.$values['name'].'</p>';
- 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/></p>';
- }
- //下拉框
- function dropdown($values){
- echo '<p>'.$values['name'].'</p>';
- //选择内容可以使页面、分类、菜单、侧边栏和自定义内容
- if($values['subtype'] == 'page'){
- $select = 'Select page';
- $entries = get_pages('title_li=&orderby=name');
- }else if($values['subtype'] == 'cat'){
- $select = 'Select category';
- $entries = get_categories('title_li=&orderby=name&hide_empty=0');
- }else if($values['subtype'] == 'menu'){
- $select = 'Select Menu in page left';
- $entries = get_terms( 'nav_menu', array( 'hide_empty' => false ) );
- }else if($values['subtype'] == 'sidebar'){
- global $wp_registered_sidebars;
- $select = 'Select a special sidebar';
- $entries = $wp_registered_sidebars;
- }else{
- $select = 'Select...';
- $entries = $values['subtype'];
- }
- echo '<p><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'] == 'menu'){
- $id = $entry->term_id;
- $title = $entry->name;
- }else if($values['subtype'] == 'sidebar'){
- $id = $entry['id'];
- $title = $entry['name'];
- }else{
- $id = $entry;
- $title = $key;
- }
- if ($values['std'] == $id ){
- $selected = "selected='selected'";
- }else{
- $selected = "";
- }
- echo"<option $selected value='". $id."'>". $title."</option>";
- }
- echo '</select>';
- echo $values['desc'].'<br/></p>';
- echo '<br/>';
- }
- //编辑器
- function tinymce($values){
- if(isset($this->database_options[$values['id']]))
- $values['std'] = $this->database_options[$values['id']];
- echo '<p>'.$values['name'].'</p>';
- wp_editor( $values['std'], $values['id'] );
- //wp_editor( $values['std'], 'content', array('dfw' => true, 'tabfocus_elements' => 'sample-permalink,post-preview', 'editor_height' => 360) );
- //带配置参数
- /*wp_editor($meta_box['std'],$meta_box['name'].'_value', $settings = array(quicktags=>0,//取消 html 模式
- tinymce=>1,//可视化模式
- media_buttons=>0,//取消媒体上传
- textarea_rows=>5,//行数设为 5
- editor_class=>"textareastyle") ); */
- }
- }
- ?>
对应的 js 文件metabox_fields.js,如果用不到图片上传,可不需要加载 js:
- jQuery.noConflict();
- jQuery(document).ready(function(){
- hijack_media_uploader();
- hijack_preview_pic();
- });
- function hijack_preview_pic(){
- jQuery('.kriesi_preview_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 hijack_media_uploader(){
- $buttons = jQuery('.k_hijack');
- $realmediabuttons = jQuery('.media-buttons a');
- window.custom_editor = false;
- $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);
- }
- };
- }
类文件实例化对应的配置文件metabox.php:
注意
复选框保存的数据为数组
- <?php
- //自定义面板类的实例化
- /**********title*************/
- $options = array();
- //page 参数为在页面和文章中都添加面板 ,可以添加自定义文章类型
- //context 参数为面板在后台的位置,比如 side 则显示在侧栏
- $boxinfo = array('title' => 'meta box', 'id'=>'ashubox', 'page'=>array('page','post'), 'context'=>'normal', 'priority'=>'low', 'callback'=>'');
- $options[] = array( "name" => "标题",
- "type" => "title");
- $options[] = array(
- "name" => "文本框",
- "desc" => "",
- "id" => "ashu_text",
- "size"=>"40",
- "std" => "",
- "type" => "text"
- );
- $options[] = array(
- "name" => "文本域",
- "desc" => "",
- "id" => "ashu_textarea",
- "std" => "",
- "type" => "textarea"
- );
- $options[] = array(
- "name" => "图片上传",
- "desc" => "",
- "id" => "ashu_upimg",
- "std" => "",
- "button_label"=>'上传图片',
- "type" => "media"
- );
- $options[] = array(
- "name" => "单选框",
- "desc" => "",
- "id" => "ashu_radio",
- "std" => 1,
- "buttons" => array('Yes','No'),
- "type" => "radio"
- );
- $options[] = array(
- "name" => "复选框",
- "desc" => "喜欢吃啥?",
- "id" => "ashu_checkbox",
- "buttons" => array('苹果','香蕉','西瓜','芒果'),
- "type" => "checkbox"
- );
- $options[] = array(
- "name" => "下拉选择",
- "desc" => "",
- "id" => "ashu_dropdown",
- "subtype"=> array(
- '1'=>'1',
- '2'=>'2',
- '3'=>'3'
- ),
- "type" => "dropdown"
- );
- $options[] = array(
- "name" => "选择分类",
- "desc" => "",
- "id" => "ashu_cat",
- "subtype"=> "cat",
- "type" => "dropdown"
- );
- $options[] = array(
- "name" => "选择页面",
- "desc" => "",
- "id" => "ashu_page",
- "subtype"=> "page",
- "type" => "dropdown"
- );
- $options[] = array(
- "name" => "选择菜单",
- "desc" => "",
- "id" => "ashu_menu",
- "subtype"=> "menu",
- "type" => "dropdown"
- );
- $options[] = array(
- "name" => "选择侧边栏",
- "desc" => "",
- "id" => "ashu_sidebar",
- "subtype"=> "sidebar",
- "type" => "dropdown"
- );
- $options[] = array(
- "name" => "编辑器",
- "desc" => "",
- "id" => "ashu_tinymce",
- "std" => "",
- "type" => "tinymce"
- );
- $new_box = new ashu_meta_box($options, $boxinfo);
- ?>
使用方法:在主题中加载这两个文件,比如在主题的 functions.php 中加载两个文件:
- include_once('metaboxclass.php');
- include_once('metabox.php');
则后台文章和页面的编辑页面都会出现配置的自定义面板。
字段调用,比如调用上面配置文件中的文本框字段:
- $ashu_eitor = get_post_meta($post->ID, "ashu_text", true); //ashu_text 为配置文件中文本框的 id
有图有真相,李菊福: