Creare un modulo di contatto senza plugin

1 apr 2018, 15:08:29
Visualizzazioni: 17.2K
Voti: 3

Sono nuovo nello sviluppo WordPress e sono stanco di lottare con Contact Form 7 per personalizzarne lo stile. È possibile e non considerata una "cattiva pratica" inserire un modulo HTML nella mia pagina di contatto e farlo inviare a una pagina PHP che gestisce l'invio del modulo? O semplicemente non si fa?

2
Commenti

hai provato l'estensione Smart Grid-layout che ti permette di creare layout di form avanzati utilizzando un'interfaccia a griglia, potrebbe riconciliarti con CF7

Aurovrata Aurovrata
1 apr 2018 19:07:52

Una cosa che aggiungerei a qualsiasi form che codifichi manualmente è sia un campo nascosto da verificare per assicurarsi che l'invio sia effettivamente avvenuto dal form, sia un campo nascosto CSS (così come ARIA) che controlli per assicurarti che sia vuoto come "test di tortura inverso"

Cedon Cedon
2 apr 2018 01:45:41
Tutte le risposte alla domanda 3
6

Questa è la mia implementazione molto semplice di un modulo di contatto:

class WPSE_299521_Form {

    /**
     * Costruttore della classe
     */
    public function __construct() {

        $this->define_hooks();
    }

    public function controller() {

        if( isset( $_POST['submit'] ) ) { // Pulsante di invio

            $full_name   = filter_input( INPUT_POST, 'full_name', FILTER_SANITIZE_STRING );
            $email       = filter_input( INPUT_POST, 'email', FILTER_SANITIZE_STRING | FILTER_SANITIZE_EMAIL );
            $color       = filter_input( INPUT_POST, 'color', FILTER_SANITIZE_STRING );
            $accessories = filter_input( INPUT_POST, 'accessories', FILTER_SANITIZE_STRING, FILTER_REQUIRE_ARRAY );
            $comments    = filter_input( INPUT_POST, 'comments', FILTER_SANITIZE_STRING );

            // Invia un'email e reindirizza l'utente alla pagina "Grazie"
        }
    }

    /**
     * Mostra il modulo
     */
    public function display_form() {

        $full_name   = filter_input( INPUT_POST, 'full_name', FILTER_SANITIZE_STRING );
        $email       = filter_input( INPUT_POST, 'email', FILTER_SANITIZE_STRING | FILTER_SANITIZE_EMAIL );
        $color       = filter_input( INPUT_POST, 'color', FILTER_SANITIZE_STRING );
        $accessories = filter_input( INPUT_POST, 'accessories', FILTER_SANITIZE_STRING, FILTER_REQUIRE_ARRAY );
        $comments    = filter_input( INPUT_POST, 'comments', FILTER_SANITIZE_STRING );

        // Array vuoto di default
        $accessories = ( $accessories === null ) ? array() : $accessories;

        $output = '';

        $output .= '<form method="post">';
        $output .= '    <p>';
        $output .= '        ' . $this->display_text( 'full_name', 'Nome', $full_name );
        $output .= '    </p>';
        $output .= '    <p>';
        $output .= '        ' . $this->display_text( 'email', 'Email', $email );
        $output .= '    </p>';
        $output .= '    <p>';
        $output .= '        ' . $this->display_radios( 'color', 'Colore', $this->get_available_colors(), $color );
        $output .= '    </p>';
        $output .= '    <p>';
        $output .= '        ' . $this->display_checkboxes( 'accessories', 'Accessori', $this->get_available_accessories(), $accessories );
        $output .= '    </p>';
        $output .= '    <p>';
        $output .= '        ' . $this->display_textarea( 'comments', 'Commenti', $comments );
        $output .= '    </p>';
        $output .= '    <p>';
        $output .= '        <input type="submit" name="submit" value="Invia" />';
        $output .= '    </p>';
        $output .= '</form>';

        return $output;
    }

    /**
     * Mostra campo di testo
     */
    private function display_text( $name, $label, $value = '' ) {

        $output = '';

        $output .= '<label>' . esc_html__( $label, 'wpse_299521' ) . '</label>';
        $output .= '<input type="text" name="' . esc_attr( $name ) . '" value="' . esc_attr( $value ) . '">';

        return $output;
    }

    /**
     * Mostra area di testo
     */
    private function display_textarea( $name, $label, $value = '' ) {

        $output = '';

        $output .= '<label> ' . esc_html__( $label, 'wpse_299521' ) . '</label>';
        $output .= '<textarea name="' . esc_attr( $name ) . '" >' . esc_html( $value ) . '</textarea>';

        return $output;
    }

    /**
     * Mostra radio button
     */
    private function display_radios( $name, $label, $options, $value = null ) {

        $output = '';

        $output .= '<label>' . esc_html__( $label, 'wpse_299521' ) . '</label>';

        foreach ( $options as $option_value => $option_label ):
            $output .= $this->display_radio( $name, $option_label, $option_value, $value );
        endforeach;

        return $output;
    }

    /**
     * Mostra singolo radio button
     */
    private function display_radio( $name, $label, $option_value, $value = null ) {

        $output = '';

        $checked = ( $option_value === $value ) ? ' checked' : '';

        $output .= '<label>';
        $output .= '    <input type="radio" name="' . esc_attr( $name ) . '" value="' . esc_attr( $option_value ) . '"' . esc_attr( $checked ) . '>';
        $output .= '    ' . esc_html__( $label, 'wpse_299521' );
        $output .= '</label>';

        return $output;
    }

