Creare un modulo di contatto senza plugin
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?

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.

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

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

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

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.

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, 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.

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()
).
