it-swarm-eu.dev

Jakým způsobem „taxonomie značky“ a „kategorie“ (výchozí) provádějí akci „save_post“?

Snažím se nahradit kategorie metabox tím, co vypadá a funguje jako metabox značek, protože příliš mnoho hierarchie a posouvání pro kontrolu příslušných kategorií a podkategorií není možností. V mém případě je tedy metabox jako tag lepší.

Takhle to dělám:

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

Ten kód funguje tak, jak by měl ... vidět ...

 The categories metabox now looks like the tags metabox 

... kromě že neuloží metadata kategorie, když je příspěvek uložen. Trochu hledání odhalilo, že musím dělat něco takhle :

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

Ale jak jsem se zabývají výchozí funkcí (tj. Jak/co wordpress již dělá s tagy metabox), Chci vědět, jaké kontroly jsou v místě pro save_post pro 'kategorie' a 'tag' meta boxy a jak WordPress dělá standardně.

// 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?';

}

A pokud to tak není, co by měl kód vypadat, když konvertuji metabox kategorie, aby vypadal jako tag metabox a naopak (dva případy)?


CLARIFICATION: Nechci měnit kategorie z hierarchické na nehierarchickou. Chci jen tag-metabox pro kategorie. Kdybych chtěl nehierarchickou taxonomii, jednoduše bych zaregistroval vlastní taxonomii.

6
its_me

Je informativní zkontrolovat soubor /wp-admin/post.php, který obsahuje funkci edit_post(), která volá wp_update_post(), což je wp_insert_post() wrapper.

Zde je kostra pro uložení přiřazených výrazů kategorie:

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

kde naše pomocná funkce wpse_save_assigned_cats() je založena na funkci 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 );
    }   
}

Předchozí odpověď:

Zde je můj páteční odpověď, takže možná bude třeba nějaké testování ;-)

Právě jsem znovu zaregistroval taxonomii category jako nehierarchický with:

        'hierarchical' => false,

Pak se zobrazí toto pole:

 category 

a úsporné podmínky fungovaly podle očekávání.

Zde je můj úryvek z testovacího kódu, takže si ho můžete vyzkoušet dále:

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

Jakým způsobem „taxonomie značky“ a „kategorie“ (výchozí) provádějí akci „save_post“?

Ne!

Taxonomie se nezabývají akcí save_post, vše se děje přímo v wp_insert_post. Vidíte to ve zdroji zde .

Můžete použít wp_set_object_terms ve svém zpětném volání pro uložení podmínek z vlastního metaboxu.

2
Milo