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

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

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

代码一:

预设两个字段,可重复添加,并以组数存储在数据库 wp_postmeta 表中

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

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

    add_action('admin_init', 'add_meta_boxes', 1);
    function add_meta_boxes() {
    	add_meta_box( 'repeatable-fields', 'Audio Playlist', 'repeatable_meta_box_display', 'post', 'normal', 'high');
    }
     
    function repeatable_meta_box_display() {
    	global $post;
     
    	$repeatable_fields = get_post_meta($post->ID, 'repeatable_fields', true);
     
     
    	wp_nonce_field( 'repeatable_meta_box_nonce', 'repeatable_meta_box_nonce' );
    ?>
    	<script type="text/javascript">
    jQuery(document).ready(function($) {
    	$('.metabox_submit').click(function(e) {
    		e.preventDefault();
    		$('#publish').click();
    	});
    	$('#add-row').on('click', function() {
    		var row = $('.empty-row.screen-reader-text').clone(true);
    		row.removeClass('empty-row screen-reader-text');
    		row.insertBefore('#repeatable-fieldset-one tbody>tr:last');
    		return false;
    	});
    	$('.remove-row').on('click', function() {
    		$(this).parents('tr').remove();
    		return false;
    	});
     
    	$('#repeatable-fieldset-one tbody').sortable({
    		opacity: 0.6,
    		revert: true,
    		cursor: 'move',
    		handle: '.sort'
    	});
    });
    	</script>
     
    	<table id="repeatable-fieldset-one" width="100%">
    	<thead>
    		<tr>
    			<th width="2%"></th>
    			<th width="30%">Name</th>
    			<th width="60%">URL</th>
    			<th width="2%"></th>
    		</tr>
    	</thead>
    	<tbody>
    	<?php
     
    	if ( $repeatable_fields ) :
     
    		foreach ( $repeatable_fields as $field ) {
    ?>
    	<tr>
    		<td><a class="button remove-row" href="#">-</a></td>
    		<td><input type="text" class="widefat" name="name[]" value="<?php if($field['name'] != '') echo esc_attr( $field['name'] ); ?>" /></td>
     
    		<td><input type="text" class="widefat" name="url[]" value="<?php if ($field['url'] != '') echo esc_attr( $field['url'] ); else echo 'http://'; ?>" /></td>
    		<td><a class="sort">|||</a></td>
    		
    	</tr>
    	<?php
    		}
    	else :
    		// show a blank one
    ?>
    	<tr>
    		<td><a class="button remove-row" href="#">-</a></td>
    		<td><input type="text" class="widefat" name="name[]" /></td>
     
     
    		<td><input type="text" class="widefat" name="url[]" value="http://" /></td>
    <td><a class="sort">|||</a></td>
    		
    	</tr>
    	<?php endif; ?>
     
    	<!-- empty hidden one for jQuery -->
    	<tr class="empty-row screen-reader-text">
    		<td><a class="button remove-row" href="#">-</a></td>
    		<td><input type="text" class="widefat" name="name[]" /></td>
     
     
    		<td><input type="text" class="widefat" name="url[]" value="http://" /></td>
    <td><a class="sort">|||</a></td>
    		
    	</tr>
    	</tbody>
    	</table>
     
    	<p><a id="add-row" class="button" href="#">Add another</a>
    	<input type="submit" class="metabox_submit" value="Save" />
    	</p>
    	
    	<?php
    }
     
    add_action('save_post', 'repeatable_meta_box_save');
    function repeatable_meta_box_save($post_id) {
    	if ( ! isset( $_POST['repeatable_meta_box_nonce'] ) ||
    		! wp_verify_nonce( $_POST['repeatable_meta_box_nonce'], 'repeatable_meta_box_nonce' ) )
    		return;
     
    	if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
    		return;
     
    	if (!current_user_can('edit_post', $post_id))
    		return;
     
    	$old = get_post_meta($post_id, 'repeatable_fields', true);
    	$new = array();
     
     
    	$names = $_POST['name'];
    	$urls = $_POST['url'];
     
    	$count = count( $names );
     
    	for ( $i = 0; $i < $count; $i++ ) {
    		if ( $names[$i] != '' ) :
    			$new[$i]['name'] = stripslashes( strip_tags( $names[$i] ) );
     
     
    		if ( $urls[$i] == 'http://' )
    			$new[$i]['url'] = '';
    		else
    			$new[$i]['url'] = stripslashes( $urls[$i] ); // and however you want to sanitize
    		endif;
    	}
     
    	if ( !empty( $new ) && $new != $old )
    		update_post_meta( $post_id, 'repeatable_fields', $new );
    	elseif ( empty($new) && $old )
    		delete_post_meta( $post_id, 'repeatable_fields', $old );
    }

前端调用:

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

