Come visualizzare il modulo di registrazione utente nel front-end del sito web?
Come posso visualizzare il modulo di registrazione utenti WordPress (il form che appare nella pagina "www.mywebsite.com/wp-register.php") nel front-end del mio blog?
Ho personalizzato il modulo di registrazione, ma non so come richiamare quel form nella pagina front-end. Qualsiasi supporto sarà di grande aiuto.
Grazie in anticipo. :)

Il processo coinvolge 2 passaggi:
- mostrare il form frontend
- salvare i dati all'invio
Ci sono 3 approcci diversi che mi vengono in mente per mostrare il frontend:
- usare il form di registrazione integrato, modificando gli stili, ecc. per renderlo più "frontend like"
- usare una pagina/post di WordPress, e visualizzare il form usando uno shortcode
- usare un template dedicato non connesso a nessuna pagina/post, ma chiamato da un URL specifico
Per questa risposta userò l'ultimo. Le ragioni sono:
- usare il form di registrazione integrato può essere una buona idea, ma personalizzazioni profonde possono essere molto difficili usando il form integrato, e se si vogliono anche personalizzare i campi del form la difficoltà aumenta
- usare una pagina di WordPress in combinazione con uno shortcode non è così affidabile, e inoltre penso che gli shortcode non dovrebbero essere usati per le funzionalità, solo per la formattazione e simili
1: Costruire l'URL
Tutti sappiamo che il form di registrazione predefinito di un sito WordPress è spesso un bersaglio per gli spammer. Usare un URL personalizzato aiuta a risolvere questo problema. Inoltre voglio anche usare un URL variabile, cioè l'URL del form di registrazione non dovrebbe essere sempre lo stesso, questo rende la vita più difficile agli spammer. Il trucco si fa usando un nonce nell'URL:
/**
* Genera un URL di registrazione dinamico
*/
function custom_registration_url() {
$nonce = urlencode( wp_create_nonce( 'registration_url' ) );
return home_url( $nonce );
}
/**
* Genera un link di registrazione dinamico
*/
function custom_registration_link() {
$format = '<a href="%s">%s</a>';
printf(
$format,
custom_registration_url(), __( 'Registrati', 'custom_reg_form' )
);
}
Usando queste funzioni è facile mostrare nei template un link al form di registrazione anche se è dinamico.
2: Riconoscere l'URL, prima bozza della classe Custom_Reg\Custom_Reg
Ora dobbiamo riconoscere l'URL. Per questo scopo inizierò a scrivere una classe, che sarà completata più avanti nella risposta:
<?php
// non salvare, solo una bozza
namespace Custom_Reg;
class Custom_Reg {
function checkUrl() {
$url_part = $this->getUrl();
$nonce = urlencode( wp_create_nonce( 'registration_url' ) );
if ( ( $url_part === $nonce ) ) {
// non fare nulla se la registrazione non è permessa o l'utente è loggato
if ( is_user_logged_in() || ! get_option('users_can_register') ) {
wp_safe_redirect( home_url() );
exit();
}
return TRUE;
}
}
protected function getUrl() {
$home_path = trim( parse_url( home_url(), PHP_URL_PATH ), '/' );
$relative = trim(str_replace($home_path, '', esc_url(add_query_arg(array()))), '/');
$parts = explode( '/', $relative );
if ( ! empty( $parts ) && ! isset( $parts[1] ) ) {
return $parts[0];
}
}
}
La funzione guarda alla prima parte dell'URL dopo home_url()
, e se corrisponde al nostro nonce restituisce TRUE. Questa funzione sarà usata per verificare la nostra richiesta e eseguire le azioni necessarie per mostrare il nostro form.
3: La classe Custom_Reg\Form
Ora scriverò una classe, che sarà responsabile di generare il markup del form. La userò anche per memorizzare in una proprietà il percorso del file template che dovrebbe essere usato per mostrare il form.
<?php
// file: Form.php
namespace Custom_Reg;
class Form {
protected $fields;
protected $verb = 'POST';
protected $template;
protected $form;
public function __construct() {
$this->fields = new \ArrayIterator();
}
public function create() {
do_action( 'custom_reg_form_create', $this );
$form = $this->open();
$it = $this->getFields();
$it->rewind();
while( $it->valid() ) {
$field = $it->current();
if ( ! $field instanceof FieldInterface ) {
throw new \DomainException( "Campo non valido" );
}
$form .= $field->create() . PHP_EOL;
$it->next();
}
do_action( 'custom_reg_form_after_fields', $this );
$form .= $this->close();
$this->form = $form;
add_action( 'custom_registration_form', array( $this, 'output' ), 0 );
}
public function output() {
unset( $GLOBALS['wp_filters']['custom_registration_form'] );
if ( ! empty( $this->form ) ) {
echo $this->form;
}
}
public function getTemplate() {
return $this->template;
}
public function setTemplate( $template ) {
if ( ! is_string( $template ) ) {
throw new \InvalidArgumentException( "Template non valido" );
}
$this->template = $template;
}
public function addField( FieldInterface $field ) {
$hook = 'custom_reg_form_create';
if ( did_action( $hook ) && current_filter() !== $hook ) {
throw new \BadMethodCallException( "Aggiungi campi prima che {$hook} sia eseguito" );
}
$this->getFields()->append( $field );
}
public function getFields() {
return $this->fields;
}
public function getVerb() {
return $this->verb;
}
public function setVerb( $verb ) {
if ( ! is_string( $verb) ) {
throw new \InvalidArgumentException( "Verbo non valido" );
}
$verb = strtoupper($verb);
if ( in_array($verb, array( 'GET', 'POST' ) ) ) $this->verb = $verb;
}
protected function open() {
$out = sprintf( '<form id="custom_reg_form" method="%s">', $this->verb ) . PHP_EOL;
$nonce = '<input type="hidden" name="_n" value="%s" />';
$out .= sprintf( $nonce, wp_create_nonce( 'custom_reg_form_nonce' ) ) . PHP_EOL;
$identity = '<input type="hidden" name="custom_reg_form" value="%s" />';
$out .= sprintf( $identity, __CLASS__ ) . PHP_EOL;
return $out;
}
protected function close() {
$submit = __('Registrati', 'custom_reg_form');
$out = sprintf( '<input type="submit" value="%s" />', $submit );
$out .= '</form>';
return $out;
}
}
La classe genera il markup del form ciclando tutti i campi aggiunti chiamando il metodo create
su ognuno di essi.
Ogni campo deve essere un'istanza di Custom_Reg\FieldInterface
.
Un campo hidden aggiuntivo è aggiunto per la verifica del nonce. Il metodo del form è 'POST' di default, ma può essere impostato su 'GET' usando il metodo setVerb
.
Una volta creato il markup è salvato all'interno della proprietà $form
dell'oggetto che viene mostrato dal metodo output()
, agganciato all'hook 'custom_registration_form'
: nel template del form, semplicemente chiamando do_action( 'custom_registration_form' )
verrà mostrato il form.
4: Il template predefinito
Come ho detto il template per il form può essere facilmente sovrascritto, tuttavia abbiamo bisogno di un template base come fallback. Scriverò qui un template molto grezzo, più una prova di concetto che un vero template.
<?php
// file: default_form_template.php
get_header();
global $custom_reg_form_done, $custom_reg_form_error;
if ( isset( $custom_reg_form_done ) && $custom_reg_form_done ) {
echo '<p class="success">';
_e(
'Grazie, la tua registrazione è stata inviata, controlla la tua email.',
'custom_reg_form'
);
echo '</p>';
} else {
if ( $custom_reg_form_error ) {
echo '<p class="error">' . $custom_reg_form_error . '</p>';
}
do_action( 'custom_registration_form' );
}
get_footer();
5: L'interfaccia Custom_Reg\FieldInterface
Ogni campo dovrebbe essere un oggetto che implementa la seguente interfaccia
<?php
// file: FieldInterface.php
namespace Custom_Reg;
interface FieldInterface {
/**
* Restituisce l'id del campo, usato per nominare il valore della richiesta e per il parametro 'name' del
* campo input html
*/
public function getId();
/**
* Restituisce la costante del filtro che deve essere usata con
* filter_input per ottenere il valore dalla richiesta
*/
public function getFilter();
/**
* Restituisce true se il valore passato come argomento deve essere accettato, false se no
*/
public function isValid( $value = NULL );
/**
* Restituisce true se il campo è obbligatorio, false se no
*/
public function isRequired();
/**
* Restituisce il markup del campo input. Il parametro 'name' deve essere mostrato
* secondo getId()
*/
public function create( $value = '');
}
Penso che i commenti spieghino cosa dovrebbero fare le classi che implementano questa interfaccia.
6: Aggiungere alcuni campi
Ora abbiamo bisogno di alcuni campi. Possiamo creare un file chiamato 'fields.php' dove definiamo le classi dei campi:
<?php
// file: fields.php
namespace Custom_Reg;
abstract class BaseField implements FieldInterface {
protected function getType() {
return isset( $this->type ) ? $this->type : 'text';
}
protected function getClass() {
$type = $this->getType();
if ( ! empty($type) ) return "{$type}-field";
}
public function getFilter() {
return FILTER_SANITIZE_STRING;
}
public function isRequired() {
return isset( $this->required ) ? $this->required : FALSE;
}
public function isValid( $value = NULL ) {
if ( $this->isRequired() ) {
return $value != '';
}
return TRUE;
}
public function create( $value = '' ) {
$label = '<p><label>' . $this->getLabel() . '</label>';
$format = '<input type="%s" name="%s" value="%s" class="%s"%s /></p>';
$required = $this->isRequired() ? ' required' : '';
return $label . sprintf(
$format,
$this->getType(), $this->getId(), $value, $this->getClass(), $required
);
}
abstract function getLabel();
}
class FullName extends BaseField {
protected $required = TRUE;
public function getID() {
return 'fullname';
}
public function getLabel() {
return __( 'Nome Completo', 'custom_reg_form' );
}
}
class Login extends BaseField {
protected $required = TRUE;
public function getID() {
return 'login';
}
public function getLabel() {
return __( 'Username', 'custom_reg_form' );
}
}
class Email extends BaseField {
protected $type = 'email';
public function getID() {
return 'email';
}
public function getLabel() {
return __( 'Email', 'custom_reg_form' );
}
public function isValid( $value = NULL ) {
return ! empty( $value ) && filter_var( $value, FILTER_VALIDATE_EMAIL );
}
}
class Country extends BaseField {
protected $required = FALSE;
public function getID() {
return 'country';
}
public function getLabel() {
return __( 'Paese', 'custom_reg_form' );
}
}
Ho usato una classe base per definire l'implementazione predefinita dell'interfaccia, tuttavia, si possono aggiungere campi molto personalizzati implementando direttamente l'interfaccia o estendendo la classe base e sovrascrivendo alcuni metodi.
A questo punto abbiamo tutto per mostrare il form, ora abbiamo bisogno di qualcosa per validare e salvare i campi.
7: La classe Custom_Reg\Saver
<?php
// file: Saver.php
namespace Custom_Reg;
class Saver {
protected $fields;
protected $user = array( 'user_login' => NULL, 'user_email' => NULL );
protected $meta = array();
protected $error;
public function setFields( \ArrayIterator $fields ) {
$this->fields = $fields;
}
/**
* valida tutti i campi
*/
public function validate() {
// se la registrazione non è permessa restituisce false
if ( ! get_option('users_can_register') ) return FALSE;
// se nessun campo è impostato restituisce FALSE
if ( ! $this->getFields() instanceof \ArrayIterator ) return FALSE;
// prima controlla il nonce
$nonce = $this->getValue( '_n' );
if ( $nonce !== wp_create_nonce( 'custom_reg_form_nonce' ) ) return FALSE;
// poi controlla tutti i campi
$it = $this->getFields();
while( $it->valid() ) {
$field = $it->current();
$key = $field->getID();
if ( ! $field instanceof FieldInterface ) {
throw new \DomainException( "Campo non valido" );
}
$value = $this->getValue( $key, $field->getFilter() );
if ( $field->isRequired() && empty($value) ) {
$this->error = sprintf( __('%s è obbligatorio', 'custom_reg_form' ), $key );
return FALSE;
}
if ( ! $field->isValid( $value ) ) {
$this->error = sprintf( __('%s non è valido', 'custom_reg_form' ), $key );
return FALSE;
}
if ( in_array( "user_{$key}", array_keys($this->user) ) ) {
$this->user["user_{$key}"] = $value;
} else {
$this->meta[$key] = $value;
}
$it->next();
}
return TRUE;
}
/**
* Salva l'utente usando register_new_user che gestisce il controllo di username e email
* e anche l'invio dell'email al nuovo utente
* in aggiunta salva tutti gli altri dati personalizzati nei meta dell'utente
*
* @see register_new_user()
*/
public function save() {
// se la registrazione non è permessa restituisce false
if ( ! get_option('users_can_register') ) return FALSE;
// controlla i campi obbligatori
if ( ! isset($this->user['user_login']) || ! isset($this->user['user_email']) ) {
return false;
}
$user = register_new_user( $this->user['user_login'], $this->user['user_email'] );
if ( is_numeric($user) ) {
if ( ! update_user_meta( $user, 'custom_data', $this->meta ) ) {
wp_delete_user($user);
return FALSE;
}
return TRUE;
} elseif ( is_wp_error( $user ) ) {
$this->error = $user->get_error_message();
}
return FALSE;
}
public function getValue( $var, $filter = FILTER_SANITIZE_STRING ) {
if ( ! is_string($var) ) {
throw new \InvalidArgumentException( "Valore non valido" );
}
$method = strtoupper( filter_input( INPUT_SERVER, 'REQUEST_METHOD' ) );
$type = $method === 'GET' ? INPUT_GET : INPUT_POST;
$val = filter_input( $type, $var, $filter );
return $val;
}
public function getFields() {
return $this->fields;
}
public function getErrorMessage() {
return $this->error;
}
}
Questa classe ha 2 metodi principali, uno (validate
) che cicla i campi, li valida e salva i dati corretti in un array, il secondo (save
) salva tutti i dati nel database e invia la password via email al nuovo utente.
8: Usare le classi definite: completare la classe Custom_Reg
Ora possiamo lavorare di nuovo sulla classe Custom_Reg
, aggiungendo i metodi che "incollano" gli oggetti definiti e li fanno funzionare
<?php
// file Custom_Reg.php
namespace Custom_Reg;
class Custom_Reg {
protected $form;
protected $saver;
function __construct( Form $form, Saver $saver ) {
$this->form = $form;
$this->saver = $saver;
}
/**
* Controlla se l'URL da riconoscere è quello per la pagina del form di registrazione
*/
function checkUrl() {
$url_part = $this->getUrl();
$nonce = urlencode( wp_create_nonce( 'registration_url' ) );
if ( ( $url_part === $nonce ) ) {
// non fare nulla se la registrazione non è permessa o l'utente è loggato
if ( is_user_logged_in() || ! get_option('users_can_register') ) {
wp_safe_redirect( home_url() );
exit();
}
return TRUE;
}
}
/**
* Inizializza il form, se inviato valida e salva, altrimenti lo mostra
*/
function init() {
if ( $this->checkUrl() !== TRUE ) return;
do_action( 'custom_reg_form_init', $this->form );
if ( $this->isSubmitted() ) {
$this->save();
}
// non serve creare il form se è già stato salvato
if ( ! isset( $custom_reg_form_done ) || ! $custom_reg_form_done ) {
$this->form->create();
}
load_template( $this->getTemplate() );
exit();
}
protected function save() {
global $custom_reg_form_error;
$this->saver->setFields( $this->form->getFields() );
if ( $this->saver->validate() === TRUE ) { // validato?
if ( $this->saver->save() ) { // salvato?
global $custom_reg_form_done;
$custom_reg_form_done = TRUE;
} else { // errore nel salvataggio
$err = $this->saver->getErrorMessage();
$custom_reg_form_error = $err ? : __( 'Errore nel salvataggio.', 'custom_reg_form' );
}
} else { // errore nella validazione
$custom_reg_form_error = $this->saver->getErrorMessage();
}
}
protected function isSubmitted() {
$type = $this->form->getVerb() === 'GET' ? INPUT_GET : INPUT_POST;
$sub = filter_input( $type, 'custom_reg_form', FILTER_SANITIZE_STRING );
return ( ! empty( $sub ) && $sub === get_class( $this->form ) );
}
protected function getTemplate() {
$base = $this->form->getTemplate() ? : FALSE;
$template = FALSE;
$default = dirname( __FILE__ ) . '/default_form_template.php';
if ( ! empty( $base ) ) {
$template = locate_template( $base );
}
return $template ? : $default;
}
protected function getUrl() {
$home_path = trim( parse_url( home_url(), PHP_URL_PATH ), '/' );
$relative = trim( str_replace( $home_path, '', add_query_arg( array() ) ), '/' );
$parts = explode( '/', $relative );
if ( ! empty( $parts ) && ! isset( $parts[1] ) ) {
return $parts[0];
}
}
}
Il costruttore della classe accetta un'istanza di Form
e una di Saver
.
Il metodo init()
(usando checkUrl()
) guarda alla prima parte dell'URL dopo home_url()
, e se corrisponde al nonce corretto, controlla se il form è già stato inviato, se sì usando l'oggetto Saver
, valida e salva i dati dell'utente, altrimenti mostra semplicemente il form.
Il metodo init()
esegue anche l'hook 'custom_reg_form_init'
passando l'istanza del form come argomento: questo hook dovrebbe essere usato per aggiungere campi, per impostare il template personalizzato e anche per personalizzare il metodo del form.
9: Mettere tutto insieme
Ora dobbiamo scrivere il file principale del plugin, dove possiamo
- richiedere tutti i file
- caricare il textdomain
- avviare l'intero processo istanziando la classe
Custom_Reg
e chiamando il metodoinit()
su di essa usando un hook abbastanza precoce - usare 'custom_reg_form_init' per aggiungere i campi alla classe del form
Quindi:
<?php
/**
* Plugin Name: Custom Registration Form
* Description: Solo un plugin di esempio per rispondere a una domanda su WPSE
* Plugin URI: https://wordpress.stackexchange.com/questions/10309/
* Author: G. M.
* Author URI: https://wordpress.stackexchange.com/users/35541/g-m
*
*/
if ( is_admin() ) return; // questo plugin riguarda tutto il frontend
load_plugin_textdomain(
'custom_reg_form',
FALSE,
plugin_dir_path( __FILE__ ) . 'langs'
);
require_once plugin_dir_path( __FILE__ ) . 'FieldInterface.php';
require_once plugin_dir_path( __FILE__ ) . 'fields.php';
require_once plugin_dir_path( __FILE__ ) . 'Form.php';
require_once plugin_dir_path( __FILE__ ) . 'Saver.php';
require_once plugin_dir_path( __FILE__ ) . 'CustomReg.php';
/**
* Genera un URL di registrazione dinamico
*/
function custom_registration_url() {
$nonce = urlencode( wp_create_nonce( 'registration_url' ) );
return home_url( $nonce );
}
/**
* Genera un link di registrazione dinamico
*/
function custom_registration_link() {
$format = '<a href="%s">%s</a>';
printf(
$format,
custom_registration_url(), __( 'Registrati', 'custom_reg_form' )
);
}
/**
* Configura, mostra e salva il form
*/
add_action( 'wp_loaded', function() {
try {
$form = new Custom_Reg\Form;
$saver = new Custom_Reg\Saver;
$custom_reg = new Custom_Reg\Custom_Reg( $form, $saver );
$custom_reg->init();
} catch ( Exception $e ) {
if ( defined('WP_DEBUG') && WP_DEBUG ) {
$msg = 'Eccezione in ' . __FUNCTION__;
$msg .= ', Tipo: ' . get_class( $e ) . ', Messaggio: ';
$msg .= $e->getMessage() ? : 'Errore sconosciuto';
error_log( $msg );
}
wp_safe_redirect( home_url() );
}
}, 0 );
/**
* Aggiunge campi al form
*/
add_action( 'custom_reg_form_init', function( $form ) {
$classes = array(
'Custom_Reg\FullName',
'Custom_Reg\Login',
'Custom_Reg\Email',
'Custom_Reg\Country'
);
foreach ( $classes as $class ) {
$form->addField( new $class );
}
}, 1 );
10: Compiti mancanti
Ora tutto è praticamente fatto. Dobbiamo solo personalizzare il template, probabilmente aggiungendo un file template personalizzato nel nostro tema.
Possiamo aggiungere stili e script specifici solo alla pagina di registrazione personalizzata in questo modo
add_action( 'wp_enqueue_scripts', function() {
// se non siamo nel form di registrazione personalizzato non fare nulla
if ( did_action('custom_reg_form_init') ) {
wp_enqueue_style( ... );
wp_enqueue_script( ... );
}
});
Usando questo metodo possiamo caricare alcuni script js per gestire la validazione lato client, ad esempio questo. Il markup necessario per far funzionare quello script può essere facilmente gestito modificando la classe Custom_Reg\BaseField
.
Se vogliamo personalizzare l'email di registrazione, possiamo usare metodi standard e avendo i dati personalizzati salvati nei meta, possiamo usarli nell'email.
L'ultimo compito che probabilmente vogliamo implementare è prevenire le richieste al form di registrazione predefinito, semplice come:
add_action( 'login_form_register', function() { exit(); } );
Tutti i file possono essere trovati in un Gist qui.

