web-dev-qa-db-ja.com

'tag'と 'category'(デフォルト)の分類法はどのように 'save_post'アクションをしますか?

適切なカテゴリとサブカテゴリをチェックするには階層が多すぎてスクロールできないため、メタボックスカテゴリをメタボックスタグのように見え、動作するものに置き換えようとしています。だから私の場合はタグのようなメタボックスが良いです。

これが私のやり方です。

/*
 * 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
}

そのコードは意図したとおりに機能します。

The categories metabox now looks like the tags metabox 

...except投稿が保存されてもカテゴリメタデータは保存されません。ちょっとした検索の結果、私は何かをしなければならないことがわかりました このように

<?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 );
}
?>

しかし、私はデフォルトの機能(つまり、どのように/どのワードプレスが既にタグメタボックスを使っているか)を扱っているので、私は 'category'と 'tag'メタボックスのsave_postのチェックと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?';

}

ANDそれがうまくいかない場合、カテゴリメタボックスをタグメタボックスに、またはその逆に変換する場合、コードはどのようになりますか(2つの場合)?


分類:カテゴリを階層から非階層に変更したくない。私はただカテゴリーのためのタグのようなメタボックスが欲しいのです。非階層的分類法が必要な場合は、カスタム分類法を登録しただけです。

6
its_me

edit_post()を呼び出すwp_update_post()関数が含まれている/wp-admin/post.phpファイルをチェックすると有益です。これは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'], " \n\t\r\0\x0B," ) );
        $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 );
    }   
}

前の回答:

これが私の金曜日の答えです、それでそれはいくらかのテストを必要とするかもしれません;-)

category分類法をnon-hierarchyとして再登録したところです。

        'hierarchical' => false,

それからカテゴリボックスはこのように現れました:

category 

保存条件は期待通りに機能しました。

これが私のテストコードスニペットなので、さらに試すことができます。

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',
        ),
    ) );
} );
5
birgire

'tag'と 'category'(デフォルト)の分類法はどのように 'save_post'アクションをしますか?

そうではありません。

分類法はsave_postアクションでは処理されず、すべてwp_insert_post内で直接行われます。 あなたはここでソースでそれを見ることができます

あなたのコールバックで wp_set_object_terms を使ってあなたのカスタムメタボックスから用語を保存することができます。

2
Milo