WordPress 添加可重复使用的自定义metabox 字段

所谓 WordPress metabox,就是类似文章编辑框下面 WP 自带的自定义字段的设置面板,通过 add_meta_box() 可以添加自定义面板,方便地输入相关信息,并在前端调用实现一些功能。

基本的面板添加代码网上很多,本文分享两个可重复使用的自定义 metabox 字段面板。

代码一

预设两个字段,可重复添加,并以组数存储在数据库 wp_postmeta 表中
WordPress 添加可重复使用的自定义metabox 字段
WordPress 添加可重复使用的自定义metabox 字段

  1. add_action('admin_init', 'add_meta_boxes', 1);
  2. function add_meta_boxes() {
  3. add_meta_box( 'repeatable-fields', 'Audio Playlist', 'repeatable_meta_box_display', 'post', 'normal', 'high');
  4. }
  5. function repeatable_meta_box_display() {
  6. global $post;
  7. $repeatable_fields = get_post_meta($post->ID, 'repeatable_fields', true);
  8. wp_nonce_field( 'repeatable_meta_box_nonce', 'repeatable_meta_box_nonce' );
  9. ?>
  10. <script type="text/javascript">
  11. jQuery(document).ready(function($) {
  12. $('.metabox_submit').click(function(e) {
  13. e.preventDefault();
  14. $('#publish').click();
  15. });
  16. $('#add-row').on('click', function() {
  17. var row = $('.empty-row.screen-reader-text').clone(true);
  18. row.removeClass('empty-row screen-reader-text');
  19. row.insertBefore('#repeatable-fieldset-one tbody>tr:last');
  20. return false;
  21. });
  22. $('.remove-row').on('click', function() {
  23. $(this).parents('tr').remove();
  24. return false;
  25. });
  26. $('#repeatable-fieldset-one tbody').sortable({
  27. opacity: 0.6,
  28. revert: true,
  29. cursor: 'move',
  30. handle: '.sort'
  31. });
  32. });
  33. </script>
  34. <table id="repeatable-fieldset-one" width="100%">
  35. <thead>
  36. <tr>
  37. <th width="2%"></th>
  38. <th width="30%">Name</th>
  39. <th width="60%">URL</th>
  40. <th width="2%"></th>
  41. </tr>
  42. </thead>
  43. <tbody>
  44. <?php
  45. if ( $repeatable_fields ) :
  46. foreach ( $repeatable_fields as $field ) {
  47. ?>
  48. <tr>
  49. <td><a class="button remove-row" href="#">-</a></td>
  50. <td><input type="text" class="widefat" name="name[]" value="<?php if($field['name'] != '') echo esc_attr( $field['name'] ); ?>" /></td>
  51. <td><input type="text" class="widefat" name="url[]" value="<?php if ($field['url'] != '') echo esc_attr( $field['url'] ); else echo 'http://'; ?>" /></td>
  52. <td><a class="sort">|||</a></td>
  53. </tr>
  54. <?php
  55. }
  56. else :
  57. // show a blank one
  58. ?>
  59. <tr>
  60. <td><a class="button remove-row" href="#">-</a></td>
  61. <td><input type="text" class="widefat" name="name[]" /></td>
  62. <td><input type="text" class="widefat" name="url[]" value="http://" /></td>
  63. <td><a class="sort">|||</a></td>
  64. </tr>
  65. <?php endif; ?>
  66. <!-- empty hidden one for jQuery -->
  67. <tr class="empty-row screen-reader-text">
  68. <td><a class="button remove-row" href="#">-</a></td>
  69. <td><input type="text" class="widefat" name="name[]" /></td>
  70. <td><input type="text" class="widefat" name="url[]" value="http://" /></td>
  71. <td><a class="sort">|||</a></td>
  72. </tr>
  73. </tbody>
  74. </table>
  75. <p><a id="add-row" class="button" href="#">Add another</a>
  76. <input type="submit" class="metabox_submit" value="Save" />
  77. </p>
  78. <?php
  79. }
  80. add_action('save_post', 'repeatable_meta_box_save');
  81. function repeatable_meta_box_save($post_id) {
  82. if ( ! isset( $_POST['repeatable_meta_box_nonce'] ) ||
  83. ! wp_verify_nonce( $_POST['repeatable_meta_box_nonce'], 'repeatable_meta_box_nonce' ) )
  84. return;
  85. if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
  86. return;
  87. if (!current_user_can('edit_post', $post_id))
  88. return;
  89. $old = get_post_meta($post_id, 'repeatable_fields', true);
  90. $new = array();
  91. $names = $_POST['name'];
  92. $urls = $_POST['url'];
  93. $count = count( $names );
  94. for ( $i = 0; $i < $count; $i++ ) {
  95. if ( $names[$i] != '' ) :
  96. $new[$i]['name'] = stripslashes( strip_tags( $names[$i] ) );
  97. if ( $urls[$i] == 'http://' )
  98. $new[$i]['url'] = '';
  99. else
  100. $new[$i]['url'] = stripslashes( $urls[$i] ); // and however you want to sanitize
  101. endif;
  102. }
  103. if ( !empty( $new ) && $new != $old )
  104. update_post_meta( $post_id, 'repeatable_fields', $new );
  105. elseif ( empty($new) && $old )
  106. delete_post_meta( $post_id, 'repeatable_fields', $old );
  107. }