Wow, questa è una completa riprogettazione della funzionalità di registrazione! Probabilmente è una buona soluzione se vuoi sovrascrivere completamente il processo di registrazione integrato. Penso che non utilizzare il modulo di registrazione integrato non sia una buona idea perché perderai altre funzionalità core come il modulo per il recupero della password. Inoltre, un nuovo utente registrato dovrebbe mostrare il tradizionale modulo di login del backend per accedere.

@FabienQuatravaux il recupero password e il modulo di login possono essere utilizzati normalmente (backend). Sì, il codice è incompleto perché il recupero password e il modulo di login non sono gestiti, ma la domanda dell'OP riguardava solo il modulo di registrazione e la risposta era già troppo lunga per aggiungere altre funzionalità...

TLDR; Inserisci il seguente form nel tuo tema, gli attributi name
e id
sono importanti:
<form action="<?php echo site_url('wp-login.php?action=register', 'login_post') ?>" method="post">
<input type="text" name="user_login" value="Username" id="user_login" class="input" />
<input type="text" name="user_email" value="E-Mail" id="user_email" class="input" />
<?php do_action('register_form'); ?>
<input type="submit" value="Registrati" id="register" />
</form>
Ho trovato un eccellente articolo su Tutsplus riguardo Come creare un form di registrazione WordPress elegante da zero. L'articolo dedica molto tempo allo stile del form, ma contiene la seguente sezione abbastanza semplice sul codice WordPress necessario:
Passo 4. WordPress
Non c'è nulla di complicato qui; abbiamo solo bisogno di due frammenti di codice WordPress, nascosti all'interno del file wp-login.php.
Il primo frammento:
<?php echo site_url('wp-login.php?action=register', 'login_post') ?>
E:
<?php do_action('register_form'); ?>
Modifica: Ho aggiunto la parte finale dell'articolo per spiegare dove inserire i frammenti di codice sopra - è semplicemente un form che può essere inserito in qualsiasi template di pagina, sidebar o trasformato in uno shortcode. La sezione importante è il form
che contiene i frammenti sopra e i campi obbligatori richiesti.
Il codice finale dovrebbe apparire così:
<div style="display:none"> <!-- Registrazione --> <div id="register-form"> <div class="title"> <h1>Registra il tuo Account</h1> <span>Registrati con noi e divertiti!</span> </div> <form action="<?php echo site_url('wp-login.php?action=register', 'login_post') ?>" method="post"> <input type="text" name="user_login" value="Username" id="user_login" class="input" /> <input type="text" name="user_email" value="E-Mail" id="user_email" class="input" /> <?php do_action('register_form'); ?> <input type="submit" value="Registrati" id="register" /> <hr /> <p class="statement">Una password ti verrà inviata via email.</p> </form> </div> </div><!-- /Registrazione -->
Nota che è molto importante, e necessario, avere
user_login
come attributoname
eid
nel tuo campo di testo; lo stesso vale per il campo email. Altrimenti, non funzionerà.E con questo, abbiamo finito!

