Cum pot pune o casetă meta personalizată deasupra editorului, dar sub secțiunea de titlu în pagina de editare a articolului?
Am o casetă meta personalizată pentru un tip de postare personalizat pe care clientul meu dorește să o plaseze între secțiunea titlu/permalink și editorul de postări în panoul de administrare. Este posibil acest lucru și, dacă da, ce hook/filtru/etc ar trebui să folosesc?

- Adaugă simplu un meta box folosind contextul avansat și prioritatea înaltă
- Apoi, conectează-te la hook-ul
edit_form_after_title
Afișează meta box-urile tale acolo, apoi elimină-l ca să nu apară de două ori.
// Mută toate meta box-urile "avansate" deasupra editorului implicit 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 la care lucrez înregistrează unele metabox-uri folosind parametrul register_meta_box_cb
al funcției register_post_type
. Am încercat codul tău, dar metabox-urile nu se mută deasupra editorului. Poate fi folosit în cazul meu? Mulțumesc

Aș recomanda să folosești un $context
personalizat, în loc de advanced
, folosește ceva de genul my_before_editor
, astfel încât să nu muți toate metabox-urile din contextul advanced
, ci să țintești anumite metabox-uri specifice... vezi https://developer.wordpress.org/reference/functions/add_meta_box/

edit_form_after_title
nu este suportat de editorul pe blocuri https://github.com/WordPress/gutenberg/issues/5821

Iată cum poți muta cutiile meta specifice deasupra editorului, dar înainte de a posta codul, aș dori să le mulțumesc lui Andrew și mhulse. Sunteți grozavi!
function foo_deck( $post_type ) {
if ( in_array( $post_type, array( 'post', 'page' ) ) ) {
add_meta_box(
'contact_details_meta',
'Detalii de contact', // Tradus: Contact Details
'contact_details_meta',
$post_type,
'test', // schimbă în altceva decât normal, advanced sau side
'high'
);
}
}
add_action('add_meta_boxes', 'foo_deck');
function foo_move_deck() {
# Obține variabilele globale:
global $post, $wp_meta_boxes;
# Afișează cutiile meta "avansate":
do_meta_boxes( get_current_screen(), 'test', $post );
# Elimină cutiile meta "avansate" inițiale:
unset($wp_meta_boxes['post']['test']);
}
add_action('edit_form_after_title', 'foo_move_deck');

