wordpress创建metabox之image uploader

Wayne Shen

先添加metabox:

<?php 

// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) exit;

// metabox creating main class
class Mx_Metaboxes_Class
{

	private $args = [];

	private $defauls = [];

	public function __construct( $args )
	{

		$this->defaults = [
			'id'			=> 'mx-extra-metabox-1',
			'post_types' 	=> 'page', // ['page', 'post']
			'name'			=> esc_html( 'Extra metabox 1', 'mx-domain' ),
			'metabox_type'	=> 'input-text'
		];

		$this->args = wp_parse_args( $args, $this->defaults );

		if( is_array( $this->args['post_types'] ) ) :

			$this->args['metabox_id'] = $this->args['id'] . '_' . implode( '_',  $this->args['post_types'] );

		else :

			$this->args['metabox_id'] = $this->args['id'] . '_' . $this->args['post_types'];

		endif;

		$this->args['post_meta_key'] = '_mx_' . $this->args['metabox_id'] . '_id';
		$this->args['nonce_action']  = $this->args['metabox_id'] . '_nonce_action';
		$this->args['nonce_name']    = $this->args['metabox_id'] . '_nonce_name';

		add_action( 'add_meta_boxes', [ $this, 'add_meta_box' ] );

		add_action( 'save_post', [ $this, 'save_meta_box' ] );

	}

	// add post meta
	public function add_meta_box() {
		add_meta_box(
			$this->args['metabox_id'],
			$this->args['name'],
			[ $this, 'meta_box_content' ],
			$this->args['post_types'],
			'normal'
			// 'low'
		);
	}

	// save post meta
	public function save_meta_box( $post_id ) {
		if ( ! isset( $_POST[ $this->args['nonce_name'] ] ) || ! wp_verify_nonce( wp_unslash( $_POST[ $this->args['nonce_name'] ] ), $this->args['nonce_action'] ) ) { // phpcs:ignore WordPress.Security
			return;
		}

		if ( ! current_user_can( 'edit_post', $post_id ) ) {
			return;
		}

		$value = '';
		if ( isset( $_POST ) && isset( $_POST[ $this->args['post_meta_key'] ] ) ) :

			if( $this->args['metabox_type'] == 'input-email' ) :

				// email field
				$value = sanitize_email( wp_unslash( $_POST[ $this->args['post_meta_key'] ] ) );

			elseif( $this->args['metabox_type'] == 'input-url' ) :

				// url field
				$value = esc_url_raw( $_POST[ $this->args['post_meta_key'] ] );


			elseif( $this->args['metabox_type'] == 'textarea' ) :

				// textarea field
				$value = sanitize_textarea_field( $_POST[ $this->args['post_meta_key'] ] );

			elseif( $this->args['metabox_type'] == 'image' ) :

				// image id
				$value = sanitize_text_field( $_POST[ $this->args['post_meta_key'] ] );
				
			else :

				// input text
				$value = sanitize_text_field( wp_unslash( $_POST[ $this->args['post_meta_key'] ] ) );

			endif;


		endif;
		update_post_meta( $post_id, $this->args['post_meta_key'], $value );
	}

	// metabox content
	public function meta_box_content( $post, $meta )
	{

		$meta_value = get_post_meta(
			$post->ID,
			$this->args['post_meta_key'],
			true
		); ?>

		<p>
			<label for="<?php echo esc_attr( $this->args['post_meta_key'] ); ?>"></label>

			<?php if( $this->args['metabox_type'] == 'input-email' ) : ?>

				<!-- email field -->
				<input 
					type="email" id="<?php echo esc_attr( $this->args['post_meta_key'] ); ?>"
					name="<?php echo esc_attr( $this->args['post_meta_key'] ); ?>"
					value="<?php echo $meta_value; ?>"
				/>

			<?php elseif( $this->args['metabox_type'] == 'input-url' ) : ?>

				<!-- url field -->
				<input 
					type="url" id="<?php echo esc_attr( $this->args['post_meta_key'] ); ?>"
					name="<?php echo esc_attr( $this->args['post_meta_key'] ); ?>"
					value="<?php echo $meta_value; ?>"
				/>

			<?php elseif( $this->args['metabox_type'] == 'textarea' ) : ?>

				<!-- textarea field -->
				<textarea name="<?php echo esc_attr( $this->args['post_meta_key'] ); ?>" id="<?php echo esc_attr( $this->args['post_meta_key'] ); ?>" cols="30" rows="10"><?php echo $meta_value; ?></textarea>

			<?php elseif( $this->args['metabox_type'] == 'image' ) : ?>

				<?php

					$image_url = '';

					if( $meta_value !== '' ) {

						$image_url = wp_get_attachment_url( $meta_value );

					}

				?>

				<!-- image upload -->
				<div class="mx-image-uploader">

					<button
						class="mx_upload_image"
						<?php echo $image_url !== '' ? 'style="display: none;"' : ''; ?>
					>Choose image</button>				

					<!-- here we will save an id of image -->
					<input
						name="<?php echo esc_attr( $this->args['post_meta_key'] ); ?>"
						id="<?php echo esc_attr( $this->args['post_meta_key'] ); ?>"
						type="hidden"
						class="mx_upload_image_save"
					/>

					<!-- show an image -->
					<img
						src="<?php echo $image_url !== '' ? $image_url : ''; ?>"					
						style="width: 300px;"
						alt=""
						class="mx_upload_image_show"
						<?php echo $image_url == '' ? 'style="display: none;"' : ''; ?>						
					/>

					<!-- remove image -->
					<a
						href="#"
						class="mx_upload_image_remove"
						<?php echo $image_url == '' ? 'style="display: none;"' : ''; ?>
					>Remove Image</a>

				</div>
				
			<?php else : ?>

				<!-- input text -->
				<input 
					type="text" id="<?php echo esc_attr( $this->args['post_meta_key'] ); ?>"
					name="<?php echo esc_attr( $this->args['post_meta_key'] ); ?>"
					value="<?php echo $meta_value; ?>"
				/>

			<?php endif; ?>


		</p>

		<?php wp_nonce_field( $this->args['nonce_action'], $this->args['nonce_name'], true, true );

	}

}

