Durante creazione di un tema o di un plugin spesso ci troviamo di fronte alla necessità di personalizzare l’editor degli articoli o di un custom post type in base alle peculiarità del sito. Per i casi più semplici esite la possibilità impostare al volo i campi personalizzati, tuttavia l’utilizzo dei metabox permette di ottenere un risultato più pulito e professionale.

Cosa vogliamo ottenere

Vogliamo creare un nuovo campo per l’inserimento di un titolo secondario nell’editor di wordpress. Il nuovo campo sarà visualizzato appena sotto il titolo principale dell’articolo.

titolo secondario

Passo I: registrare un nuovo metabox

Usiamo add_meta_box();. I parametri che possiamo inserire sono:

  • $id
    è l’id html del div contenitore del metabox
  • $title
    è il titolo della sezione che contiente il campo
  • $callback
    è il nome della funzione che genera l’html
  • $post_type
    il tipo di post a cui aggiungeremo il metabox
  • $context
    indica la posizione nella schermata dell’editor (‘normal’, ‘advanced’ o ‘side’).
  • $priority
    è la priorità rispetto ad altri campi (‘high’, ‘core’, ‘default’ o ‘low’)
  • $callback_args
    dà la possibilità di passare parametri alla funzione che genera il codice.

add_action( 'add_meta_boxes', 'isw_add_metabox' );

function isw_add_metabox()
{

		add_meta_box(
			'isw-sottotitolo', // id attributo html
			'Sottotitolo', // titolo del metabox
			'isw_callback_create_html', // funzione di callback che stampa l'html
			'post',  // post type
			'advanced',
			'high'
			);

}

La funzione add_meta_box() non può essere utilizzata da sola ma deve essere inserita in un altra funzione e spedita all’hook add_meta_boxes. Si tratta di un action hook che permette di registrare tutte le nuove sezioni prima che vengano visualizzate nella schermata di modifica degli articoli.

La funzione seguente è quella che genera l’html del nuovo input. Il suo nome deve essere inserito come terzo parametro della funzione add_meta_box() di sopra


function isw_callback_create_html( $post )
{
       // preleviamo i dati inseriti se esistono per il camp aggiuntivo
       $sottotitolo = esc_html( get_post_meta( $post->ID, 'sottotitolo', true ) );

       ?>
	       	<tr>
	       		<td>
	       		 	<input type="text" size="100"  name="sottotitolo" value="<?php echo $sottotitolo; ?>" />
	       		</td>
	       	</tr>

       	<?php 

}

Passo II: salvare i dati nel database quando salviamo il post

A questo punto vediamo che è comparso il nuovo campo sotto l’editor di testo. Tuttavia se proviamo a inserie qualche parola e ad aggiornare l’articolo vedremo che i dati non verranno salvati nel database.
È necessario prelevare il testo presente in $_POST[ ‘sottotitolo’ ] nel momento in cui si salva l’articolo e poi registrarlo nel database attraverso la funzione update_post_meta().
Per fare questo lavoro ci agganceremo all’hook save_post.

add_action( 'save_post', 'isw_save_with_post', 10, 2 );

function isw_save_with_post( $post_id = false, $post = false )
{
	 // se il contenuto che stiamo salvando è un articolo
	if ( $post->post_type == 'post' )
	{
		// recupera i dati inviati dal form nel campo 'sottotitolo' aggiorna il database
		if ( !empty( $_POST['sottotitolo'] ) )
			update_post_meta( $post_id, 'sottotitolo',  $_POST['sottotitolo'] );
	}
}

Passo III: Posizionare il nuovo metabox

Utilizziamo l’action hook edit_form_after_title che permette di inserirsi nel codice subito dopo che il campo per i titoli è stato creato.
La funzione do_meta_boxes() consente di visualizzare un gruppo di metabox in base alla posizione in cui sono stati registrati es. (side, normal). Nel nostro caso ci interessa visualizzare il campo che abbiamo registrato in ‘advanced‘.
Con la funzione remove_meta_box() invece disabilitiamo i campi ‘advanced’ nella loro posizione di default.


// Sposta i meta box con context = advanced dopo il titolo
add_action( 'edit_form_after_title', 'isw_output_after_title');

function isw_output_after_title()
{
    global $post, $wp_meta_boxes;
    // stampiamo tutti i campi advanced
    do_meta_boxes( get_current_screen(), 'advanced', $post );
    // disabilitiamo i campi advanced, altrimenti risulterebbero doppi
    //unset( $wp_meta_boxes[get_post_type( $post )][ 'advanced '] );
    remove_meta_box( 'isw-sottotitolo', 'post', 'advanced' );
}

