据我所知,您需要创建一个带有字段的元框,并使用jQuery添加/删除图像框。如果愿意,还可以使用jQuery UI使字段可拖动。
您的元框代码如下所示
// Fields
$prefix = \'your_prefix_\';
$custom_meta_fields = array(
array(
\'label\' => \'Gallery Images\',
\'desc\' => \'Add additional images for this portfolio item.\',
\'id\' => $prefix.\'gallery_images\',
\'scope\' => array(\'your_custom_post_type\'),
\'type\' => \'repeatable_image\',
),
);
// Add the Meta Box
function add_custom_meta_box()
{
$post_types = array(\'your_custom_post_type\', \'page\', \'post\');
foreach ($post_types as $post_type) {
add_meta_box(
\'custom_meta_box\', // $id
\'Additional Information\', // $title
\'show_custom_meta_box\', // $callback
$post_type,
\'normal\', // $context
\'high\' // $priority
);
}
}
add_action(\'add_meta_boxes\', \'add_custom_meta_box\');
// The Callback
function show_custom_meta_box()
{
global $custom_meta_fields, $post;
// Use nonce for verification
echo \'<input type="hidden" name="custom_meta_box_nonce" value="\'.wp_create_nonce(basename(__FILE__)).\'" />\';
// Begin the field table and loop
echo \'<table class="form-table">\';
foreach ($custom_meta_fields as $field) {
//Check if scope matches post type
$scope = $field[ \'scope\' ];
$field_output = false;
foreach ($scope as $scopeItem) {
switch ($scopeItem) {
default: {
if ($post->post_type == $scopeItem) {
$field_output = true;
}
break;
}
}
if ($field_output) {
break;
}
}
if ($field_output) {
// get value of this field if it exists for this post
$meta = get_post_meta($post->ID, $field[\'id\'], true);
$row = 0;
// begin a table row with
echo \'<tr>
<th><label for="\'.$field[\'id\'].\'">\'.$field[\'label\'].\'</label></th>
<td>\';
switch ($field[\'type\']) {
// text
case \'text\':
echo \'<input type="text" name="\'.$field[\'id\'].\'" id="\'.$field[\'id\'].\'" value="\'.$meta.\'" size="30" />
<br /><span class="description">\'.$field[\'desc\'].\'</span>\';
break;
// repeatable
case \'repeatable_image\':
echo \'<a class="repeatable-add button" href="#">+</a>
<ul id="\'.$field[\'id\'].\'-repeatable" class="custom_repeatable">\';
$i = 0;
if ($meta) {
foreach ($meta as $row) {
echo \'<li><span class="sort hndle">|||</span>
<input type="text" class="img_field" name="\'.$field[\'id\'].\'[\'.$i.\']" id="\'.$field[\'id\'].\'" value="\'.$row.\'" size="30" />
<a class="repeatable-remove button" href="#">-</a></li>\';
++$i;
}
} else {
echo \'<li><span class="sort hndle">|||</span>
<input class="img_field" type="text" name="\'.$field[\'id\'].\'[\'.$i.\']" id="\'.$field[\'id\'].\'" value="" size="30" />
<a class="repeatable-remove button" href="#">-</a></li>\';
}
echo \'</ul>
<span class="description">\'.$field[\'desc\'].\'</span>\';
break;
} //end switch
echo \'</td></tr>\';
}
} // end foreach
echo \'</table>\'; // end table
}
// Save the Data
function save_custom_meta($post_id)
{
global $custom_meta_fields;
// verify nonce
if (!isset($_POST[\'custom_meta_box_nonce\']) || !wp_verify_nonce($_POST[\'custom_meta_box_nonce\'], basename(__FILE__))) {
return $post_id;
}
// check autosave
if (defined(\'DOING_AUTOSAVE\') && DOING_AUTOSAVE) {
return $post_id;
}
// check permissions
if (\'page\' == $_POST[\'post_type\']) {
if (!current_user_can(\'edit_page\', $post_id)) {
return $post_id;
} elseif (!current_user_can(\'edit_post\', $post_id)) {
return $post_id;
}
}
// loop through fields and save the data
foreach ($custom_meta_fields as $field) {
$old = get_post_meta($post_id, $field[\'id\'], true);
if (isset($_POST[$field[\'id\']])) {
$new = $_POST[$field[\'id\']];
if ($field[\'type\'] === \'repeatable_ad\' || $field[\'type\'] === \'repeatable_image\') {
$new = array_values($new);
}
}
if ($new && $new != $old) {
update_post_meta($post_id, $field[\'id\'], str_replace(\'"\', "\'", $new));
} elseif (\'\' == $new && $old) {
delete_post_meta($post_id, $field[\'id\'], $old);
}
} // end foreach
}
add_action(\'save_post\', \'save_custom_meta\');
你的js应该是这样的
jQuery(document).on(\'click\', \'.img_field\', function(e) {
var clicked_field = e.target.name;
var custom_uploader;
e.preventDefault();
//If the uploader object has already been created, reopen the dialog
if (custom_uploader) {
custom_uploader.open();
return;
}
//Extend the wp.media object
custom_uploader = wp.media.frames.file_frame = wp.media({
title: \'Select Image\',
button: {
text: \'Select Image\'
},
multiple: false
});
//When a file is selected, grab the URL and set it as the text field\'s value
custom_uploader.on(\'select\', function() {
attachment = custom_uploader.state().get(\'selection\').first().toJSON();
jQuery(\'input[name="\'+ clicked_field +\'"]\').val(attachment.url);
jQuery(\'.custom_preview_image\').attr(\'src\', attachment.url);
jQuery(\'.custom_media_image\').attr(\'src\',attachment.url);
});
//Open the uploader dialog
custom_uploader.open();
});
jQuery(\'.repeatable-add\').click(function() {
field = jQuery(this).closest(\'td\').find(\'.custom_repeatable li:last\').clone(true);
fieldLocation = jQuery(this).closest(\'td\').find(\'.custom_repeatable li:last\');
jQuery(\'input\', field).val(\'\').attr(\'name\', function(index, name) {
return name.replace(/(\\d+)/, function(fullMatch, n) {
return Number(n) + 1;
});
})
field.insertAfter(fieldLocation, jQuery(this).closest(\'td\'))
return false;
});
jQuery(\'.repeatable-remove\').click(function(){
jQuery(this).parent().remove();
return false;
});
jQuery(\'.custom_repeatable\').sortable({
opacity: 0.6,
revert: true,
cursor: \'move\',
handle: \'.sort\'
});
我还没有测试过这个,所以如果它不起作用,请告诉我,但它应该给你一个良好的开端。话虽如此,但使用起来要容易得多
ACF 或
CMB2 做这种事。无论如何,我希望这能有所帮助。