之前写过一篇关于给主题增加配置项的东西,那时使用的是add_theme_page()函数。后来WP结构调整,这个函数虽然还能用,但不能跟预览挂钩,已经逐渐淘汰了,取而代之的是customizer的用法。
add_theme_page()有个同胞兄弟,一看就是给插件用的,叫add_plugins_page()。现在的插件一般也不用这个函数了,而是用add_menu_page()函数来增加后台配置页面。
这三个函数其实是一回事,而且也不是这篇文章的重点。
配置项的内容当然可以自己画。但WP已经定义好了一组API来帮你,这些API被称作“WP Settings API”。
WP把一个配置页面划分成Page,Secition和Field。关系见下图(via)
这也不是今天的重点。我要做的是让不同的Section作为不同的Tab页存在。
一切用例子来说话吧。
1)上那个自动生成配置项代码的网站,增加两个测试框,然后点击“Let’s Go”。生成了一堆代码。
<?php add_action( 'admin_menu', 'wp_pcd_add_admin_menu' ); add_action( 'admin_init', 'wp_pcd_settings_init' ); function wp_pcd_add_admin_menu( ) { add_menu_page( 'plugin_config_demo', 'plugin_config_demo', 'manage_options', 'plugin_config_demo', 'wp_pcd_options_page' ); } function wp_pcd_settings_init( ) { register_setting( 'pluginPage', 'wp_pcd_settings' ); add_settings_section( 'wp_pcd_pluginPage_section', __( 'Your section description', 'wordpress' ), 'wp_pcd_settings_section_callback', 'pluginPage' ); add_settings_field( 'wp_pcd_text_field_0', __( 'Settings field description', 'wordpress' ), 'wp_pcd_text_field_0_render', 'pluginPage', 'wp_pcd_pluginPage_section' ); add_settings_field( 'wp_pcd_textarea_field_1', __( 'Settings field description', 'wordpress' ), 'wp_pcd_textarea_field_1_render', 'pluginPage', 'wp_pcd_pluginPage_section' ); } function wp_pcd_text_field_0_render( ) { $options = get_option( 'wp_pcd_settings' ); ?> <input type='text' name='wp_pcd_settings[wp_pcd_text_field_0]' value='<?php echo $options['wp_pcd_text_field_0']; ?>'> <?php } function wp_pcd_textarea_field_1_render( ) { $options = get_option( 'wp_pcd_settings' ); ?> <textarea cols='40' rows='5' name='wp_pcd_settings[wp_pcd_textarea_field_1]'> <?php echo $options['wp_pcd_textarea_field_1']; ?> </textarea> <?php } function wp_pcd_settings_section_callback( ) { echo __( 'This section description', 'wordpress' ); } function wp_pcd_options_page( ) { ?> <form action='options.php' method='post'> <h2>plugin_config_demo</h2> <?php settings_fields( 'pluginPage' ); do_settings_sections( 'pluginPage' ); submit_button(); ?> </form> <?php } ?>
2)把生成的东西存成一个配置页面,比如option.php,放在插件目录下。注意,第8行第4个参要改成__FILE__
add_menu_page( 'plugin_config_demo', 'plugin_config_demo', 'manage_options', __FILE__, 'wp_pcd_options_page','' );
3)在插件的主文件里加上下面代码:
if (is_admin()) { require_once( plugin_dir_path( __FILE__ ) . '/options.php'); }
至于怎么作个插件,一搜到处都是,要是你不知道的话,那么就请先搜一下之后再往下看,我没有“伪原创”的习惯。
刷新一下后台,这个简陋的页面就出来了,可以看到,两个文本框此时是上下排列的。
4)在主描绘函数wp_pcd_options_page()里加点料。
4.1)增加当前tab页的选择信息
if( isset( $_GET[ 'tab' ] ) ) { $active_tab = $_GET[ 'tab' ]; } else { $active_tab = 'tab_1'; }
4.2)增加两个tab页的链接。链接加在form前面。
tab的风格用”nav-tab-wrapper”和”nav-tab-active”的话,WP的默认风格会帮我们搞定一切。
<h2 class="nav-tab-wrapper"> <a href="?page=<?php echo __FILE__;?>&tab=tab_1" class="nav-tab <?php echo $active_tab == 'tab_1' ? 'nav-tab-active' : ''; ?>">Tab One</a> <a href="?page=<?php echo __FILE__;?>&tab=tab_2" class="nav-tab <?php echo $active_tab == 'tab_2' ? 'nav-tab-active' : ''; ?>">Tab Two</a> </h2>
4.3)把form里的东西也分开。
4.3.1)我们把原来的settings_fields()、do_settings_sections()拆成两部分。
当然这是以两个tab为例子,如果更多就多加else好了。
if( $active_tab == 'tab_1' ) { settings_fields( 'pluginPage' ); do_settings_sections( 'pluginPage' ); } else { settings_fields( 'pluginPage666' ); do_settings_sections( 'pluginPage666' ); }
4.3.2)当然要补上叫666的坑。
在wp_pcd_settings_init()里,追加一个section。还记得前面那张图吗?
add_settings_section( 'wp_pcd_pluginPage_section666',//section名 __( '新追加的section', 'wordpress' ),//描述 'wp_pcd_settings_section666_callback',//回调函数,其实可以留空 'pluginPage666'//group名。必须与settings_fields()、do_settings_sections()里一致 );
再把已经存在的第二个文本框“挪”到第二个tab页里。主要是修改后面两个参数。
add_settings_field( 'wp_pcd_textarea_field_1', __( '第二页', 'wordpress' ), 'wp_pcd_textarea_field_1_render', 'pluginPage666', 'wp_pcd_pluginPage_section666' );
然后还有一个callback要写。
function wp_pcd_settings_section666_callback( ) { echo '选中了第二个tab页'; }
看,样子变了吧,点击tab页试试吧。
下面是最终代码。跟原始代码比较是理解追加和修改的过程的最好办法。希望对您的开发有所帮助。
<?php add_action( 'admin_menu', 'wp_pcd_add_admin_menu' ); add_action( 'admin_init', 'wp_pcd_settings_init' ); function wp_pcd_add_admin_menu( ) { add_menu_page( 'plugin_config_demo', 'plugin_config_demo', 'manage_options', __FILE__, 'wp_pcd_options_page','' ); } function wp_pcd_settings_init( ) { register_setting( 'pluginPage', 'wp_pcd_settings' ); add_settings_section( 'wp_pcd_pluginPage_section', __( 'Your section description', 'wordpress' ), 'wp_pcd_settings_section_callback', 'pluginPage' ); add_settings_section( 'wp_pcd_pluginPage_section666', __( '新追加的section', 'wordpress' ), 'wp_pcd_settings_section666_callback', 'pluginPage666' ); add_settings_field( 'wp_pcd_text_field_0', __( 'Settings field description', 'wordpress' ), 'wp_pcd_text_field_0_render', 'pluginPage', 'wp_pcd_pluginPage_section' ); add_settings_field( 'wp_pcd_textarea_field_1', __( '第二页', 'wordpress' ), 'wp_pcd_textarea_field_1_render', 'pluginPage666', 'wp_pcd_pluginPage_section666' ); } function wp_pcd_text_field_0_render( ) { $options = get_option( 'wp_pcd_settings' ); ?> <input type='text' name='wp_pcd_settings[wp_pcd_text_field_0]' value='<?php echo $options['wp_pcd_text_field_0']; ?>'> <?php } function wp_pcd_textarea_field_1_render( ) { $options = get_option( 'wp_pcd_settings' ); ?> <textarea cols='40' rows='5' name='wp_pcd_settings[wp_pcd_textarea_field_1]'> <?php echo $options['wp_pcd_textarea_field_1']; ?> </textarea> <?php } function wp_pcd_settings_section_callback( ) { echo __( 'This section description', 'wordpress' ); } function wp_pcd_settings_section666_callback( ) { echo '选中了第二个tab页'; } function wp_pcd_options_page( ) { if( isset( $_GET[ 'tab' ] ) ) { $active_tab = $_GET[ 'tab' ]; } else { $active_tab = 'tab_1'; } ?> <h2 class="nav-tab-wrapper"> <a href="?page=<?php echo __FILE__;?>&tab=tab_1" class="nav-tab <?php echo $active_tab == 'tab_1' ? 'nav-tab-active' : ''; ?>">Tab One</a> <a href="?page=<?php echo __FILE__;?>&tab=tab_2" class="nav-tab <?php echo $active_tab == 'tab_2' ? 'nav-tab-active' : ''; ?>">Tab Tow</a> </h2> <form action='options.php' method='post'> <h2>plugin_config_demo</h2> <?php if( $active_tab == 'tab_1' ) { settings_fields( 'pluginPage' ); do_settings_sections( 'pluginPage' ); } else { settings_fields( 'pluginPage666' ); do_settings_sections( 'pluginPage666' ); } submit_button(); ?> </form> <?php } ?>
P.S:原文是一段代码,前面都是我自己的理解。我觉得翻译代码也是一种翻译。
via
因为 WordPress 的代码实在太肿了,而且插件仓库还不是 git 管理,所以一直没研究过这些玩意,自制的插件也都是免配置的。
确实有很多东西应该甩出去。但我真的很喜欢wordpress的钩子机制。
钩子机制可以说是 WordPress 的精华了,只不过几年前的大更新后,官方文档就有点脱节,想介入开发变得很困难。
我被绑在wp这个破车上13年了,换是没法换的了。
有没有新能源车,简单高效一点,基本功能齐全。
不了解唉。我是信奉篱笆不破就不要去补的那类人。
我上车也有10年了,现在还是用的 4.3,每次出新版都自己手工 merge 代码。
我要是换我就干脆自己写了,毕竟主修的就是 PHP ,写博客自用的话没难度,只不过做不出来钩子,扩展都得改代码了。
没换的必要,就个人写个文章,哪来那么多新需求。当时升 4.4 第一版出一堆 Bug 我直接就回退了,之后一直没升过大版本。
4.0的时候,主要功能是主题的预览,以及一堆媒体的东西。当时就觉得没什么大用了。那时后台设置是不升级,但当时用的虚拟主机,服务商后来偷摸给自动升了,让我好一阵恼火,也坚定了我换VPS的决心。
功能上不觉得WP能有什么进步了。现在5.0听说主要是加古腾堡,没什么卵用。但是吧,每次要是它说有安全方面的更新又不敢不管。没那个精力像你那样比较代码,再说php我也仅限于对着手册和代码能用,完全说不上精通。
4.4是不是后台中文包少了半个括号导致打开白屏那次?我后台从来不设成中文,感觉完全没必要。
按的wordpress刚起步,不小心跑到这里,发现你的后台居然是纯英文的,牛气了啊,插件制作我是学不会了。
这是个历史遗留问题。主要是我刚开始用wordpress那会儿,还没有语言包这个东西,早习惯了。
回踩
这个评论区的叠加挺好看的