Pentru a oferi un exemplu complet de cod bazat pe răspunsul lui Andrew ... Am avut nevoie de o modalitate de a include un "Deck" (subtitlu) în postările mele; am dorit ca câmpul deck să apară după bara principală de titlu.
/**
* Adaugă o cutie meta "deck" (subtitlu) la pagina de editare a postărilor și o poziționează
* sub titlu.
*
* @todo Mută într-o clasă.
* @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
*/
# Adaugă o cutie în coloana principală pe ecranele de editare Post și Pagină:
function foo_deck($post_type) {
# Tipuri de postări permise pentru afișarea cutiei meta:
$post_types = array('post', 'page');
if (in_array($post_type, $post_types)) {
# Adaugă o cutie meta în interfața administrativă:
add_meta_box(
'foo-deck-meta-box', // Atributul HTML 'id' al secțiunii de editare.
'Deck', // Titlul secțiunii de editare, vizibil utilizatorului.
'foo_deck_meta_box', // Funcția care afișează HTML-ul pentru secțiunea de editare.
$post_type, // Tipul de ecran Write în care să se afișeze secțiunea de editare.
'advanced', // Parte a paginii unde ar trebui să apară secțiunea de editare.
'high' // Prioritatea în contextul unde cutiile ar trebui să apară.
);
}
}
# Callback care afișează conținutul cutiei:
function foo_deck_meta_box($post) {
# Folosește `get_post_meta()` pentru a prelua o valoare existentă din baza de date și o folosește pentru formular:
$deck = get_post_meta($post->ID, '_deck', true);
# Câmp de formular de afișat:
?>
<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
# Afișează câmpul ascuns nonce al formularului:
wp_nonce_field(
plugin_basename(__FILE__), // Numele acțiunii.
'foo_deck_meta_box' // Numele nonce.
);
}
/**
* @see https://wordpress.stackexchange.com/a/16267/32387
*/
# Salvează datele noastre personalizate când postarea este salvată:
function foo_deck_save_postdata($post_id) {
# Este utilizatorul curent autorizat să facă această acțiune?
if ((($_POST['post_type'] === 'page') && current_user_can('edit_page', $post_id) || current_user_can('edit_post', $post_id))) { // Dacă este o pagină, SAU, dacă este o postare, poate utilizatorul să o editeze?
# Oprește WP de a șterge câmpurile personalizate la autosalvare:
if ((( ! defined('DOING_AUTOSAVE')) || ( ! DOING_AUTOSAVE)) && (( ! defined('DOING_AJAX')) || ( ! DOING_AJAX))) {
# Verificare nonce:
if (wp_verify_nonce($_POST['foo_deck_meta_box'], plugin_basename(__FILE__))) {
# Preluare deck postat:
$deck = sanitize_text_field($_POST['foo_deck']);
# Adaugă, actualizează sau șterge?
if ($deck !== '') {
# Deck existent, deci adaugă SAU actualizează:
add_post_meta($post_id, '_deck', $deck, true) OR update_post_meta($post_id, '_deck', $deck);
} else {
# Deck gol sau șters:
delete_post_meta($post_id, '_deck');
}
}
}
}
}
# Obține deck-ul:
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));
}
# Afișează deck (va fi mai elegant când va fi OOP):
function foo_the_deck() {
echo foo_get_deck(get_the_ID());
}
# Verificare condițională:
function foo_has_subtitle($post_id = FALSE) {
if (foo_get_deck($post_id)) return TRUE;
}
# Definește cutia personalizată:
add_action('add_meta_boxes', 'foo_deck');
# Fă ceva cu datele introduse:
add_action('save_post', 'foo_deck_save_postdata');
/**
* @see https://wordpress.stackexchange.com/questions/36600
* @see https://wordpress.stackexchange.com/questions/94530/
*/
# Mută acum cutiile meta avansate după titlu:
function foo_move_deck() {
# Obține variabilele globale:
global $post, $wp_meta_boxes;
# Afișează cutiile meta "avansate":
do_meta_boxes(get_current_screen(), 'advanced', $post);
# Elimină cutiile meta "avansate" inițiale:
unset($wp_meta_boxes['post']['advanced']);
}
add_action('edit_form_after_title', 'foo_move_deck');
Evident, codul de mai sus ar putea fi îmbunătățit, dar ar trebui să ajute pe alții care încearcă să facă același lucru (răspunsul lui Andrew a dat indicații, dar am considerat util să ofer un exemplu funcțional).
Acest răspuns a fost de asemenea util.
Îmbunătățiri posibile:
- Transformarea în OOP/clase.
- Adăugare de stiluri/js pentru a arăta/simți/se comporta ca câmpul de titlu.
Planific să fac aceste îmbunătățiri în viitor, dar cel puțin codul de mai sus ar trebui să ajute pe alții care încearcă să rezolve această problemă.
Vezi codul sursă aici pentru mai multă inspirație (ei au ales să folosească jQuery pentru a muta "sub-titlul").

În caz că ajută pe cineva care merge pe aceeași cale: Am pus o întrebare aici care conține un cod similar/înrudit (am ales să folosesc câmpul "title" pentru a stoca și filtra subtitlul).

În loc să mutăm totul din secțiunea avansată în partea de sus, de ce să nu creăm o nouă secțiune și să o mutăm acolo:
// Creăm secțiunea 'top' și o mutăm în partea de sus
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']);
});
Acum tot ce trebuie să faci este să înregistrezi meta box-ul folosind top
pentru secțiune și high
pentru prioritate.
Funcționează pe WordPress 4.4.2 pentru mine. Nu am testat acest lucru pe alte versiuni de WP.

Există o altă metodă, prin care putem poziționa editorul în orice locație dorită:
Elimină editorul din parametrul 'support' la înregistrarea tipului de postare
Adaugă un metabox fals
add_meta_box( 'does-not-matter', __( 'Descriere'), function($post){ wp_editor($post->post_content,'post_content',array('name'=>'post_content')); }, 'post_type_type', 'advanced', 'high' );
