Comment puis-je mettre une méta-boîte personnalisée au-dessus de l'éditeur mais en dessous de la section de titre sur la page d'édition du message?


30

J'ai une boîte de méta personnalisée pour un type de publication personnalisé que mon client souhaite placer entre la section titre / permalien et l'éditeur de publication dans le panneau d'administration. Est-ce possible et dans l'affirmative, existe-t-il un crochet / filtre / etc que je devrais utiliser?


Réponses:


51
  • Ajoutez simplement une méta-boîte en utilisant le contexte avancé et la priorité élevée
  • Ensuite, edit_form_after_titleaccrochez-vous au crochet
  • Imprimez vos méta-boîtes, puis supprimez-les afin qu'elles n'apparaissent pas deux fois.

    // Move all "advanced" metaboxes above the default editor
    add_action('edit_form_after_title', function() {
        global $post, $wp_meta_boxes;
        do_meta_boxes(get_current_screen(), 'advanced', $post);
        unset($wp_meta_boxes[get_post_type($post)]['advanced']);
    });

Un site sur lequel je travaille enregistre des métaboxes en utilisant le register_meta_box_cbparamètre de la register_post_typefonction. J'ai essayé votre code mais les métaboxes ne se déplacent pas au dessus de l'éditeur. Cela peut-il être utilisé dans mon cas? Merci
leemon

Je recommanderais d'utiliser une méthode personnalisée $context, au lieu de advanced, utiliser quelque chose comme my_before_editor, de sorte que vous ne déplacez pas toutes les méta-boîtes dans le advancedcontexte, vous ciblez spécifiquement vos méta-boîtes spécifiques. Voir developer.wordpress.org/reference/functions/add_meta_box
farinspace

14

Voici comment déplacer des métadonnées spécifiques au-dessus de l'éditeur, mais avant de publier le code, je voudrais simplement remercier Andrew et mhulse. Vous êtes top les gars!

function foo_deck( $post_type ) {
    if ( in_array( $post_type, array( 'post', 'page' ) ) ) {
        add_meta_box(
            'contact_details_meta',
            'Contact Details',
            'contact_details_meta',
            $post_type,
            'test', // change to something other then normal, advanced or side
            'high'
        );
    }
}

add_action('add_meta_boxes', 'foo_deck');

function foo_move_deck() {
        # Get the globals:
        global $post, $wp_meta_boxes;

        # Output the "advanced" meta boxes:
        do_meta_boxes( get_current_screen(), 'test', $post );

        # Remove the initial "advanced" meta boxes:
        unset($wp_meta_boxes['post']['test']);
    }

add_action('edit_form_after_title', 'foo_move_deck');

1
change to something other then normal, advanced or side-était la clé dans mon cas. Merci pour l'info.
Mayeenul Islam

Ce fut la réponse la plus utile pour moi. Merci!
marvinpoo

12

Pour fournir un exemple de code complet basé sur la réponse d'Andrew ... J'avais besoin d'un moyen d'inclure un "Deck" (aka sous-titre) à mes messages; Je voulais que le champ du deck apparaisse après la barre de titre principale.

/**
 * Add a "deck" (aka subhead) meta box to post page(s) and position it
 * under the title.
 *
 * @todo Move to class.
 * @see http://codex.wordpress.org/Function_Reference/add_meta_box
 * @see http://wordpress.org/extend/ideas/topic/add-meta-box-to-multiple-post-types
 * @see https://github.com/Horttcore/WordPress-Subtitle
 * @see http://codex.wordpress.org/Function_Reference/wp_nonce_field
 */

# Adds a box to the main column on the Post and Page edit screens:
function foo_deck($post_type) {

    # Allowed post types to show meta box:
    $post_types = array('post', 'page');

    if (in_array($post_type, $post_types)) {

        # Add a meta box to the administrative interface:
        add_meta_box(
            'foo-deck-meta-box', // HTML 'id' attribute of the edit screen section.
            'Deck',              // Title of the edit screen section, visible to user.
            'foo_deck_meta_box', // Function that prints out the HTML for the edit screen section.
            $post_type,          // The type of Write screen on which to show the edit screen section.
            'advanced',          // The part of the page where the edit screen section should be shown.
            'high'               // The priority within the context where the boxes should show.
        );

    }

}

# Callback that prints the box content:
function foo_deck_meta_box($post) {

    # Use `get_post_meta()` to retrieve an existing value from the database and use the value for the form:
    $deck = get_post_meta($post->ID, '_deck', true);

    # Form field to display:
    ?>

        <label class="screen-reader-text" for="foo_deck">Deck</label>
        <input id="foo_deck" type="text" autocomplete="off" value="<?=esc_attr($deck)?>" name="foo_deck" placeholder="Deck">

    <?php

    # Display the nonce hidden form field:
    wp_nonce_field(
        plugin_basename(__FILE__), // Action name.
        'foo_deck_meta_box'        // Nonce name.
    );

}

