我有一个自定义post类型的自定义metabox,用于记录我所在校园内的系统停机情况。metabox中的一个字段是一个多选框,其中列出了校园中的所有建筑。
当我保存帖子时,我能够检索前端的建筑阵列。但是,如果我返回编辑帖子,multiselect不会高亮显示以前选择的建筑列表。因此,如果我更新帖子,我必须记住还要重新突出显示受停电影响的建筑物。所有其他(非数组)字段成功保留其数据。
Adding the custom MetaBox:
function add_custom_meta_box() {
add_meta_box(\'system_outage\',\'System Outage\',\'show_system_outage\',\'outage\',\'normal\',\'high\');
}
add_action(\'add_meta_boxes\', \'add_custom_meta_box\');
Create Field Array:
$prefix = \'sysout_\';
$outage_meta_fields = array(
array(
\'label\' => \'Buildings Affected\',
\'desc\' => \'Select the buildings affected\',
\'id\' => $prefix.\'buildings\',
\'type\' => \'multiselect\',
\'options\' => array(
\'building1\' => array(
\'label\' => \'Building 1\',
\'value\' => \'building1\'
),
\'building2\' => array(
\'label\' => \'Building 2\',
\'value\' => \'building2\' //This continues for a while
)
)
);
);
The Callback:
function show_system_outage() {
global $outage_meta_fields, $post;
echo \'<input type="hidden" name="custom_meta_box_nonce" value="\'.wp_create_nonce(basename(__FILE__)).\'" />\';
echo \'<table class="form-table">\';
foreach ($outage_meta_fields as $field) {
$meta = get_post_meta($post->ID, $field[\'id\'], true);
echo \'<tr>\';
echo \'<th><label for="\'.$field[\'id\'].\'">\'.$field[\'label\'].\'</label></th>\';
echo \'<td>\';
switch($field[\'type\']) {
case \'multiselect\':
echo \'<select data-placeholder="Choose a building..." multiple="true" class="chosen" name="\'.$field[\'id\'].\'[]" id="\'.$field[\'id\'].\'">\';
foreach ($field[\'options\'] as $option) {
echo \'<option\', $meta == $option[\'value\'] ? \' selected="selected"\' : \'\', \' value="\'.$option[\'value\'].\'">\'.$option[\'label\'].\'</option>\';
}
echo \'</select><br /><span class="description">\'.$field[\'desc\'].\'</span>\';
break;
}
echo \'</td>\';
echo \'</tr>\';
}
echo \'</table>\';
}
And Then I Save the Data:
function save_custom_meta($post_id) {
global $outage_meta_fields;
if (!wp_verify_nonce($_POST[\'custom_meta_box_nonce\'], basename(__FILE__)))
return $post_id;
if (defined(\'DOING_AUTOSAVE\') && DOING_AUTOSAVE)
return $post_id;
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;
}
foreach ($outage_meta_fields as $field) {
$old = get_post_meta($post_id, $field[\'id\'], true);
$new = $_POST[$field[\'id\']];
if ($new && $new != $old) {
update_post_meta($post_id, $field[\'id\'], $new);
}
elseif (\'\' == $new && $old) {
delete_post_meta($post_id, $field[\'id\'], $old);
}
}
}
add_action(\'save_post\', \'save_custom_meta\');
我希望我已经把它格式化了,这样它就可以模糊地阅读了。
对此,我们将不胜感激。谢谢
最合适的回答,由SO网友:keilowe 整理而成
我测试了你的代码,结果对我有效:
case \'multiselect\':
echo \'<select name="\'.$field[\'id\'].\'" id="\'.$field[\'id\'].\'">\';
foreach ($field[\'options\'] as $option) {
echo \'<option\', $meta == $option[\'value\'] ? \' selected="selected"\' : \'\', \' value="\'.$option[\'value\'].\'">\'.$option[\'label\'].\'</option>\'; }
echo \'</select><br /><span class="description">\'.$field[\'desc\'].\'</span>\';
break;
对于字段array,我刚刚添加了另一个选项,该选项具有空白值和“Select”标签
另外,我删除了一个额外的“;”在倒数第二行。
$prefix = \'sysout_\';
$outage_meta_fields = array(
array(
\'label\' => \'Buildings Affected\',
\'desc\' => \'Select the buildings affected\',
\'id\' => $prefix.\'buildings\',
\'type\' => \'multiselect\',
\'options\' => array(
\'Select\' => array(
\'label\' => \'Select\',
\'value\' => \'\'
),
\'building1\' => array(
\'label\' => \'Building 1\',
\'value\' => \'building1\'
),
\'building2\' => array(
\'label\' => \'Building 2\',
\'value\' => \'building2\' //This continues for a while
)
)
)
);
SO网友:sqdge
我把keihead的回答标记为答案,因为他们肯定为我指明了正确的方向。然而,文章在Reusable Custom Metaboxes 仍然无法将数据从数组中检索到“编辑帖子”部分。幸运的是,他们添加复选框的过程包含了多选指令中缺少的部分。
$prefix = \'sysout_\';
$outage_meta_fields = array(
array(
\'label\' => \'Buildings Affected\',
\'desc\' => \'Select the buildings affected\',
\'id\' => $prefix.\'buildings\',
\'type\' => \'chosen\', //This was only changed to match the instructions
\'multiple\' => true, //This didn\'t have to be an option - I could have added multiple="multiple" in the HTML below
\'options\' => array(
\'building1\' => array(
\'label\' => \'Building 1\',
\'value\' => \'building1\'
),
\'building2\' => array(
\'label\' => \'Building 2\',
\'value\' => \'building2\'
)
)
)
);
造成所有差异的部分是
is_array ( $meta )...
部分这将查询数据库中的数组,如果该值存在于数组中,则会在多选框中将该选项标记为“已选定”。
请注意:我也在使用JQuery Chosen 插件,因此该选项也存在于代码中。
case \'chosen\':
echo \'<select name="\'.$field[\'id\'].\'[]" id="\'.$field[\'id\'].\'"\' , $field[\'type\'] == \'chosen\' ? \' class="chosen"\' : \'\' , isset( $field[\'multiple\'] ) && $field[\'multiple\'] == true ? \' multiple="multiple"\' : \'\' , \'>\';
foreach ( $field[\'options\'] as $option )
echo \'<option value="\' . $option[\'value\'] . \'"\' , is_array( $meta ) && in_array( $option[\'value\'], $meta ) ? \' selected="selected"\' : \'\' , \' >\' . $option[\'label\'] . \'</option>\';
echo \'</select><br />\' . $field[\'desc\'];
break;