web-dev-qa-db-fra.com

Ajouter des attributs de page standard Metabox pour le parent de page

J'ai un type de publication personnalisé 'produit' qui m'a été fourni par un plugin Wordpress eCommerce qui n'offre pas la possibilité de changer le parent de la page dans le Metabox des attributs de la page. J'aimerais remédier à cela.

J'ai trouvé ce message sur Wordpress StackExchange, mais il traite spécifiquement de l'élément Modèle de page du Metabox Attributs de page. Quelqu'un peut-il extrapoler sur la très bonne réponse fournie dans cette autre question WSE pour répondre à mes besoins? Il peut même inclure toutes les options Metabox des attributs de page. Il n'est pas nécessaire de le réduire à Page Parent. Mais Page Parent est celui dont j'ai besoin.


Edit # 2: Voici ce que j'ai jusqu'à présent. La métabox apparaît avec la liste déroulante appropriée, mais je ne peux pas enregistrer le parent_id. Il semble que la page admin/post.php ne capture pas la variable $ _POST ['parent_id']. Existe-t-il une fonctionnalité de Wordpress qui n'autorise pas les types de publication personnalisés non hiérarchiques à avoir des identifiants parent? Ou devrais-je regarder quelque part dans le code Woocommerce?

    function product_attributes_meta_box($post) {
        $dropdown_args = array(
            'post_type'        => 'page',
            'exclude_tree'     => $post->ID,
            'selected'         => $post->post_parent,
            'name'             => 'parent_id',
            'show_option_none' => __('(no parent)'),
            'sort_column'      => 'menu_order, post_title',
            'echo'             => 0,
            'child_of'         => 282, // Sales Page
        );

        $dropdown_args = apply_filters( 'page_attributes_dropdown_pages_args', $dropdown_args, $post );
        $pages = wp_dropdown_pages( $dropdown_args );
        if ( ! empty($pages) ) {
?>
<p><strong><?php _e('Parent') ?></strong></p>
<label class="screen-reader-text" for="parent_id"><?php _e('Parent') ?></label>
<?php echo $pages; ?>
<?php
        } // end empty pages check
    }
    add_action('add_meta_boxes','add_post_template_metabox');
    function add_post_template_metabox() {
        add_meta_box('postparentdiv', __('Page Parent'), 'product_attributes_meta_box', 'product', 'side', 'core');
    }
    add_action('save_post','save_post_parent',10,2);
    function save_post_parent($post_id,$post) {
      if ($post->post_type=='product' && !empty($_POST['parent_id'])
      ) {
        update_post_meta($post->ID,'_parent_id',$_POST['parent_id']);
      }
    }

Éditer # 3: J'ai changé le type de message personnalisé 'product' en hierarchical => true mais la page post.php ne capture toujours pas la variable $ _POST ['parent_id']. J'ai également essayé de commenter remove_meta_box( 'pageparentdiv', 'product', 'side' ); dans le fichier woocommerce.php et de supprimer TOUT mon code personnalisé ci-dessus, mais la page parent n'est toujours pas enregistrée.

1
Timothy D

Bien que non répertorié dans les ressources suivantes, il semble que parent_id soit un nom réservé dans $_POST et $_REQUEST:

Ce code fonctionne dans une page de produit Woocommerce pour afficher une liste déroulante de pages normales. De plus, dans votre code, il manquait le get_post_meta pour renseigner la valeur de l'argument selected.

add_action( 'add_meta_boxes','add_metabox_wpse_83542' );
add_action( 'save_post', 'save_post_wpse_83542', 10, 2 );

function add_metabox_wpse_83542() 
{
    add_meta_box(
        'postparentdiv', 
        __('Page Parent'), 
        'meta_box_content_wpse_83542', 
        'product', 
        'side', 
        'core'
    );
}

function meta_box_content_wpse_83542( $post ) 
{
    $meta = get_post_meta( $post->ID, '_parent_id', true );
    $selected = ( isset( $meta ) ) ? $meta : '';
    $dropdown_args = array(
        'post_type'        => 'page',
        'exclude_tree'     => $post->ID,
        'selected'         => $selected,
        'name'             => '_parent_id',
        'show_option_none' => __( '(no parent)' ),
        'sort_column'      => 'menu_order, post_title',
        'echo'             => 0,
        'child_of'         => 97, // Sales Page
    );

    $dropdown_args = apply_filters( 'page_attributes_dropdown_pages_args', $dropdown_args, $post );
    $pages = wp_dropdown_pages( $dropdown_args );

    if ( ! empty($pages) ) 
    {
        wp_nonce_field( plugin_basename( __FILE__ ), 'noncename_wpse_83542' );          
        ?>
        <p><strong><?php _e('Parent') ?></strong></p>
        <label class="screen-reader-text" for="parent_id"><?php _e('Parent') ?></label>
        <?php 
        echo $pages; 
    } // end empty pages check
}    

function save_post_wpse_83542( $post_id, $post ) 
{
    // Block on Autosave
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )  
        return;

    // Block Revisions
    if ( 'revision' == $post->post_type )
        return;

    // Nonce verify
    if ( !wp_verify_nonce( $_POST['noncename_wpse_83542'], plugin_basename( __FILE__ ) ) )
        return;

    if ( $post->post_type == 'product' && !empty( $_POST['_parent_id'] ) ) 
    {
        update_post_meta( $post->ID, '_parent_id', $_POST['_parent_id'] );
    }
}
1
brasofilo