Ottima soluzione! Semplice ed efficace. Ma dove inserisci questi snippet? In una sidebar? Questo suggerimento sembra funzionare solo con un modulo di registrazione ajax.

questo articolo fornisce un ottimo tutorial su come creare i propri moduli frontend per registrazione/login/recupero password.
oppure se stai cercando un plugin, ho usato questi in passato e posso raccomandarli:

Ho realizzato un sito web qualche tempo fa che mostrava un modulo di registrazione personalizzato sul front-end. Questo sito non è più online, ma ecco alcuni screenshot.
Ecco i passaggi che ho seguito:
1) Attivare la possibilità per tutti i visitatori di richiedere un nuovo account tramite Impostazioni > Generale > Opzione Membership. La pagina di registrazione ora appare all'URL /wp-login.php?action=register
2) Personalizzare il modulo di registrazione in modo che abbia lo stesso stile del front-end del tuo sito. Questo è più complesso e dipende dal tema che stai utilizzando.
Ecco un esempio con twentythirteen:
// includi script e stili del tema nella pagina di login/registrazione
add_action('login_enqueue_scripts', 'twentythirteen_scripts_styles');
// rimuovi lo stile admin nella pagina di login/registrazione
add_filter( 'style_loader_tag', 'user16975_remove_admin_css', 10, 2);
function user16975_remove_admin_css($tag, $handle){
if ( did_action('login_init')
&& ($handle == 'wp-admin' || $handle == 'buttons' || $handle == 'colors-fresh'))
return "";
else return $tag;
}
// mostra header e footer del front-end nella pagina di login/registrazione
add_action('login_footer', 'user16975_integrate_login');
function user16975_integrate_login(){
?><div id="page" class="hfeed site">
<header id="masthead" class="site-header" role="banner">
<a class="home-link" href="<?php echo esc_url( home_url( '/' ) ); ?>" title="<?php echo esc_attr( get_bloginfo( 'name', 'display' ) ); ?>" rel="home">
<h1 class="site-title"><?php bloginfo( 'name' ); ?></h1>
<h2 class="site-description"><?php bloginfo( 'description' ); ?></h2>
</a>
<div id="navbar" class="navbar">
<nav id="site-navigation" class="navigation main-navigation" role="navigation">
<h3 class="menu-toggle"><?php _e( 'Menu', 'twentythirteen' ); ?></h3>
<a class="screen-reader-text skip-link" href="#content" title="<?php esc_attr_e( 'Vai al contenuto', 'twentythirteen' ); ?>"><?php _e( 'Vai al contenuto', 'twentythirteen' ); ?></a>
<?php wp_nav_menu( array( 'theme_location' => 'primary', 'menu_class' => 'nav-menu' ) ); ?>
<?php get_search_form(); ?>
</nav><!-- #site-navigation -->
</div><!-- #navbar -->
</header><!-- #masthead -->
<div id="main" class="site-main">
<?php get_footer(); ?>
<script>
// sposta il modulo di login nell'area principale della pagina
jQuery('#main').append(jQuery('#login'));
</script>
<?php
}
Poi modifica il foglio di stile del tema per far apparire il modulo come desideri.
3) Puoi modificare ulteriormente il form personalizzando i messaggi visualizzati:
add_filter('login_message', 'user16975_login_message');
function user16975_login_message($message){
if(strpos($message, 'register') !== false){
$message = 'messaggio personalizzato di registrazione';
} else {
$message = 'messaggio personalizzato di login';
}
return $message;
}
add_action('login_form', 'user16975_login_message2');
function user16975_login_message2(){
echo 'un altro messaggio personalizzato di login';
}
add_action('register_form', 'user16975_tweak_form');
function user16975_tweak_form(){
echo 'un altro messaggio personalizzato di registrazione';
}
4) Se hai bisogno di un modulo di registrazione front-end, probabilmente non vorrai che gli utenti registrati vedano il backend quando fanno il login.
add_filter('user_has_cap', 'user16975_refine_role', 10, 3);
function user16975_refine_role($allcaps, $cap, $args){
global $pagenow;
$user = wp_get_current_user();
if($user->ID != 0 && $user->roles[0] == 'subscriber' && is_admin()){
// nega l'accesso al backend di WP
$allcaps['read'] = false;
}
return $allcaps;
}
add_action('admin_page_access_denied', 'user16975_redirect_dashbord');
function user16975_redirect_dashbord(){
wp_redirect(home_url());
die();
}
Sono tanti passaggi, ma il risultato è questo!

