✅ Notizie, temi, plugin WEB e WordPress. Qui condividiamo suggerimenti e le migliori soluzioni per siti web.

Creazione di un controllo di selezione link CMB2 personalizzato per WordPress

73

In questo tutorial vedremo come creare un controllo personalizzato per estendere la funzionalità di CMB2 (Custom Meta Boxes 2) di WebDevStudios.

Sviluppo siti web (e applicazioni web) con WordPress CMS (Content Management System), e quando arriva un nuovo progetto puoi garantire che ci sarà l’obbligo per me di sviluppare ‘Custom Meta Box’ per consentire all’utente di avere un controllo accurato sul contenuto e sul layout dei siti.

Descriverò in dettaglio come ho creato il Link Picker di controllo CMB2 per CMB2 (disponibile in tutti i buoni repository di plugin di WordPress). Uno screenshot di cui può essere visto di seguito.

Il controllo CMB2 "Link Picker" in azione

Il selettore di link attiva la finestra di dialogo "Inserisci/modifica link" incorporata in WordPress quando fai clic sul pulsante "Scegli". Questo può essere visto nello screenshot qui sotto:

Creazione di un controllo di selezione link CMB2 personalizzato per WordPressPremendo il pulsante puoi scegliere da un link (o aggiungerne uno tuo)

Sono sicuro che sarai d’accordo sul fatto che avere un controllo come questo è incredibilmente utile se vuoi dare agli editori del tuo sito la possibilità di aggiungere un collegamento e anche cercare in WordPress i suoi collegamenti interni, piuttosto che dover tagliare e incollare i collegamenti in un collegamento campo.

Introduzione / Storia

Per chi non lo sapesse, una meta box risiede nella schermata dell’editor di un post di WordPress e probabilmente conterrà vari controlli dei moduli (caselle di testo, elenchi a discesa, caselle di controllo ecc…). Questi controlli consentono agli utenti del tuo sito Web di modificare facilmente una parte di testo o una funzionalità personalizzata sul sito.

Creazione di un controllo di selezione link CMB2 personalizzato per WordPressCreazione di un controllo di selezione link CMB2 personalizzato per WordPressUn esempio di meta box con vari controlli del modulo

