Como posso colocar uma meta box personalizada acima do editor, mas abaixo da seção de título na página de edição da postagem?

30

Eu tenho uma caixa meta personalizada para um tipo de postagem personalizado que meu cliente deseja colocar entre a seção title / permalink e o editor de postagem no painel de administração. Isso é possível e, se houver, existe um gancho / filtro / etc que eu precisaria usar?

cstrouse
fonte
Pergunta muito semelhante aqui: wordpress.stackexchange.com/questions/35416/…
Simon East

Respostas:

51
  • Basta adicionar uma meta box usando o contexto avançado e alta prioridade
  • Em seguida, edit_form_after_titleprenda no gancho
  • Imprima suas caixas de meta e remova-as para que não apareçam duas vezes.

    // 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']);
    });
    
Andrew
fonte
Um site em que estou trabalhando registra alguns metaboxes usando o register_meta_box_cbparâmetro da register_post_typefunção Eu tentei seu código, mas os metaboxes não se movem acima do editor. Isso pode ser usado no meu caso? Graças
Leemon
Eu recomendaria usar um personalizado $context, em vez de advancedusar algo como my_before_editor, para que você não mova todas as meta boxes no advancedcontexto, direcione-as especificamente para as meta boxes específicas. Consulte developer.wordpress.org/reference/functions/add_meta_box
farinspace
14

Aqui está como você pode mover meta boxes específicos acima do editor, mas antes de publicar o código, gostaria de agradecer a Andrew e mhulse. Vocês são foda!

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');
adamj
fonte
11
change to something other then normal, advanced or side-foi a chave no meu caso. Obrigado pela informação.
Mayeenul Islam
Esta foi a resposta mais útil para mim. Obrigado!
Marvinpoo #
12

Para fornecer um exemplo de código completo com base na resposta de Andrew ... eu precisava de uma maneira de incluir um "Deck" (também conhecido como subtítulo) em minhas postagens; Eu queria que o campo do deck aparecesse após a barra de título principal.

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

Obviamente, o código acima poderia usar um pouco mais de trabalho, mas deve ajudar outras pessoas que tentam fazer as mesmas coisas (a resposta de Andrew brilhou, mas achei que seria útil fornecer um exemplo de trabalho).

Esta resposta também ajudou .

Melhorias que poderiam ser feitas:

  1. Faça OOP / classe (s).
  2. Adicione styles / js para que pareça / sinta / se comporte como o campo do título.

Eu pretendo fazer as melhorias acima em algum momento no futuro, mas pelo menos o código acima deve ajudar outras pessoas a tentar descobrir isso.

Veja o código fonte aqui para obter mais inspiração (eles optaram por usar o jQuery para mover o "subtítulo").

mhulse
fonte
Caso isso ajude alguém a seguir o mesmo caminho: fiz uma pergunta aqui com código relacionado / semelhante (optei por usar o campo "title" para conter e filtrar o subtítulo).
Mhulse
6

Em vez de mover tudo na seção avançada para o topo, por que não criar uma nova seção e movê-la para o topo:

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

Agora tudo o que você precisa fazer é registrar a meta box usando topa seção e higha prioridade.

Está funcionando no WordPress 4.4.2 para mim. Não testei isso em outras versões do WP.

titanic_fanatic
fonte
1

Existe uma outra maneira, pela maneira como podemos colocar o editor em qualquer posição:

  1. Remova o editor dos parâmetros de suporte ao registrar post_type

  2. adicione um metabox falso

    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' );
Hix.botay
fonte
Para sua informação, isso ainda funciona, mas quando você move a caixa, ele causa um comportamento estranho com o conteúdo do campo. Os usuários devem ficar atentos.
Eckstein