Molto più semplice: utilizza una funzione di WordPress chiamata wp_login_form()
(pagina Codex qui).
Puoi creare il tuo plugin per poter utilizzare uno shortcode in una delle tue pagine:
<?php
/*
Plugin Name: WP Login Form Shortcode
Description: Usa <code>[wp_login_form]</code> per mostrare il form di login di WordPress.
Version: 1.0
Author: WP-Buddy
Author URI: http://wp-buddy.com
License: GPLv2 or later
*/
add_action( 'init', 'wplfsc_add_shortcodes' );
function wplfsc_add_shortcodes() {
add_shortcode( 'wp_login_form', 'wplfsc_shortcode' );
}
function wplfsc_shortcode( $atts, $content, $name ) {
$atts = shortcode_atts( array(
'redirect' => site_url( $_SERVER['REQUEST_URI'] ),
'form_id' => 'loginform',
'label_username' => __( 'Nome utente' ),
'label_password' => __( 'Password' ),
'label_remember' => __( 'Ricordami' ),
'label_log_in' => __( 'Accedi' ),
'id_username' => 'user_login',
'id_password' => 'user_pass',
'id_remember' => 'rememberme',
'id_submit' => 'wp-submit',
'remember' => false,
'value_username' => NULL,
'value_remember' => false
), $atts, $name );
// echo è sempre false
$atts['echo'] = false;
// converte in valori booleani reali
$atts['remember'] = filter_var( $atts['remember'], FILTER_VALIDATE_BOOLEAN );
$atts['value_remember'] = filter_var( $atts['value_remember'], FILTER_VALIDATE_BOOLEAN );
return '<div class="cct-login-form">' . wp_login_form( $atts ) . '</div>';
}
Tutto quello che devi fare è stilizzare il tuo form nel frontend.