In pratica bisogna rimuovere il nuovo metabox dalla sua posizione predefinita (subito dopo l’editor di testo) per posizionarlo sotto il campo del titolo.

Passo IV: Visualizzare il sottotitolo

Una volta capito quale file template genera l’html (nel tema twentyfourteen è il file content.php) inseriamo un codice simile al seguente


if ( $sub_tit = get_post_meta( get_the_ID(), 'sottotitolo', true ))
{
	echo '<h2 class="sub-title">' . $sub_tit . '</h2>';
}

Passo V: estendere il campo per i sottotitoli ad altri tipi di post

Per insirire il nuovo campo in altri post type è sufficiente ripetere la registrazione del metabox per ogni tipo di post. A tale scopo possiamo utilizzare un ciclo foreach:


function isw_add_metabox()
{
		$posttypes = array( 'post', 'page', 'tutorial' );

		foreach ($posttypes as $type)
		{
			add_meta_box(
			'isw-sottotitolo', // id attributo html
			'Sottotitolo', // titolo del metabox
			'isw_callback_create_html', // funzione di callback che stampa l'html
			$type,  // post type
			'advanced',
			'high'
			);
		}

}

Inoltre è necessario modificare la funzione per la registrazione nel database dei valori. In questo caso bisogna allargare la condizione iniziale ai casi in cui stiamo salvando una pagina o un tutorial.


add_action( 'save_post', 'isw_save_with_post', 10, 2 );

function isw_save_with_post( $post_id = false, $post = false )
{
	 // se il contenuto che stiamo salvando è un articolo oppure una pagina o un tutorial
	if ( $post->post_type == 'post' || $post->post_type == 'page' || $post->post_type == 'tutorial')
	{
		// recupera i dati inviati dal form nel campo sottotitolo' aggiorna il database
		if ( !empty( $_POST['sottotitolo'] ) )
			update_post_meta( $post_id, 'sottotitolo',  $_POST['sottotitolo'] );
	}
}

Modifichiamo anche isw_output_after_title() per rimuovere il doppio campo anche ai post type doversi dagli articoli.

function isw_output_after_title()
{
    global $post, $wp_meta_boxes;
    // stampiamo tutti i campi advanced
    do_meta_boxes( get_current_screen(), 'advanced', $post );
    // disabilitiamo i campi advanced, altrimenti risulterebbero doppi
    remove_meta_box( 'isw-sottotitolo', get_post_type( $post ), 'advanced' );

}

Codice completo per post e pagine

add_action( 'add_meta_boxes', 'isw_add_metabox' );
 
function isw_add_metabox()
{
 
        $posttypes = array( 'post', 'page' );
 
        foreach ($posttypes as $type)
        {
            add_meta_box(
            'isw-sottotitolo', // id attributo html
            'Sottotitolo', // titolo del metabox
            'isw_callback_create_html', // funzione di callback che stampa l'html
            $type,  // post type
            'advanced',
            'high'
            );
        }
 
}


function isw_callback_create_html( $post )
{
       // preleviamo i dati inseriti se esistono per il camp aggiuntivo
       $sottotitolo = esc_html( get_post_meta( $post->ID, 'sottotitolo', true ) );
 
       ?>
            <tr>
                <td>
                    <input style="padding: 3px 8px; font-size: 1.7em; line-height: 100%; height: 1.7em; width: 100%; outline: 0; margin: 0; background-color: #fff;" type="text" size="100"  name="sottotitolo" value="<?php echo $sottotitolo; ?>" />
                </td>
            </tr>
 
        <?php 
 
}


add_action( 'save_post', 'isw_save_with_post', 10, 2 );
 
function isw_save_with_post( $post_id = false, $post = false )
{
     // se il contenuto che stiamo salvando è un articolo oppure una pagina o un tutorial
    if ( $post->post_type == 'post' || $post->post_type == 'page' )
    {
        // recupera i dati inviati dal form nel campo sottotitolo' aggiorna il database
        if ( !empty( $_POST['sottotitolo'] ) )
            update_post_meta( $post_id, 'sottotitolo',  $_POST['sottotitolo'] );
    }
}



// Sposta i meta box con context = advanced dopo il titolo
add_action( 'edit_form_after_title', 'isw_output_after_title');
 


function isw_output_after_title()
{
    global $post, $wp_meta_boxes;
    // stampiamo tutti i campi advanced
    do_meta_boxes( get_current_screen(), 'advanced', $post );
    // disabilitiamo i campi advanced, altrimenti risulterebbero doppi
    remove_meta_box( 'isw-sottotitolo', get_post_type( $post ), 'advanced' );

}

  inStileWeb.com
blog comments powered by Disqus