问题描述
我试图用 metabox 的标签来替换 metabox 的类别,因为有太多的层次结构和滚动来检查适当的类别,而 sub-categories 不是一个选项。所以在我的情况下,标签的 metabox 更好。
这就是我这样做:
/*
* Non-hierarchal metabox for categories
* (like the tags metabox)
*
* SOURCES:
* http://wordpress.stackexchange.com/a/50098
* http://wordpress.stackexchange.com/a/49048
* http://wordpress.stackexchange.com/a/48816
*
*/
// De-register categories metabox
add_action( 'admin_menu', 'flatsy_remove_meta_box' );
function flatsy_remove_meta_box() {
remove_meta_box( 'categorydiv', 'post', 'normal' );
}
// Add new taxonomy meta box
add_action( 'add_meta_boxes', 'flatsy_add_custom_cat_meta_box' );
function flatsy_add_custom_cat_meta_box() {
add_meta_box( 'flatsy_categorydiv', 'Categories', 'flatsy_custom_cat_metabox', 'post', 'side', 'core' );
}
// This function determines what displays in your metabox
function flatsy_custom_cat_metabox( $post ) {
$defaults = array('taxonomy' => 'category');
if ( !isset($box['args']) || !is_array($box['args']) )
$args = array();
else
$args = $box['args'];
extract( wp_parse_args($args, $defaults), EXTR_SKIP );
$tax_name = esc_attr($taxonomy);
$taxonomy = get_taxonomy($taxonomy);
$disabled = !current_user_can($taxonomy->cap->assign_terms) ? 'disabled="disabled"' : '';
?>
<div class="tagsdiv" id="<?php echo $tax_name; ?>">
<div class="jaxtag">
<div class="nojs-tags hide-if-js">
<p><?php echo $taxonomy->labels->add_or_remove_items; ?></p>
<textarea name="<?php echo "tax_input[$tax_name]"; ?>" rows="3" cols="20" class="the-tags" id="tax-input-<?php echo $tax_name; ?>" <?php echo $disabled; ?>><?php echo get_terms_to_edit( $post->ID, $tax_name ); // textarea_escaped by esc_attr() ?></textarea></div>
<?php if ( current_user_can($taxonomy->cap->assign_terms) ) : ?>
<div class="ajaxtag hide-if-no-js">
<label class="screen-reader-text" for="new-tag-<?php echo $tax_name; ?>"><?php echo $box['title']; ?></label>
<div class="taghint"><?php echo $taxonomy->labels->add_new_item; ?></div>
<p><input type="text" id="new-tag-<?php echo $tax_name; ?>" name="newtag[<?php echo $tax_name; ?>]" class="newtag form-input-tip" size="16" autocomplete="off" value="" />
<input type="button" class="button tagadd" value="<?php esc_attr_e('Add'); ?>" tabindex="3" /></p>
</div>
<p class="howto"><?php echo esc_attr( $taxonomy->labels->separate_items_with_commas ); ?></p>
<?php endif; ?>
</div>
<div class="tagchecklist"></div>
</div>
<?php if ( current_user_can($taxonomy->cap->assign_terms) ) : ?>
<p class="hide-if-no-js"><a href="#titlediv" class="tagcloud-link" id="link-<?php echo $tax_name; ?>"><?php echo $taxonomy->labels->choose_from_most_used; ?></a></p>
<?php endif; ?>
<?php
}
这段代码的工作原理应该是… 看…
… 除了在保存帖子时不保存类别元数据。有一点搜索显示我一定是在做某事 like this:
<?php
add_action( 'save_post', 'cd_meta_box_save' );
function cd_meta_box_save( $post_id )
{
// Bail if we're doing an auto save
if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
// if our nonce isn't there, or we can't verify it, bail
if( !isset( $_POST['meta_box_nonce'] ) || !wp_verify_nonce( $_POST['meta_box_nonce'], 'my_meta_box_nonce' ) ) return;
// if our current user can't edit this post, bail
if( !current_user_can( 'edit_post' ) ) return;
// now we can actually save the data
$allowed = array(
'a' => array( // on allow a tags
'href' => array() // and those anchors can only have href attribute
)
);
// Make sure your data is set before trying to save it
if( isset( $_POST['my_meta_box_text'] ) )
update_post_meta( $post_id, 'my_meta_box_text', wp_kses( $_POST['my_meta_box_text'], $allowed ) );
if( isset( $_POST['my_meta_box_select'] ) )
update_post_meta( $post_id, 'my_meta_box_select', esc_attr( $_POST['my_meta_box_select'] ) );
// This is purely my personal preference for saving check-boxes
$chk = isset( $_POST['my_meta_box_check'] ) && $_POST['my_meta_box_select'] ? 'on' : 'off';
update_post_meta( $post_id, 'my_meta_box_check', $chk );
}
?>
但是,由于我正在处理默认功能 (即使用标签 metabox 已经具有多少/什么 wordpress),所以我想知道 save_post
对于’category’ 和’tag’ 元框有什么检查,以及 WordPress 默认情况下是如何进行的。
// Save post metadata when a post is saved.
add_action( 'save_post', 'flatsy_save_cat_meta' );
function flatsy_save_cat_meta( $post_id, $post, $update ) {
return 'WHAT DO I DO HERE? HOW DOES WORDPRESS DO IT FOR THE TAGS METABOX?';
}
如果不是这样做,那么当我将类别 metabox 转换成一个标签 metabox 和 vice-versa(两种情况) 时,代码如何?
澄清:我不想将分类从分层更改为 non-hierarchical 。我只想要一个 tags-like metabox 类别。如果我想要一个 non-hierarchical 分类法,我只需要注册一个自定义分类法。
最佳解决方案
检查出/wp-admin/post.php
文件,其中包含 edit_post()
函数,edit_post()
函数调用 wp_update_post()
,它是一个 wp_insert_post()
包装器。
这是保存分配的类别术语的骨架:
/**
* Saving assigned category terms (skeleton)
*/
add_action( 'admin_action_editpost', function()
{
add_filter( 'wp_insert_post_data', function( $data, $parr )
{
add_action( 'save_post_post', function( $post_ID, $post ) use ( $parr )
{
if(
isset( $parr['_wpnonce'] )
&& wp_verify_nonce( $parr['_wpnonce'], 'update-post_' . absint( $post_ID ) )
&& current_user_can( 'manage_categories' )
&& function_exists( 'wpse_save_assigned_cats' )
&& ! did_action( 'wpse_save_assigned_cats' )
) {
wpse_save_assigned_cats( $post_ID, $parr );
do_action( 'wpse_save_assigned_cats' );
}
}, 10, 2 );
return $data;
}, 10, 2 );
} );
我们的帮助函数 wpse_save_assigned_cats()
基于 edit_post()
功能:
/**
* Helper function based on the cat/tax handling of the edit_post() functions
*/
function wpse_save_assigned_cats( $post_ID, $parr )
{
if( ! empty( $parr['tax_input']['category'] ) && $post_ID > 0 )
{
// Change the comma seperated string of category names,
// in $parr['tax_input']['category'], to an array of cats id
$input_cats = explode( ',', trim( $parr['tax_input']['category'], " ntrx0B," ) );
$clean_cats = array();
foreach ( $input_cats as $cat_name )
{
// Don't allow empty categories
if ( empty( $cat_name ) )
continue;
// Check if there already exists such a category
$_cat = get_terms( 'category', array(
'name' => $cat_name,
'fields' => 'ids',
'hide_empty' => false,
) );
// The category name already exists
if ( ! empty( $_cat ) )
{
// Collect the (first) category id
$clean_cats[] = intval( $_cat[0] );
}
else
{
// Create the category, since it doesn't exists
$cat_id = wp_create_category( $cat_name );
// Collect the category id
if( $cat_id > 0 )
$clean_cats[] = $cat_id;
}
}
// Current post's category IDs
$cats = (array) wp_get_post_categories( $post_ID, array( 'fields' => 'ids' ) );
// Unique array of category IDs
$post_categories = array_unique( array_merge( $cats, $clean_cats ) );
// Assign the categories to the current post
wp_set_post_categories( $post_ID, $post_categories );
}
}
上一个答案:
这是我的星期五答案,所以可能需要一些测试;-)
我只是 re-registered 的 category
分类法作为 non-hierarchical 与:
'hierarchical' => false,
那么类别框出现如下:
并保存条款按预期工作。
这是我的测试代码片段,所以您可以进一步尝试:
add_action( 'init', function()
{
global $wp_rewrite;
register_taxonomy( 'category', 'post', array(
'hierarchical' => false,
'query_var' => 'category_name',
'rewrite' => array(
'hierarchical' => true,
'slug' => get_option('category_base') ? get_option('category_base') : 'category',
'with_front' => ! get_option('category_base') || $wp_rewrite->using_index_permalinks(),
'ep_mask' => EP_CATEGORIES,
),
'public' => true,
'show_ui' => true,
'show_admin_column' => true,
'_builtin' => true,
'labels' => array(
'name' => __( 'Categories' ),
'singular_name' => __( 'Category' ),
'search_items' => __( 'Search Categories' ),
'popular_items' => null,
'all_items' => __( 'All Categories' ),
'edit_item' => __( 'Edit Category' ),
'update_item' => __( 'Update Category' ),
'add_new_item' => __( 'Add New Category' ),
'new_item_name' => __( 'New Category Name' ),
'separate_items_with_commas' => null,
'add_or_remove_items' => null,
'choose_from_most_used' => null,
),
'capabilities' => array(
'manage_terms' => 'manage_categories',
'edit_terms' => 'manage_categories',
'delete_terms' => 'manage_categories',
'assign_terms' => 'edit_posts',
),
) );
} );
参考文献
注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。