Se sei aperto all'uso di plugin, ho utilizzato in passato l'add-on User Registration per Gravity Forms e ha funzionato molto bene:
http://www.gravityforms.com/add-ons/user-registration/
Nota: Mi rendo conto che questa non sia una soluzione molto dettagliata, ma fa esattamente ciò di cui hai bisogno ed è una buona soluzione.
Per approfondire ulteriormente la mia risposta, l'add-on User Registration per Gravity Forms ti permette di mappare qualsiasi campo in un modulo creato con Gravity Forms ai campi specifici dell'utente. Ad esempio, puoi creare un modulo con Nome, Cognome, Email, Sito Web, Password. All'invio, l'add-on mapperà tali input ai relativi campi utente.
Un'altra grande caratteristica è che puoi aggiungere gli utenti registrati in una coda di approvazione. I loro account utente verranno creati solo dopo essere stati approvati nel backend da un amministratore.
Se il link sopra non funziona, cerca su Google "User Registration add on for Gravity Forms"

Hai letto le note che @kaiser ha aggiunto alla domanda (in grassetto le mie): "Cerchiamo risposte lunghe che forniscano spiegazioni e contesto. Non limitarti a dare una risposta di una riga; spiega perché la tua risposta è corretta, idealmente con citazioni. Le risposte che non includono spiegazioni potrebbero essere rimosse"

Sì, ma ho pensato che l'add-on valesse comunque la pena menzionarlo, dato che l'OP non menziona la necessità di codificarlo personalmente. Felice di spostarlo in un commento se ritieni sia necessario

Non sono un moderatore, quindi non posso spostare la tua risposta in un commento. Posso solo votare negativamente, ma non l'ho fatto perché penso che il tuo link contenga informazioni utili, tuttavia, una risposta composta solo da un link non è utile, anche perché quel link potrebbe cambiare facilmente e quindi la tua risposta porterebbe a un 404. Prova a riportare qui il codice rilevante e a spiegare cosa fa quel codice, poi la tua risposta sarà a posto, credo.

James, ho assegnato la ricompensa a una risposta reale che include il codice. Se vuoi una ricompensa aggiuntiva, per favore analizza il plugin in dettaglio e mostracelo esattamente cosa fa. Grazie.