    /**
     * Mostra checkbox
     */
    private function display_checkboxes( $name, $label, $options, $values = array() ) {

        $output = '';

        $name .= '[]';

        $output .= '<label>' . esc_html__( $label, 'wpse_299521' ) . '</label>';

        foreach ( $options as $option_value => $option_label ):
            $output .= $this->display_checkbox( $name, $option_label, $option_value, $values );
        endforeach;

        return $output;
    }

    /**
     * Mostra singola checkbox
     */
    private function display_checkbox( $name, $label, $available_value, $values = array() ) {

        $output = '';

        $checked = ( in_array($available_value, $values) ) ? ' checked' : '';

        $output .= '<label>';
        $output .= '    <input type="checkbox" name="' . esc_attr( $name ) . '" value="' . esc_attr( $available_value ) . '"' . esc_attr( $checked ) . '>';
        $output .= '    ' . esc_html__( $label, 'wpse_299521' );
        $output .= '</label>';

        return $output;
    }

    /**
     * Ottieni i colori disponibili
     */
    private function get_available_colors() {

        return array(
            'red' => 'Rosso',
            'blue' => 'Blu',
            'green' => 'Verde',
        );
    }

    /**
     * Ottieni gli accessori disponibili
     */
    private function get_available_accessories() {

        return array(
            'case' => 'Custodia',
            'tempered_glass' => 'Vetro temperato',
            'headphones' => 'Cuffie',
        );
    }

    /**
     * Definisci gli hook relativi al plugin
     */
    private function define_hooks() {

        /**
         * Aggiungi azione per inviare email
         */
        add_action( 'wp', array( $this, 'controller' ) );

        /**
         * Aggiungi shortcode per mostrare il modulo
         */
        add_shortcode( 'contact', array( $this, 'display_form' ) );
    }
}

new WPSE_299521_Form();

Dopo aver incollato il codice puoi usare lo shortcode [contact] per visualizzarlo.

1 apr 2018 21:15:03
Commenti

Dove metteresti questo codice?

user8463989 user8463989
2 apr 2018 09:38:14

Probabilmente creerei un semplice plugin.

kierzniak kierzniak
2 apr 2018 09:48:46

@user8463989 - potresti inserirlo nel file functions.php del tuo child theme... stai lavorando con un child theme, vero?

HPWD HPWD
11 feb 2019 22:36:21

Stranamente, dopo aver trovato questa risposta, mi è capitata l'occasione di utilizzare questo codice come punto di partenza. Molto bello.

HPWD HPWD
15 feb 2019 16:21:00

Implementazione interessante. Dove posso controllare l'azione del form, cioè dove viene inviato il form?

MontyHall MontyHall
4 set 2019 10:02:04

C'è un metodo controller agganciato all'azione wp. Questo metodo verrà eseguito ad ogni richiesta ma, come puoi vedere nella condizione, il resto del metodo procederà solo se ci sono dati submit nella richiesta POST, che corrispondono al nostro pulsante di invio.

kierzniak kierzniak
4 set 2019 10:20:34
Mostra i restanti 1 commenti
3

Tutti i plugin per i form sono orribili, è semplicemente che i form sono tipicamente molto complessi da codificare correttamente, specialmente quando l'amministratore del sito dovrebbe essere in grado di progettarli.

Non c'è nulla di sbagliato nel codificare un form da soli, è solo che probabilmente avrete bisogno di ricreare cose che altre persone hanno già perfezionato, o almeno hanno una buona base (formattazione delle email, archiviazione nel database e probabilmente altro).

Quindi dipende davvero dalle vostre esigenze specifiche, se la flessibilità non è richiesta e l'invio di email è sufficiente, dovrebbe essere più semplice scrivere il proprio form che "combattere" con i plugin.

1 apr 2018 16:22:54
Commenti

Il mio problema più grande è in realtà cercare di stilizzare checkbox e pulsanti radio utilizzando Contact Form 7 o qualsiasi altro plugin per moduli di contatto. Mi sta lentamente uccidendo, motivo per cui ho pensato di utilizzare semplicemente un modulo html e poi usare php per inviare il modulo.

user8463989 user8463989
1 apr 2018 16:34:56

@user8463989, forse dovresti usare un plugin diverso. CF7 secondo me è troppo basilare, ma non l'ho mai usato quindi forse non sono abbastanza familiare con esso per criticarlo. Tutti hanno i loro difetti, nessuno è veramente perfetto.

Mark Kaplun Mark Kaplun
1 apr 2018 16:46:20

Ne ho provati alcuni che funzionano tutti ma ho lo stesso problema. Il CSS si rompe. Forse perché sto cercando di convertire un modulo html in WordPress, non lo so.

user8463989 user8463989
1 apr 2018 21:09:57
0

Dato che non stai eseguendo operazioni CRUD sul database, non vedo perché no. L'ho già fatto in passato utilizzando un template di pagina per l'elaborazione del form e puntando l'action del mio modulo di contatto a esso action="<?php echo home_url( 'slug-del-mio-template-di-elaborazione' ); ?>".

In alternativa, puoi utilizzare direttamente il singolo post type per elaborarlo, ad esempio action="<?php echo get_the_permalink();?>" (deve essere una pagina is_single() || is_singular() per poter usare get_the_permalink()).

1 apr 2018 16:21:04