前端调用

  1. <?php $repeatable_fields = get_post_meta( $post->ID, 'repeatable_fields', true ); if ( $repeatable_fields ) : ?>
  2. <div class="list">
  3. <?php foreach ( $repeatable_fields as $field ) { ?>
  4. <div class="row">
  5. <?php if( $field['name'] != '' ) echo '<span class="field">'. esc_attr( $field['name'] ) . '</span>'; ?>
  6. <?php if( $field['url'] != '' ) echo '<span class="field">'. esc_attr( $field['url'] ) . '</span>'; ?>
  7. </div>
  8. <?php } ?>
  9. </div>
  10. <?php endif; ?>

代码二

在上面的基础上,附加了下拉选项字段。

  1. function hhs_get_sample_options() {
  2. $options = array (
  3. 'Option 1' => 'option1',
  4. 'Option 2' => 'option2',
  5. 'Option 3' => 'option3',
  6. 'Option 4' => 'option4',
  7. );
  8. return $options;
  9. }
  10. add_action('admin_init', 'hhs_add_meta_boxes', 1);
  11. function hhs_add_meta_boxes() {
  12. add_meta_box( 'repeatable-fields', 'Repeatable Fields', 'hhs_repeatable_meta_box_display', 'post', 'normal', 'default');
  13. }
  14. function hhs_repeatable_meta_box_display() {
  15. global $post;
  16. $repeatable_fields = get_post_meta($post->ID, 'repeatable_fields', true);
  17. $options = hhs_get_sample_options();
  18. wp_nonce_field( 'hhs_repeatable_meta_box_nonce', 'hhs_repeatable_meta_box_nonce' );
  19. ?>
  20. <script type="text/javascript">
  21. jQuery(document).ready(function( $ ){
  22. $( '#add-row' ).on('click', function() {
  23. var row = $( '.empty-row.screen-reader-text' ).clone(true);
  24. row.removeClass( 'empty-row screen-reader-text' );
  25. row.insertBefore( '#repeatable-fieldset-one tbody>tr:last' );
  26. return false;
  27. });
  28. $( '.remove-row' ).on('click', function() {
  29. $(this).parents('tr').remove();
  30. return false;
  31. });
  32. });
  33. </script>
  34. <table id="repeatable-fieldset-one" width="100%">
  35. <thead>
  36. <tr>
  37. <th width="40%">Name</th>
  38. <th width="12%">Select</th>
  39. <th width="40%">URL</th>
  40. <th width="8%"></th>
  41. </tr>
  42. </thead>
  43. <tbody>
  44. <?php
  45. if ( $repeatable_fields ) :
  46. foreach ( $repeatable_fields as $field ) {
  47. ?>
  48. <tr>
  49. <td><input type="text" class="widefat" name="name[]" value="<?php if($field['name'] != '') echo esc_attr( $field['name'] ); ?>" /></td>
  50. <td>
  51. <select name="select[]">
  52. <?php foreach ( $options as $label => $value ) : ?>
  53. <option value="<?php echo $value; ?>"<?php selected( $field['select'], $value ); ?>><?php echo $label; ?></option>
  54. <?php endforeach; ?>
  55. </select>
  56. </td>
  57. <td><input type="text" class="widefat" name="url[]" value="<?php if ($field['url'] != '') echo esc_attr( $field['url'] ); else echo 'http://'; ?>" /></td>
  58. <td><a class="button remove-row" href="#">Remove</a></td>
  59. </tr>
  60. <?php
  61. }
  62. else :
  63. // show a blank one
  64. ?>
  65. <tr>
  66. <td><input type="text" class="widefat" name="name[]" /></td>
  67. <td>
  68. <select name="select[]">
  69. <?php foreach ( $options as $label => $value ) : ?>
  70. <option value="<?php echo $value; ?>"><?php echo $label; ?></option>
  71. <?php endforeach; ?>
  72. </select>
  73. </td>
  74. <td><input type="text" class="widefat" name="url[]" value="http://" /></td>
  75. <td><a class="button remove-row" href="#">Remove</a></td>
  76. </tr>
  77. <?php endif; ?>
  78. <!-- empty hidden one for jQuery -->
  79. <tr class="empty-row screen-reader-text">
  80. <td><input type="text" class="widefat" name="name[]" /></td>
  81. <td>
  82. <select name="select[]">
  83. <?php foreach ( $options as $label => $value ) : ?>
  84. <option value="<?php echo $value; ?>"><?php echo $label; ?></option>
  85. <?php endforeach; ?>
  86. </select>
  87. </td>
  88. <td><input type="text" class="widefat" name="url[]" value="http://" /></td>
  89. <td><a class="button remove-row" href="#">Remove</a></td>
  90. </tr>
  91. </tbody>
  92. </table>
  93. <p><a id="add-row" class="button" href="#">Add another</a></p>
  94. <?php
  95. }
  96. add_action('save_post', 'hhs_repeatable_meta_box_save');
  97. function hhs_repeatable_meta_box_save($post_id) {
  98. if ( ! isset( $_POST['hhs_repeatable_meta_box_nonce'] ) ||
  99. ! wp_verify_nonce( $_POST['hhs_repeatable_meta_box_nonce'], 'hhs_repeatable_meta_box_nonce' ) )
  100. return;
  101. if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
  102. return;
  103. if (!current_user_can('edit_post', $post_id))
  104. return;
  105. $old = get_post_meta($post_id, 'repeatable_fields', true);
  106. $new = array();
  107. $options = hhs_get_sample_options();
  108. $names = $_POST['name'];
  109. $selects = $_POST['select'];
  110. $urls = $_POST['url'];
  111. $count = count( $names );
  112. for ( $i = 0; $i < $count; $i++ ) {
  113. if ( $names[$i] != '' ) :
  114. $new[$i]['name'] = stripslashes( strip_tags( $names[$i] ) );
  115. if ( in_array( $selects[$i], $options ) )
  116. $new[$i]['select'] = $selects[$i];
  117. else
  118. $new[$i]['select'] = '';
  119. if ( $urls[$i] == 'http://' )
  120. $new[$i]['url'] = '';
  121. else
  122. $new[$i]['url'] = stripslashes( $urls[$i] ); // and however you want to sanitize
  123. endif;
  124. }
  125. if ( !empty( $new ) && $new != $old )
  126. update_post_meta( $post_id, 'repeatable_fields', $new );
  127. elseif ( empty($new) && $old )
  128. delete_post_meta( $post_id, 'repeatable_fields', $old );
  129. }

前端调用

  1. <?php $repeatable_fields = get_post_meta( $post->ID, 'repeatable_fields', true ); if ( $repeatable_fields ) : ?>
  2. <div class="list">
  3. <?php foreach ( $repeatable_fields as $field ) { ?>
  4. <div class="row">
  5. <?php if( $field['name'] != '' ) echo '<span class="field">'. esc_attr( $field['name'] ) . '</span>'; ?>
  6. <?php if( $field['select'] != '' ) echo '<span class="field">'. esc_attr( $field['select'] ) . '</span>'; ?>
  7. <?php if( $field['url'] != '' ) echo '<span class="field">'. esc_attr( $field['url'] ) . '</span>'; ?>
  8. </div>
  9. <?php } ?>
  10. </div>
  11. <?php endif; ?>

给TA打赏
共{{data.count}}人
人已打赏
WordPress教程

WP_Query使用meta_query里比较大小时compare用>=、、

2022-6-5 14:00:47

WordPress教程

限制 WordPress 用户上传图片尺寸大小

2022-6-5 17:04:09

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索