WordPress ti consente di creare meta box utilizzando funzioni (come [add_meta_box](https://developer.wordpress.org/reference/functions/add_meta_box/)), ma la creazione di meta box in questo modo può essere un processo lungo, con molte ripetizioni di codice (soprattutto se desideri utilizzare gli stessi controlli del modulo in più progetti).

Perché CMB2?

Alcuni di voi potrebbero aver sentito parlare di Advanced Custom Fields (ACF) che fornisce una GUI (Graphical User Interface) che consente di creare meta box direttamente con WordPress.

ACF secondo me non è un ottimo strumento per nessuna soluzione web scalabile. Il plug-in fa troppo affidamento sui dati archiviati all’interno del database. Ciò causa problemi durante la distribuzione delle modifiche a un sito, poiché non puoi semplicemente inviare il codice e visualizzare le modifiche all’istante. Invece devi rifare il lavoro sui vari ambienti di distribuzione (staging, live, et al). Quindi avevamo bisogno di una soluzione che ci permettesse di creare meta box in modo programmatico. Immettere CMB2.

Prima di adottare CMB2, in precedenza abbiamo utilizzato HM Custom Meta Box di quegli adorabili umani di Human Made (che è iniziato come un fork del precursore di WebDevStudio di CMB2,).

Abbiamo adorato le Meta Box personalizzate HM e, con i più semplici frammenti di codice, abbiamo potuto creare rapidamente Meta Box personalizzate per fare praticamente qualsiasi cosa!

Creazione di un controllo di selezione link CMB2 personalizzato per WordPressEsempio di markup delle Meta Box personalizzate HM (questo è il markup per la Meta Box di Instagram nel primo screenshot)

Allora perché passare a CMB2? Bene, HM Custom Meta Boxes sfortunatamente non stava ottenendo molto amore (ho parlato con il suo sviluppatore principale ed è un uomo molto molto impegnato), mentre CMB2 stava andando avanti con nuove funzionalità, nuovi controlli e aveva guadagnato trazione nella community di WordPress con molte persone che lo adottano e rilasciano plug-in per estenderlo (incluse molte delle nostre agenzie partner).

Infine, come avrai capito, lavorare con CMB2 è incredibilmente semplice come ci eravamo abituati, poiché entrambe le piattaforme condividono un antenato comune.

Esercitazione

Prima di iniziare, ognuno ha la propria serie di ideali su come creare un plugin per WordPress, e io ne ho provati alcuni, tuttavia il tutorial su " Root Composition in WordPress " di Tom J Nowell, ha completamente cambiato il mio modo di lavorare. Trovo il suo approccio pulito, semplice e rende la manutenzione futura di qualsiasi plug-in un gioco da ragazzi. Se prendi il sorgente del plug-in Link Picker per CMB2, puoi vedere i metodi che insegna nella pratica.

Costruire la forma

Per costruire il form che rende il Link Picker, la prima cosa che dobbiamo fare è agganciarci cmb2_render_[control_name]all’azione. Poiché ho chiamato questo controllo ‘link_picker’, possiamo completare l’hook in questo modo:

<?php
add_action( 'cmb2_render_link_picker', array( $this, 'cmb2_render_link_picker' ), 10, 5 );
`

Per quelli di voi che non capiscono davvero l’ add_actionhook, funziona come segue:

  1. Il primo argomento cmb2_render_link_pickerè il nome dell’hook a cui vogliamo agganciarci.
  2. Il secondo argomento array( $this, 'cmb2_render_link_picker' )è la funzione che vogliamo chiamare quando viene eseguito questo hook. Nota che lo sto avvolgendo in un array, con $thiscome primo parametro, perché sto chiamando la funzione all’interno di una classe. Se non stai lavorando con le classi puoi semplicemente usare il nome della funzione cmb2_render_link_picker.
  3. Il 10, è l’ordine in cui vogliamo che la funzione si attivi (più basso è il numero, prima si attiva quando viene chiamata l’azione).
  4. È 5la quantità di parametri che verranno passati alla funzione che sto chiamando (questo diventerà chiaro a breve).

Successivamente creiamo la funzione che renderà il modulo:

<?php

public function cmb2_render_link_picker( $field, $value, $object_id, $object_type, $field_type_object) {
…
}
`

Ho lasciato il "DocBlock" nel codice sopra che descrive cosa cmb2_render_link_picker()fa ciascuno dei parametri passati nella funzione.

Nota che la mia funzione inizia con la publicdichiarazione. Anche questo è perché sto lavorando all’interno di una classe. Se non lavori con le classi puoi ometterlo.

Il valore di questo campo viene passato alla funzione tramite il $valueparametro. Nel caso di questo campo, passeremo attraverso un array, poiché il nostro controllo ha tre elementi separati:

  • Il testo
  • L’URL
  • Se il link si apre in una nuova finestra (o meno)

Poiché $valuenon è sempre impostato (ad esempio la prima volta che viene eseguito il rendering del controllo), è necessario inizializzarlo con alcuni valori predefiniti. Lo facciamo con il seguente bit di codice:

<?php
$value = wp_parse_args( 
    $value, 
    array(
        'text'  => '',
        'url'   => '',
        'blank' => 'false',) );

Possiamo quindi metterci al lavoro per eseguire il rendering del modulo. Ecco un esempio del primo controllo di input di testo:

<p>
    <label for="<?php echo $field_type_object->_id( '_text' ); ?>'">
        <?php echo esc_html( $field_type_object->_text( 'link_picker_text', 'Text') ); ?>
    </label>
</p>
<?php 
    echo $field_type_object->input( 
            array(
            'class' => 'cmb_text',
            'name'  => $field_type_object->_name( '[text]' ),
            'id'    => $field_type_object->_id( '_text' ),
            'value' => $value['text'],) ); 
?>

Uff! Sembra un po’ disordinato, vero? Analizziamolo, riga per riga:

  1. Il tag del paragrafo di apertura.
  2. Il tag dell’etichetta di apertura per il controllo, ma con l’ forattributo impostato automaticamente dal $field_type_object _idparametro. Questo genererà automaticamente un ID per il controllo quando viene eseguito il rendering.
  3. Il testo della nostra etichetta, costruito utilizzando il testo dell’array delle opzioni dei controlli (o ritorna alla parola ‘Testo’).
  4. Il tag dell’etichetta di chiusura
  5. Il tag del paragrafo di chiusura.
  6. Avvia la dichiarazione PHP
  7. Utilizzare un controllo di input (parte di $field_type_objectper creare un input del modulo (il tipo predefinito sarà testo).
  8. Avvia l’array di parametri
  9. Imposta la classe dell’input.
  10. Impostare il nome dell’input, sempre utilizzando l’ $field_type_objecthelper.
  11. Impostare l’ID dell’input, sullo stesso ID impostato sul tag dell’etichetta.
  12. Ottieni il valore da $value, poiché si tratta di un array, vogliamo la chiave ‘text’ per questo controllo.
  13. Chiudere l’array.
  14. Chiudere la funzione di immissione.
  15. Chiudi la dichiarazione PHP.

Il markup del campo del modulo URL è più o meno lo stesso, solo per utilizzare i tipi di input HTML5 possiamo impostare un parametro aggiuntivo di ‘type’ su ‘url’:

<?php 
…
'type'  => 'url',
…

Infine, vogliamo implementare un menu a discesa. Il markup è molto familiare:

<?php
echo $field_type_object->select( 
    array(
        'class'   => 'cmb_dropdown',
        'name'    => $field_type_object->_name( '[blank]' ),
        'id'      => $field_type_object->_id( '_blank' ),
        'options' => $blank_options,) );

Nota che la $field_type_objectfunzione che stiamo usando è selectquella di generare un menu a discesa. Si noti inoltre che alla riga 6 abbiamo un nuovo attributo di options. In questo stiamo passando una serie di "opzioni". Questo viene generato prima di questo controllo in questo modo:

<?php 
$blank_options = '';
$blank_options .= '<option value="false" '. selected( $value['blank'], 'false', false) .'>Opens in same</option>';
$blank_options .= '<option value="true" '. selected( $value['blank'], 'true', false) .'>Opens in new</option>';

Quindi tutto ciò che dobbiamo fare è avvolgerlo in alcuni <div>e abbiamo il nostro controllo completamente renderizzato:

<?php
public function cmb2_render_link_picker( $field, $value, $object_id, $object_type, $field_type_object) {
    $value = wp_parse_args( $value, array(
        'text'  => '',
        'url'   => '',
        'blank' => 'false',) );
    $blank_options = '';
    $blank_options .= '<option value="false" '. selected( $value['blank'], 'false', false) .'>Opens in same</option>';
    $blank_options .= '<option value="true" '. selected( $value['blank'], 'true', false) .'>Opens in new</option>';
    ?>
    <div class="link-picker">
        <div class="text">
            <p>
                <label for="<?php echo $field_type_object->_id( '_text' ); ?>'">
                    <?php echo esc_html( $field_type_object->_text( 'link_picker_text', 'Text') ); ?>
                </label>
            </p>
            <?php 
                echo $field_type_object->input( 
                    array(
                        'class' => 'cmb_text',
                        'name'  => $field_type_object->_name( '[text]' ),
                        'id'    => $field_type_object->_id( '_text' ),
                        'value' => $value['text'],
                        'desc'  => '',) ); 
            ?>
        </div>
        <div class="url">
            <p>
                <label for="<?php echo $field_type_object->_id( '_url' ); ?>'">
                    <?php echo esc_html( $field_type_object->_text( 'link_picker_url', 'URL') ); ?>
                </label>
            </p>
            <?php 
                echo $field_type_object->input( 
                    array(
                        'class' => 'cmb_text_url',
                        'name'  => $field_type_object->_name( '[url]' ),
                        'id'    => $field_type_object->_id( '_url' ),
                        'value' => $value['url'],
                        'type'  => 'url',
                        'desc'  => '',) ); 
            ?>
        </div>
        <div class="blank">
            <p>
                <label for="<?php echo $field_type_object->_id( '_blank' ); ?>'">
                    <?php echo esc_html( $field_type_object->_text( 'link_picker_blank', 'Window') ); ?>
                </label>
            </p>
            <?php 
                echo $field_type_object->select( 
                    array(
                        'class'   => 'cmb_checkbox',
                        'name'    => $field_type_object->_name( '[blank]' ),
                        'id'      => $field_type_object->_id( '_blank' ),
                        'options' => $blank_options,
                        'desc'    => '',) ); 
            ?>
        </div>
        <div class="choose">
            <p>
                <label>Choose</label>
            </p>
            <button class="dashicons dashicons-admin-links js-insert-link button button-primary" title="<?php esc_html_e( 'Insert Link', 'cmb' ); ?>">
                 <span class="screen-reader-text"><?php esc_html_e( 'Choose Link', 'cmb' ); ?></span>
             </button>
        </div>
    </div>
    <p class="clear">
        <?php echo $field_type_object->_desc();?>
    </p>
<?php
}

E questo è tutto! Abbiamo fatto il nostro controllo! CMB2 gestisce automaticamente tutti i dati che vogliamo salvare, quindi niente da fare lì.

Stili

Lo screenshot del controllo che stiamo creando (nella parte superiore di questo post) ha alcuni stili personalizzati applicati in modo che venga visualizzato in linea. Oggi non parlerò di come modellare il modulo, ma se sei curioso puoi scaricare il plugin e visualizzare il sorgente.

Rendere il controllo ripetibile

Per quelli di voi che vogliono diventare un po’ più avanzati, è possibile far funzionare il controllo con le regioni ripetibili di CMB2. Per fare ciò è necessario eseguire un po’ di mappatura dell’array. Per farlo usa il codice qui sotto:

<?php

public function cmb2_sanitize_link_picker( $check, $meta_value, $object_id, $field_args, $sanitize_object) {

    if (! is_array( $meta_value) ||! $field_args['repeatable']) {
        return $check;
    }
    foreach ($meta_value as $key => $val) {
        $meta_value[ $key ] =  null;
        if(! empty( $val['url'])) {
            $meta_value[ $key ] = array_map( 'sanitize_text_field', $val );
        }
    }
    return $meta_value;
}
public function cmb2_types_esc_link_picker( $check, $meta_value, $field_args, $field_object) {

    if (! is_array( $meta_value) ||! $field_args['repeatable']) {
        return $check;
    }
    foreach ($meta_value as $key => $val) {
        $meta_value[ $key ] =  null;
        if(! empty( $val['url'])) {
            $meta_value[ $key ] = array_map( 'esc_attr', $val );
        }
    }
    return $meta_value;
}

Scelta di un collegamento

Ovviamente lo scopo principale del selettore di link è integrarsi nella funzionalità di scelta dei link di WordPress, facendo apparire la schermata di dialogo "Inserisci/modifica link" quando si fa clic sul pulsante "Scegli".

Per fare in modo che ciò accada, ci affidiamo fortemente a JavaScript. In particolare sto usando jQuery per far accadere le cose.

Prima di mostrarti il ​​JavaScript che avvia la finestra di dialogo, dobbiamo prima accodare il JavaScript interno di WordPress, che precaricherà le modali e le librerie da cui dipende il nostro codice. Sembra qualcosa del genere:

<?php
global $post_id;

if (isset( $post_id)) {
    wp_enqueue_media( array( 'post' => $post_id) );
}

$plugin_js_url  = plugins_url( 'js/plugin.js', ROOT );
wp_enqueue_script( 'wholesomecode', $plugin_js_url, array( 'jquery', 'jquery-ui-core', 'jquery-ui-draggable', 'jquery-ui-droppable', 'thickbox', 'wpdialogs' ), '1.0.0', true );

Come puoi vedere, molte delle librerie interne di WordPress si basano su jQuery per caricare il popup, quindi ha senso che il nostro trigger popup faccia lo stesso. Questo viene fatto tramite il /js/plugin.jsche viene caricato sulla riga 10 dell’esempio sopra.

jQuery(document).ready(function($) {

    var url   = $('body');
    var text = $('body');
    var blank = $('body');

    $('body').on('click', '.js-insert-link', function(event) {

        event.preventDefault? event.preventDefault(): event.returnValue = false;
        event.stopPropagation();

        url            = $(this).closest('.link-picker').find('input.cmb_text_url ');
        text           = $(this).closest('.link-picker').find('input.cmb_text ');
        blank          = $(this).closest('.link-picker').find('input.cmb_checkbox ');

        wpActiveEditor = true;
        wpLink.open();
        wpLink.textarea = url;

        return false;
    });

    $('body').on('click', '#wp-link-cancel, #wp-link-backdrop, #wp-link-close', function(event) {

        wpLink.textarea = url;
        wpLink.close();
        event.preventDefault? event.preventDefault(): event.returnValue = false;
        event.stopPropagation();
        return false;
    });

    $('body').on('click', '#wp-link-submit', function(event) {
        console.log(text)
        var linkAtts = wpLink.getAttrs();

        linkAtts.text = $('#wp-link-text').val();

        url.val(linkAtts.href);

        if( linkAtts.text != '') {
            text.val(linkAtts.text);
        }

        if (linkAtts.target == '_blank') {
            blank.prop('checked', true);
        } else {
            blank.prop('checked', false);
        }

        wpLink.textarea = url;
        wpLink.close();
        event.preventDefault? event.preventDefault(): event.returnValue = false;
        event.stopPropagation();
        return false;
    });
});

Usando le classi che abbiamo racchiuso attorno ai nostri controlli del modulo, JavaScript punta ai controlli e inserisce il risultato selezionato dal pop-up del selettore di link nei campi di controllo pertinenti.

Usando il controllo

Quindi, dopo aver esaminato il tutorial sopra, e possibilmente dopo aver esaminato il codice sorgente del plug- in Link Picker per CMB2, o semplicemente aver scaricato la mia versione, ora potresti chiederti come utilizzare la cosa con CMB2. Beh, non potrebbe essere più facile:

<?php
function wholesomecode_create_meta_boxes() {
  $prefix = '_profile_';

    $cmb = new_cmb2_box(
        array(
            'id'            => 'cta',
            'title'         => __( 'Call to Action', 'cmb2' ),
            'object_types'  => array( 'profile' ),
            'context'       => 'normal',
            'priority'      => 'low',
            'show_names'    => true,) );

    $field1 = $cmb->add_field( 
        array(
            'name' => __( 'Link Picker', 'cmb2' ),
            'id'   => $prefix. 'cta_link',
            'type' => 'link_picker',) );
}
add_action( 'cmb2_admin_init', 'wholesomecode_create_meta_boxes' );

Fonte di registrazione: wholesomecode.ltd

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More