然后注册上传用的js框架,调用wp自带的Image上传的js框架:

// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) exit;

// metabox creating main class
class Mx_Metaboxes_Image_Upload_Class
{

	// we will use jQuery
	// So we have to register scripts

	public static function register_scrips()
	{
		add_action( 'admin_enqueue_scripts', ['Mx_Metaboxes_Image_Upload_Class', 'upload_image_scrips'] );
	}

		public static function upload_image_scrips()
		{

			wp_enqueue_script( 'mx-image-upload', get_bloginfo( 'template_url' ) . '/mx-folder/js/image-upload.js', array( 'jquery' ), time(), true );

		}

}
image上传的js代码:
jQuery( document ).ready( function( $ ) {

	// upload image
	$( '.mx_upload_image' ).on( 'click', function( e ) {

		var mx_upload_button = $( this );

		e.preventDefault();

		var frame;

		if ( frame ) {
			frame.open();
			return;
		}

		frame = wp.media.frames.customBackground = wp.media({

			title: 'choose image',

			library: {
				type: 'image'
			},

			button: {

				text: 'Upload'
			},

			multyple: false
		});


		frame.on( 'select', function() {

			var attachment = frame.state().get('selection').first();

			// and show the image's data
			var image_id = attachment.id;

			var image_url = attachment.attributes.url;

			// pace an id
			mx_upload_button.parent().find( '.mx_upload_image_save' ).val( image_id );

			// show an image
			mx_upload_button.parent().find( '.mx_upload_image_show' ).attr( 'src', image_url );
				mx_upload_button.parent().find( '.mx_upload_image_show' ).show();

			// show "remove button"
			mx_upload_button.parent().find( '.mx_upload_image_remove' ).show();

			// hide "upload" button
			mx_upload_button.hide();

		} );

		frame.open();

	} );

	// remove image
	$( '.mx_upload_image_remove' ).on( 'click', function( e ) {

		var remove_button = $( this );

		e.preventDefault();

		// remove an id
		remove_button.parent().find( '.mx_upload_image_save' ).val( '' );

		// hide an image
		remove_button.parent().find( '.mx_upload_image_show' ).attr( 'src', '' );
			remove_button.parent().find( '.mx_upload_image_show' ).hide();

		// show "Upload button"
		remove_button.parent().find( '.mx_upload_image' ).show();

		// hide "remove" button
		remove_button.hide();

	} );

} )

functions里面的写法:

<?php 

require get_template_directory() . '/inc/metabox.php';

require get_template_directory() . '/inc/metabox-image-upload.php';

Mx_Metaboxes_Image_Upload_Class::register_scrips();


// image upload
new Mx_Metaboxes_Class(
	[
		'id'			=> 'featured-image-metabox',
		'post_types' 	=> 'post',
		'name'			=> esc_html( 'Featured image', 'mx-domain' ),
		'metabox_type'	=> 'image'
	]
);

// image upload 2
new Mx_Metaboxes_Class(
	[
		'id'			=> 'featured-image2-metabox',
		'post_types' 	=> 'post',
		'name'			=> esc_html( 'Featured image 2', 'mx-domain' ),
		'metabox_type'	=> 'image'
	]
);

// desc
new Mx_Metaboxes_Class(
	[
		'id'			=> 'desc-metabox',
		'post_types' 	=> 'post',
		'name'			=> esc_html( 'Some Description', 'mx-domain' ),
		'metabox_type'	=> 'textarea'
	]
);