先建立菜单
public function sonliss_advert_manage()
{
$menu = [
[
'page_title' => '广告位置',
'menu_title' => '广告位置',
'menu_slug' => 'advert_position',
'callback' => 'sonliss_advert_position_page'
],
[
'page_title' => '广告',
'menu_title' => '广告',
'menu_slug' => 'advert',
'callback' => 'sonliss_advert_page'
]
];
$this->sonliss_menu_page('广告管理', '广告管理', 'advert_manage', 'sonliss_advert_page');
foreach($menu as $submenu)
{
$this->sonliss_submenu_page('advert_manage', $submenu['page_title'], $submenu['menu_title'], $submenu['menu_slug'], $submenu['callback']);
}
}
/**
* 一级菜单
*/
public function sonliss_menu_page($page_title, $menu_title, $menu_slug, $callback, $icon = '', $position = null)
{
add_menu_page(
$page_title, // 当菜单选中时,显示在页面上的标题
$menu_title, // 显示在菜单列表的标题
'administrator', // 用户权限 administrator, editor, author, contributor, subscriber
$menu_slug, // 菜单的slug,必须唯一
[$this, $callback], // 菜单回调, 默认空
$icon, // 菜单图标, 默认齿轮图标
$position // 菜单在菜单列表的位子, 默认null
);
}
/**
* 子菜单
*/
public function sonliss_submenu_page($parent_slug, $page_title, $menu_title, $menu_slug, $callback)
{
add_submenu_page(
$parent_slug, // 父菜单的slug名称
$page_title, // 当菜单选中时,显示在页面上的标题
$menu_title, // 显示在菜单列表的标题
'administrator', // 用户权限 administrator, editor, author, contributor, subscriber
$menu_slug, // 菜单的slug,必须唯一
[$this, $callback] // 菜单回调, 默认空
);
}
后台很多页面都是通用的,比如广告位列表,广告位添加、修改,广告列表,广告添加、修改,所以可以归纳下
class Sonliss
{
/**
* 列表组合
* title 列表头部标题
* page_type 页面类型 admin.php?page=?
* table_header table列表头部
* table_body table主体
*/
protected function html_list($title, $page_type, $table_header, $table_body, $total_data = 0, $pagination = [])
{
$header_html = $this->html_list_header($title, $page_type);
$table_html = $this->html_list_table($table_header, $table_body, $page_type);
$bottom_html = $this->html_list_bottom($page_type, $total_data, $pagination);
$action_url = admin_url( 'admin.php?page=' . $page_type . '&action=batch_delete' );
$nonce = wp_nonce_field( $page_type );
$form_html = '<form name="theForm" method="post" action="' . $action_url . '">' . $nonce . $referer . $header_html . $table_html . $bottom_html . '</form>';
$html = $this->create_block('div', $form_html, 'wrap');
return $html;
}
/**
* 列表头部
* title 列表头部标题
* page_type 页面类型 admin.php?page=?
*/
protected function html_list_header($title, $page_type)
{
$heading_inline = $this->create_block('h1', $title, 'wp-heading-inline');
$link_text = esc_html_x( '添加'.$title, $title );
$add_url = admin_url( 'admin.php?page=' . $page_type . '&action=new' );
$add_action = $this->create_block('a', $link_text, 'page-title-action', $add_url);
$header_end = '<hr class="wp-header-end">';
$clearfix = $this->clearfix();
$html = $heading_inline . $add_action . $header_end . $clearfix;
return $html;
}
/**
* 组装table
* table_header table列表头部
* table_body table主体
* page_type 页面类型 admin.php?page=?
*/
protected function html_list_table($table_header, $table_body, $page_type)
{
$table_header_html = $this->html_list_table_header($table_header, $page_type);
$table_body_html = $this->html_list_table_body($table_body, $page_type);
$html = $this->create_block('table', $table_header_html . $table_body_html, 'wp-list-table widefat fixed striped');
return $html;
}
/**
* table head
* table_header table列表头部
*/
protected function html_list_table_header($table_header, $page_type)
{
$table_header_html = '';
foreach($table_header as $key => $val)
{
$class = 'manage-column';
$value = '';
$options = [];
if(isset($val['check_column']))
{
$html = '<label class="screen-reader-text" for="cb-select-all-1">全选</label><input id="cb-select-all-1" type="checkbox">';
$class = 'manage-column column-cb check-column';
$options = ['id' => 'cb'];
} else if(isset($val['sort_column']))
{
$sort = '<span>' . $val['title'] . '</span><span class="sorting-indicator"></span>';
$url = admin_url('admin.php?page=' . $page_type . '&orderby=' . $val['sort_column'][0] . '&order=' . $val['sort_column'][1]);
$html = $this->create_block('a', $sort, '', $url);
$class = 'manage-column sorted desc';
} else if(isset($val['column_primary']))
{
$sort = '<span>' . $val['title'] . '</span><span class="sorting-indicator"></span>';
$url = admin_url('admin.php?page=' . $page_type . '&orderby=' . $val['sort_column'][0] . '&order=' . $val['sort_column'][1]);
$html = $this->create_block('a', $sort, '', $url);
$class = 'manage-column column-primary sorted desc';
} else
{
$html = $val['title'];
}
if(isset($val['check_column']))
{
$table_header_html .= $this->create_block('td', $html, $class, $value, $options);
} else {
$table_header_html .= $this->create_block('th', $html, $class, $value, $options);
}
}
$table_header_html = '<thead>' . $this->create_block('tr', $table_header_html) . '</thead>';
return $table_header_html;
}
/**
* table body
* table_body table主体
* page_type 页面类型 admin.php?page=?
*/
protected function html_list_table_body($table_body, $page_type)
{
$table_body_html = '';
$edit_url = admin_url('admin.php?page=' . $page_type . '&action=edit');
$delete_url = wp_nonce_url('admin.php?page=' . $page_type . '&action=delete');
foreach($table_body as $key => $row)
{
$tr_html = '';
foreach($row as $list)
{
$class = 'manage-column';
$value = '';
$options = [];
if(isset($list['check_column']))
{
$html = '<label class="screen-reader-text">全选</label><input name="column[]" value="' . $list['value'] . '" type="checkbox">';
$class = 'check-column';
} else if(isset($list['column_primary']))
{
$title = '<strong>' . $list['value'] . '</strong>';
$title_html = $this->create_block('a', $title, 'row-title', $list['sort_column']);
$new_edit_url = $edit_url . "&id=" . $key;
$edit_url_html = $this->create_block('a', '编辑', '', $new_edit_url);
$edit_html = $this->create_block('span', $edit_url_html . ' | ', 'edit');
$new_delete_url = $delete_url . "&id=" . $key;
$delete_url_html = $this->create_block('a', '删除', 'submitdelete', $new_delete_url);
$delete_html = $this->create_block('span', $delete_url_html, 'delete');
$actions_html = $this->create_block('div', $edit_html . $delete_html, 'row-actions');
$html = $title_html . $actions_html;
$class = 'has-row-actions column-primary';
} else
{
$html = $list['value'];
}
if(isset($list['check_column']))
{
$tr_html .= $this->create_block('th', $html, $class, $value, $options);
} else {
$tr_html .= $this->create_block('td', $html, $class, $value, $options);
}
}
$table_body_html .= $this->create_block('tr', $tr_html, 'iedit author-self status-publish hentry');
}
$table_body_list_html = '<tbody>' . $table_body_html . '</tbody>';
return $table_body_list_html;
}
/**
* 列表底部
* page_type 页面类型 admin.php?page=?
* total_data 总数据
* pagination 分页参数, ['current' => 1, 'total' => 1]
*/
protected function html_list_bottom($page_type, $total_data = 0, $pagination = [])
{
$submit_html = '<input type="submit" class="button action" value="批量删除">';
$batch_html = $this->create_block('div', $submit_html, 'alignleft actions bulkactions');
$page_total_html = '';
if ($total_data > 0)
{
$page_total_html = $this->create_block('span', $total_data . '条项目', 'displaying-num');
}
$bottom_html = '';
if (count($pagination) > 0)
{
$url = site_url( add_query_arg('pagenum', '%#%') );
$pagination_html = paginate_links( [
'base' => $url,
'format' => '?paged=%#%',
'current' => $pagination['current'],
'total' => $pagination['total']
]);
$pagination_html = $this->create_block('span', $pagination_html, 'pagination-links');
$class = 'tablenav-pages';
if ($pagination['total'] <= 1)
{
$class = 'tablenav-pages one-page';
}
$bottom_html = $this->create_block('div', $page_total_html . $pagination_html, $class);
}
return $this->create_block('div', $batch_html . $bottom_html, 'tablenav bottom');
}
/**
* 表单
* url 表单提交url
* title 表单头部标题
* page_type 页面类型
* input_lists 收入框
*/
protected function html_form($url, $title, $page_type, $input_lists)
{
$heading_inline = $this->create_block('h1', $title, '');
$nonce = wp_nonce_field( $page_type );
$form_table = $this->create_block('table', $input_lists, 'form-table');
$form_submit = $this->create_block('p', '<input type="submit" class="button button-primary" value="提 交">', 'submit');
$form = '<form name="theForm" method="post" action="' . $url . '" class="validate" novalidate="novalidate">' . $nonce . $referer . $form_table . $form_submit . '</form>';
$html = $this->create_block('div', $heading_inline . $form, 'wrap');
return $html;
}
/**
* 保存
* table 表
* data 要保存的字段 数组
* where 条件 数组
*/
protected function html_save($table, $data, $where = [])
{
global $wpdb;
$save_table = $wpdb->prefix . $table;
if(count($where) > 0)
{
return $wpdb->update($save_table, $data, $where);
} else
{
return $wpdb->insert($save_table, $data);
}
}
/**
* 获取表单数据
* table 表
* id
*/
protected function get_form_data($table, $id)
{
global $wpdb;
$save_table = $wpdb->prefix . $table;
$res = $wpdb->get_row( "SELECT * FROM " . $save_table . " where id = " . $id );
return $res;
}
/**
* 删除表单数据
* table 表
* id
*/
protected function delete_form_data($table, $id)
{
global $wpdb;
$save_table = $wpdb->prefix . $table;
$res = $wpdb->delete( $save_table, ['id' => $id] );
return $res;
}
/**
* 获取列表
* table 表
* columns 要获取的字段
*/
protected function get_html_list($table, $columns = '*', $orderby = 'id', $order = 'desc', $offset = 0, $limit = 10)
{
global $wpdb;
$save_table = $wpdb->prefix . $table;
$res = $wpdb->get_results( "SELECT " . $columns . " FROM " . $save_table . " ORDER BY " . $orderby . " " . $order . " LIMIT " . $offset . ", " . $limit );
return $res;
}
/**
* 获取总数量
* table 表
*/
protected function get_total_data($table)
{
global $wpdb;
$save_table = $wpdb->prefix . $table;
$res = $wpdb->get_var('SELECT COUNT(id) FROM ' . $save_table);
return $res;
}
/**
* 块开始
* type dom 元素
* class 样式
* value input, href, a等具有值属性的值
* options html其他属性, 数组键值对
*/
protected function start_block($type, $class = '', $value = '', $options = [])
{
$class_html = '';
if (!empty($class))
{
$class_html = ' class="' . $class . '"';
}
$option_html = '';
if(count($options) > 0)
{
foreach($options as $key => $val)
{
$option_html .= ' ' . $key . '="' . $val . '"';
}
}
$value_html = '';
if($type == 'a')
{
$value_html = ' href="' . $value . '"';
} else if($type == 'img')
{
$value_html = ' src="' . $value . '" alt="' . $thml . '"';
}
$html = '<' . $type . $value_html . $class_html . $option_html . '>';
return $html;
}
/**
* 块结束
* type dom 元素
*/
protected function close_block($type)
{
return '</' . $type . '>';
}
/**
* 整块
* type dom 元素
* html 块的html
* class 样式
* value input, href, a等具有值属性的值
* options html其他属性, 数组键值对
*/
protected function create_block($type, $html, $class = '', $value = '', $options = [])
{
$start_html = $this->start_block($type, $class, $value, $options);
$close_html = $this->close_block($type);
$block = $start_html . $html . $close_html;
return $block;
}
/**
* 清理浮动
*/
protected function clearfix()
{
return '<div class="clear"></div>';
}
/**
* 表单
* type input 类型
* name
* value
* data 对于radio, checkbox,select等需要有选项的data
* options html其他属性, 数组键值对
*/
protected function create_input($type, $name, $value = '', $data = [], $options = [])
{
$option_html = '';
if(count($options) > 0)
{
foreach($options as $key => $val)
{
$option_html .= ' ' . $key . '="' . $val . '"';
}
}
$html = '';
$input_html = ' id="' . $name . '" name="' . $name . '" ' . $option_html;
switch($type)
{
case 'hidden':
$html = '<input type="hidden" value="' . $value . '" ' . $input_html . '/>';
break;
case 'phone':
$html = '<input type="phone" value="' . $value . '" ' . $input_html . '/>';
break;
case 'number':
$html = '<input type="number" value="'. $value .'" ' . $input_html . '/>';
break;
case 'textarea':
$html = '<textarea ' . $input_html . '>' . $value . '</textarea>';
break;
case 'radio':
foreach($data as $key => $val)
{
if($key == $value)
{
$html .= '<input type="radio" value="' . $key . '" ' . $input_html . ' checked="checked" />' . $val;
} else
{
$html .= '<input type="radio" value="' . $key . '" ' . $input_html . '/>' . $val;
}
}
break;
case 'checkbox':
foreach($data as $key => $val)
{
if($key == $value)
{
$html .= '<input type="checkbox" value="' . $key . '" ' . $input_html . ' checked="checked" />' . $val;
} else
{
$html .= '<input type="checkbox" value="' . $key . '" ' . $input_html . '/>' . $val;
}
}
break;
case 'select':
$html = '<select ' .$input_html . '>';
$html .= '<option value="">请选择</option>';
foreach($data as $key => $val)
{
if($key == $value)
{
$html .= '<option value="' . $key . '" selected="selected">' . $val . '</option>';
} else
{
$html .= '<option value="' . $key . '">' . $val . '</option>';
}
}
$html .= '</select>';
break;
default:
$html = '<input type="text" value="' . $value . '" ' . $input_html . '/>';
break;
}
return $html;
}
/**
* 表单行 tr
* type input 类型
* name
* label
* value
* data 对于radio, checkbox,select等需要有选项的data
* options html其他属性, 数组键值对
*/
protected function create_input_tr($type, $name, $label, $value = '', $data = [], $options = [])
{
$tr_class = 'form-field';
if (array_key_exists('aria-required', $options))
{
$tr_class .= ' form-required';
$label .= '<span class="description">(必填)</span>';
}
$label_html = $this->create_block('label', $label);
$label_td = $this->create_block('th', $label_html);
$input_html = $this->create_input($type, $name, $value, $data, $options);
$input_td = $this->create_block('td', $input_html);
return $this->create_block('tr', $label_td . $input_td, $tr_class);
}
}
怎么使用呢
就用继承
比如广告位置
require_once( dirname(__FILE__) . '\sonliss.php' );
class AdvertPosition extends Sonliss
{
/**
* 广告位列表
*/
public function advert_position_list($page = 1, $orderby = 'id', $order = 'desc')
{
$new_order = 'asc';
if ($order == 'asc')
{
$new_order = 'desc';
}
$table_header = [
['title' => '', 'check_column' => true, 'sort_column' => ['id', $new_order]],
['title' => '广告位置名称', 'column_primary' => true, 'sort_column' => ['name', $new_order]]
];
// 分页
$limit = 20;
$total_data = $this->get_total_data('advert_positions');
$offset = ( $page - 1 ) * $limit;
$total_pages = ceil( $total_data / $limit );
$advert_positions = $this->get_html_list('advert_positions', 'id, name', $orderby, $order, $offset, $limit);
$table_body = [];
foreach($advert_positions as $key => $val)
{
$table_body[$val->id] = [
['value' => $val->id, 'check_column' => true],
['value' => $val->name, 'column_primary' => true]
];
}
$title = '广告位置';
$pagination = [
"current" => $page,
'total' => $total_pages
];
echo $this->html_list($title, 'advert_position', $table_header, $table_body, $total_data, $pagination);
}
/**
* 广告位添加表单
*/
public function new_advert_position_form()
{
$id = $this->create_input_tr('hidden', 'id', '');
$name = $this->create_input_tr('text', 'name', '广告位置名称', '', [], ['aria-required' => true]);
$slug = $this->create_input_tr('text', 'slug', '广告位置别名');
$description = $this->create_input_tr('textarea', 'description', '广告位置描述');
$input_lists = $id . $name . $slug . $description;
$action = admin_url( 'admin.php?page=advert_position&action=store' );
$html = $this->html_form($action, '添加广告位置', 'add-advert-position', $input_lists);
echo $html;
}
/**
* 广告位修改表单
*/
public function edit_advert_position_form($id)
{
$row = $this->get_form_data('advert_positions', $id);
$id_input = $this->create_input_tr('hidden', 'id', '', $id);
$name = $this->create_input_tr('text', 'name', '广告位置名称', $row->name, [], ['aria-required' => true]);
$slug = $this->create_input_tr('text', 'slug', '广告位置别名', $row->slug);
$description = $this->create_input_tr('textarea', 'description', '广告位置描述', $row->description);
$input_lists = $id_input . $name .$slug . $description;
$action = admin_url( 'admin.php?page=advert_position&action=update&id=' . $id );
$html = $this->html_form($action, '修改广告位置', 'advert_position', $input_lists);
echo $html;
}
/**
* 保存广告位置
*/
public function advert_position_save($id = 0)
{
$table = 'advert_positions';
$name = isset( $_POST['name'] ) ? wp_unslash( $_POST['name'] ) : '';
$slug = isset( $_POST['slug'] ) ? wp_unslash( $_POST['slug'] ) : '';
$description = isset( $_POST['description'] ) ? wp_unslash( $_POST['description'] ) : '';
$data = ['name' => $name, 'slug' => $slug, 'description' => $description];
$where = [];
if($id > 0)
{
$where = ['id' => $id];
}
return $this->html_save($table, $data, $where);
}
/**
* 保存广告位置
*/
public function advert_position_delete($id)
{
$table = 'advert_positions';
return $this->delete_form_data($table, $id);
}
}
然后再菜单回调时调用
public function sonliss_advert_position_page()
{
$action = isset($_GET['action']) ? $_GET['action'] : '';
$advert_position = new AdvertPosition();
switch($action)
{
case 'new':
$advert_position->new_advert_position_form();
break;
case 'store':
$advert_position->advert_position_save();
$redirect_url = admin_url('admin.php?page=advert_position');
echo "<script>alert('提交成功');window.location.href='" . $redirect_url . "';</script>";
exit;
case 'edit':
$advert_position->edit_advert_position_form($_GET['id']);
break;
case 'update':
$advert_position->advert_position_save($_POST['id']);
$redirect_url = admin_url('admin.php?page=advert_position');
echo "<script>alert('提交成功');window.location.href='" . $redirect_url . "';</script>";
exit;
case 'delete':
$advert_position->advert_position_delete($_GET['id']);
$redirect_url = admin_url('admin.php?page=advert_position');
echo "<script>alert('提交成功');window.location.href='" . $redirect_url . "';</script>";
exit;
case 'batch_delete':
$ids = $_POST['column'];
$redirect_url = admin_url('admin.php?page=advert_position');
if (count($ids) > 0)
{
foreach($ids as $id)
{
$advert_position->advert_position_delete($id);
}
echo "<script>alert('提交成功');window.location.href='" . $redirect_url . "';</script>";
} else {
echo "<script>alert('提交失败');window.location.href='" . $redirect_url . "';</script>";
}
exit;
default:
$pagenum = isset($_GET['pagenum']) ? intval($_GET['pagenum']) : 1;
if (isset($_GET['orderby']) && isset($_GET['order']))
{
$advert_position->advert_position_list($pagenum, $_GET['orderby'], $_GET['order']);
} else
{
$advert_position->advert_position_list($pagenum);
}
break;
}
}