代码二:

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

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

    function hhs_get_sample_options() {
    	$options = array (
    		'Option 1' => 'option1',
    		'Option 2' => 'option2',
    		'Option 3' => 'option3',
    		'Option 4' => 'option4',
    	);
    	
    	return $options;
    }
     
    add_action('admin_init', 'hhs_add_meta_boxes', 1);
    function hhs_add_meta_boxes() {
    	add_meta_box( 'repeatable-fields', 'Repeatable Fields', 'hhs_repeatable_meta_box_display', 'post', 'normal', 'default');
    }
     
    function hhs_repeatable_meta_box_display() {
    	global $post;
     
    	$repeatable_fields = get_post_meta($post->ID, 'repeatable_fields', true);
    	$options = hhs_get_sample_options();
     
    	wp_nonce_field( 'hhs_repeatable_meta_box_nonce', 'hhs_repeatable_meta_box_nonce' );
    	?>
    	<script type="text/javascript">
    	jQuery(document).ready(function( $ ){
    		$( '#add-row' ).on('click', function() {
    			var row = $( '.empty-row.screen-reader-text' ).clone(true);
    			row.removeClass( 'empty-row screen-reader-text' );
    			row.insertBefore( '#repeatable-fieldset-one tbody>tr:last' );
    			return false;
    		});
      	
    		$( '.remove-row' ).on('click', function() {
    			$(this).parents('tr').remove();
    			return false;
    		});
    	});
    	</script>
      
    	<table id="repeatable-fieldset-one" width="100%">
    	<thead>
    		<tr>
    			<th width="40%">Name</th>
    			<th width="12%">Select</th>
    			<th width="40%">URL</th>
    			<th width="8%"></th>
    		</tr>
    	</thead>
    	<tbody>
    	<?php
    	
    	if ( $repeatable_fields ) :
    	
    	foreach ( $repeatable_fields as $field ) {
    	?>
    	<tr>
    		<td><input type="text" class="widefat" name="name[]" value="<?php if($field['name'] != '') echo esc_attr( $field['name'] ); ?>" /></td>
    	
    		<td>
    			<select name="select[]">
    			<?php foreach ( $options as $label => $value ) : ?>
    			<option value="<?php echo $value; ?>"<?php selected( $field['select'], $value ); ?>><?php echo $label; ?></option>
    			<?php endforeach; ?>
    			</select>
    		</td>
    	
    		<td><input type="text" class="widefat" name="url[]" value="<?php if ($field['url'] != '') echo esc_attr( $field['url'] ); else echo 'http://'; ?>" /></td>
    	
    		<td><a class="button remove-row" href="#">Remove</a></td>
    	</tr>
    	<?php
    	}
    	else :
    	// show a blank one
    	?>
    	<tr>
    		<td><input type="text" class="widefat" name="name[]" /></td>
    	
    		<td>
    			<select name="select[]">
    			<?php foreach ( $options as $label => $value ) : ?>
    			<option value="<?php echo $value; ?>"><?php echo $label; ?></option>
    			<?php endforeach; ?>
    			</select>
    		</td>
    	
    		<td><input type="text" class="widefat" name="url[]" value="http://" /></td>
    	
    		<td><a class="button remove-row" href="#">Remove</a></td>
    	</tr>
    	<?php endif; ?>
    	
    	<!-- empty hidden one for jQuery -->
    	<tr class="empty-row screen-reader-text">
    		<td><input type="text" class="widefat" name="name[]" /></td>
    	
    		<td>
    			<select name="select[]">
    			<?php foreach ( $options as $label => $value ) : ?>
    			<option value="<?php echo $value; ?>"><?php echo $label; ?></option>
    			<?php endforeach; ?>
    			</select>
    		</td>
    		
    		<td><input type="text" class="widefat" name="url[]" value="http://" /></td>
    		  
    		<td><a class="button remove-row" href="#">Remove</a></td>
    	</tr>
    	</tbody>
    	</table>
    	
    	<p><a id="add-row" class="button" href="#">Add another</a></p>
    	<?php
    }
     
    add_action('save_post', 'hhs_repeatable_meta_box_save');
    function hhs_repeatable_meta_box_save($post_id) {
    	if ( ! isset( $_POST['hhs_repeatable_meta_box_nonce'] ) ||
    	! wp_verify_nonce( $_POST['hhs_repeatable_meta_box_nonce'], 'hhs_repeatable_meta_box_nonce' ) )
    		return;
    	
    	if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
    		return;
    	
    	if (!current_user_can('edit_post', $post_id))
    		return;
    	
    	$old = get_post_meta($post_id, 'repeatable_fields', true);
    	$new = array();
    	$options = hhs_get_sample_options();
    	
    	$names = $_POST['name'];
    	$selects = $_POST['select'];
    	$urls = $_POST['url'];
    	
    	$count = count( $names );
    	
    	for ( $i = 0; $i < $count; $i++ ) {
    		if ( $names[$i] != '' ) :
    			$new[$i]['name'] = stripslashes( strip_tags( $names[$i] ) );
    			
    			if ( in_array( $selects[$i], $options ) )
    				$new[$i]['select'] = $selects[$i];
    			else
    				$new[$i]['select'] = '';
    		
    			if ( $urls[$i] == 'http://' )
    				$new[$i]['url'] = '';
    			else
    				$new[$i]['url'] = stripslashes( $urls[$i] ); // and however you want to sanitize
    		endif;
    	}
     
    	if ( !empty( $new ) && $new != $old )
    		update_post_meta( $post_id, 'repeatable_fields', $new );
    	elseif ( empty($new) && $old )
    		delete_post_meta( $post_id, 'repeatable_fields', $old );
    }

前端调用:

    <?php $repeatable_fields = get_post_meta( $post->ID, 'repeatable_fields', true );  if ( $repeatable_fields ) : ?>
    	<div class="list">
    		<?php foreach ( $repeatable_fields as $field ) { ?>
    			<div class="row">
    				<?php if( $field['name'] != '' ) echo '<span class="field">'. esc_attr( $field['name'] ) . '</span>'; ?>
    				<?php if( $field['select'] != '' ) echo '<span class="field">'. esc_attr( $field['select'] ) . '</span>'; ?>
    				<?php if( $field['url'] != '' ) echo '<span class="field">'. esc_attr( $field['url'] ) . '</span>'; ?>
    			</div>
    		<?php } ?>
    	</div>
    <?php endif; ?>
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

给TA打赏
共{{data.count}}人
人已打赏
ajax前端

WordPress Ajax

2023-5-9 21:22:09

css3html5javascript

基于CSS变量来实现主题白天、黑夜切换

2023-6-2 10:43:22

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