/**
 * @see https://wordpress.stackexchange.com/a/16267/32387
 */

# Save our custom data when the post is saved:
function foo_deck_save_postdata($post_id) {

    # Is the current user is authorised to do this action?
    if ((($_POST['post_type'] === 'page') && current_user_can('edit_page', $post_id) || current_user_can('edit_post', $post_id))) { // If it's a page, OR, if it's a post, can the user edit it? 

        # Stop WP from clearing custom fields on autosave:
        if ((( ! defined('DOING_AUTOSAVE')) || ( ! DOING_AUTOSAVE)) && (( ! defined('DOING_AJAX')) || ( ! DOING_AJAX))) {

            # Nonce verification:
            if (wp_verify_nonce($_POST['foo_deck_meta_box'], plugin_basename(__FILE__))) {

                # Get the posted deck:
                $deck = sanitize_text_field($_POST['foo_deck']);

                # Add, update or delete?
                if ($deck !== '') {

                    # Deck exists, so add OR update it:
                    add_post_meta($post_id, '_deck', $deck, true) OR update_post_meta($post_id, '_deck', $deck);

                } else {

                    # Deck empty or removed:
                    delete_post_meta($post_id, '_deck');

                }

            }

        }

    }

}

# Get the deck:
function foo_get_deck($post_id = FALSE) {

    $post_id = ($post_id) ? $post_id : get_the_ID();

    return apply_filters('foo_the_deck', get_post_meta($post_id, '_deck', TRUE));

}

# Display deck (this will feel better when OOP):
function foo_the_deck() {

    echo foo_get_deck(get_the_ID());

}

# Conditional checker:
function foo_has_subtitle($post_id = FALSE) {

    if (foo_get_deck($post_id)) return TRUE;

}

# Define the custom box:
add_action('add_meta_boxes', 'foo_deck');
# Do something with the data entered:
add_action('save_post', 'foo_deck_save_postdata');

/**
 * @see https://wordpress.stackexchange.com/questions/36600
 * @see https://wordpress.stackexchange.com/questions/94530/
 */

# Now move advanced meta boxes after the title:
function foo_move_deck() {

    # Get the globals:
    global $post, $wp_meta_boxes;

    # Output the "advanced" meta boxes:
    do_meta_boxes(get_current_screen(), 'advanced', $post);

    # Remove the initial "advanced" meta boxes:
    unset($wp_meta_boxes['post']['advanced']);

}

add_action('edit_form_after_title', 'foo_move_deck');

De toute évidence, le code ci-dessus pourrait utiliser un peu plus de travail, mais il devrait aider les autres à essayer de faire la même chose (la réponse d'Andrew a brillé, mais j'ai pensé qu'il pourrait être utile de fournir un exemple de travail).

Cette réponse a également aidé .

Améliorations qui pourraient être apportées:

  1. Créez des POO / classe (s).
  2. Ajoutez des styles / js pour lui donner l'apparence / la sensation / le comportement du champ de titre.

Je prévois d'apporter les améliorations ci-dessus à un moment donné à l'avenir, mais au moins le code ci-dessus devrait aider les autres à essayer de comprendre cela.

Voir le code source ici pour plus d'inspiration (ils ont choisi d'utiliser jQuery pour déplacer le "sous-titre").


Au cas où cela aiderait quelqu'un à suivre le même chemin: j'ai posé une question ici qui a un code similaire / similaire (j'ai choisi d'utiliser le champ "title" pour contenir et filtrer la sous-rubrique).
mhulse

6

Au lieu de tout déplacer dans la section avancée vers le haut, pourquoi ne pas créer une nouvelle section et la déplacer vers le haut:

// Create 'top' section and move that to the top
add_action('edit_form_after_title', function() {
  global $post, $wp_meta_boxes;
  do_meta_boxes(get_current_screen(), 'top', $post);
  unset($wp_meta_boxes[get_post_type($post)]['top']);
});

Il ne vous reste plus qu'à enregistrer la méta-boîte à l'aide topde la section et highde la priorité.

Cela fonctionne sur WordPress 4.4.2 pour moi. Je n'ai pas testé cela sur d'autres versions de WP.


1

Il y a une autre façon, en passant, de mettre l'éditeur dans n'importe quelle position:

  1. Supprimer l'éditeur du paramètre de support lorsque vous enregistrez post_type

  2. ajouter un faux metabox

    add_meta_box( 'does-not-matter', 
    __( 'Description'), 
    function($post){ 
      wp_editor($post->post_content,'post_content',array('name'=>'post_content'));
    },
    'post_type_type', 
    'advanced', 
    'high' );

Pour info, cela fonctionne toujours, mais lorsque vous déplacez la boîte, cela provoque un comportement étrange avec le contenu du champ. Attention aux utilisateurs.
Eckstein
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.