¿Cómo mostrar el formulario de registro de usuario de WordPress en la parte frontal del sitio web?

30

¿Cómo mostrar el formulario de registro de usuario de WordPress (el formulario que aparece en la página "www.mywebsite.com/wp-register.php") en la parte frontal de mi blog?

He personalizado el formulario de registro. Pero no sé cómo llamar a ese formulario en la página de inicio. Cualquier apoyo será de gran ayuda.

Gracias por adelantado. :)

bueltge
fuente
La mejor solución que encontré es el complemento Theme My Login .
wyrfel
Este artículo proporciona un excelente tutorial sobre cómo crear sus propios formularios de registro / inicio de sesión / restauración de la interfaz de usuario. o si está buscando un complemento, los he usado antes y puedo recomendarlos: - Ajax Iniciar sesión / Registrarse - Iniciar sesión con Ajax
Bainternet
Cristian de Cosmolabs ha publicado un gran tutorial con archivos fuente que le dan la capacidad de crear un perfil de usuario front-end, plantillas de inicio de sesión y registro.
Philip

Respuestas:

33

El proceso implica 2 pasos:

  1. muestra el formulario de la interfaz
  2. guardar los datos en el envío

Hay 3 enfoques diferentes que se me ocurren para mostrar la interfaz:

  • use el formulario de registro incorporado, los estilos de edición, etc. para hacerlo más parecido a "frontend like"
  • use una página / publicación de WordPress y muestre el formulario usando un código corto
  • use una plantilla dedicada no conectada con ninguna página / publicación, pero llamada por una URL específica

Para esta respuesta, usaré la última. Los motivos son:

  • El uso del formulario de registro incorporado puede ser una buena idea, las personalizaciones profundas pueden ser muy difíciles usando el formulario incorporado, y si uno también desea personalizar los campos del formulario, el dolor aumentará
  • usar una página de WordPress en combinación con un código corto, no es tan confiable, y también creo que los shorcodes no deberían usarse para la funcionalidad, solo para formatear y

1: Construye la url

Todos sabemos que el formulario de registro predeterminado de un sitio de WordPress es a menudo un objetivo para los spammers. Usar una URL personalizada es una ayuda para resolver este problema. Además, también quiero usar una URL variable , es decir, la url del formulario de registro no debe ser siempre la misma, esto hace que la vida de los spammers sea más difícil. El truco se hace usando un nonce en la url:

/**
* Generate dynamic registration url
*/
function custom_registration_url() {
  $nonce = urlencode( wp_create_nonce( 'registration_url' ) );
  return home_url( $nonce );
}

/**
* Generate dynamic registration link
*/
function custom_registration_link() {
  $format = '<a href="%s">%s</a>';
  printf(
    $format,
    custom_registration_url(), __( 'Register', 'custom_reg_form' )
  );
}

El uso de estas funciones es fácil de mostrar en las plantillas un enlace al formulario de registro, incluso si es dinámico.

2: Reconocer la url, primer trozo de Custom_Reg\Custom_Regclase

Ahora necesitamos reconocer la url. Para el propósito, comenzaré a escribir una clase, que se terminará más adelante en la respuesta:

<?php
// don't save, just a stub
namespace Custom_Reg;

class Custom_Reg {

  function checkUrl() {
    $url_part = $this->getUrl();
    $nonce = urlencode( wp_create_nonce( 'registration_url' ) );
    if ( ( $url_part === $nonce ) ) {
      // do nothing if registration is not allowed or user logged
      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 función mira la primera parte de la url después home_url(), y si coincide con nuestro nonce, devuelve TRUE. Esta función se utilizará para verificar nuestra solicitud y realizar las acciones necesarias para mostrar nuestro formulario.

3: la Custom_Reg\Formclase

Ahora escribiré una clase, que será responsable de generar el marcado del formulario. Lo usaré también para almacenar en una propiedad la ruta del archivo de plantilla que se debe usar para mostrar el formulario.

<?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( "Invalid field" );
      }
      $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( "Invalid template" );
    }
    $this->template = $template;
  }

  public function addField( FieldInterface $field ) {
    $hook = 'custom_reg_form_create';
    if ( did_action( $hook ) && current_filter() !== $hook ) {
      throw new \BadMethodCallException( "Add fields before {$hook} is fired" );
    }
    $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( "Invalid verb" );
    }
    $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 =  __('Register', 'custom_reg_form');
    $out = sprintf( '<input type="submit" value="%s" />', $submit );
    $out .= '</form>';
    return $out;
  }

}

La clase genera un marcado de formulario que recorre todos los campos con un createmétodo de llamada agregado en cada uno de ellos. Cada campo debe ser instancia de Custom_Reg\FieldInterface. Se agrega un campo oculto adicional para la no verificación. El método de formulario es 'POST' de forma predeterminada, pero se puede establecer en 'GET' usando el setVerbmétodo. Una vez creado, el marcado se guarda dentro de la $formpropiedad del objeto que se repite por output()método, enganchado en el 'custom_registration_form'gancho: en la plantilla de formulario, simplemente la llamada do_action( 'custom_registration_form' )generará el formulario.

4: la plantilla predeterminada

Como dije, la plantilla para el formulario se puede anular fácilmente, sin embargo, necesitamos una plantilla básica como respaldo. Escribiré aquí una plantilla muy aproximada, más una prueba de concepto que una plantilla real.

<?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(
    'Thank you, your registration was submitted, check your 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: la Custom_Reg\FieldInterfaceinterfaz

Cada campo debe ser un objeto que implemente la siguiente interfaz

<?php 
// file: FieldInterface.php
namespace Custom_Reg;

interface FieldInterface {

  /**
   * Return the field id, used to name the request value and for the 'name' param of
   * html input field
   */
  public function getId();

  /**
   * Return the filter constant that must be used with
   * filter_input so get the value from request
   */
  public function getFilter();

  /**
   * Return true if the used value passed as argument should be accepted, false if not
   */
  public function isValid( $value = NULL );

  /**
   * Return true if field is required, false if not
   */
  public function isRequired();

  /**
   * Return the field input markup. The 'name' param must be output 
   * according to getId()
   */
  public function create( $value = '');
}

Creo que los comentarios explican qué deberían hacer las clases que implementan esta interfaz.

6: Agregar algunos campos

Ahora necesitamos algunos campos. Podemos crear un archivo llamado 'fields.php' donde definimos las clases de campos:

<?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 __( 'Full Name', '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 __( 'Country', 'custom_reg_form' );
  }
}

Utilicé una clase base para definir la implementación predeterminada de la interfaz, sin embargo, uno puede agregar campos muy personalizados implementando directamente la interfaz o extendiendo la clase base y anulando algunos métodos.

En este punto tenemos todo para mostrar el formulario, ahora necesitamos algo para validar y guardar los campos.

7: la Custom_Reg\Saverclase

<?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;
  }

  /**
  * validate all the fields
  */
  public function validate() {
    // if registration is not allowed return false
    if ( ! get_option('users_can_register') ) return FALSE;
    // if no fields are setted return FALSE
    if ( ! $this->getFields() instanceof \ArrayIterator ) return FALSE;
    // first check nonce
    $nonce = $this->getValue( '_n' );
    if ( $nonce !== wp_create_nonce( 'custom_reg_form_nonce' ) ) return FALSE;
    // then check all fields
    $it =  $this->getFields();
    while( $it->valid() ) {
      $field = $it->current();
      $key = $field->getID();
      if ( ! $field instanceof FieldInterface ) {
        throw new \DomainException( "Invalid field" );
      }
      $value = $this->getValue( $key, $field->getFilter() );
      if ( $field->isRequired() && empty($value) ) {
        $this->error = sprintf( __('%s is required', 'custom_reg_form' ), $key );
        return FALSE;
      }
      if ( ! $field->isValid( $value ) ) {
        $this->error = sprintf( __('%s is not valid', '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;
  }

  /**
  * Save the user using core register_new_user that handle username and email check
  * and also sending email to new user
  * in addition save all other custom data in user meta
  *
  * @see register_new_user()
  */
  public function save() {
    // if registration is not allowed return false
    if ( ! get_option('users_can_register') ) return FALSE;
    // check mandatory fields
    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( "Invalid value" );
    }
    $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;
  }

}

Esa clase tiene 2 métodos principales, uno ( validate) que repite los campos, los valida y guarda buenos datos en una matriz, el segundo ( save) guarda todos los datos en la base de datos y envía la contraseña por correo electrónico al nuevo usuario.

8: Usar clases definidas: terminar la Custom_Regclase

Ahora podemos volver a trabajar en Custom_Regclase, agregando los métodos que "pegan" el objeto definido y los hacen funcionar

<?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;
  }

  /**
   * Check if the url to recognize is the one for the registration form page
   */
  function checkUrl() {
    $url_part = $this->getUrl();
    $nonce = urlencode( wp_create_nonce( 'registration_url' ) );
    if ( ( $url_part === $nonce ) ) {
      // do nothing if registration is not allowed or user logged
      if ( is_user_logged_in() || ! get_option('users_can_register') ) {
        wp_safe_redirect( home_url() );
        exit();
      }
      return TRUE;
    }
  }

  /**
   * Init the form, if submitted validate and save, if not just display it
   */
  function init() {
    if ( $this->checkUrl() !== TRUE ) return;
    do_action( 'custom_reg_form_init', $this->form );
    if ( $this->isSubmitted() ) {
      $this->save();
    }
    // don't need to create form if already saved
    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 ) { // validate?
      if ( $this->saver->save() ) { // saved?
        global $custom_reg_form_done;
        $custom_reg_form_done = TRUE;
      } else { // saving error
        $err =  $this->saver->getErrorMessage(); 
        $custom_reg_form_error = $err ? : __( 'Error on save.', 'custom_reg_form' );
      }
    } else { // validation error
       $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];
    }
  }

}

El constructor de la clase acepta una instancia de Formy una de Saver.

init()El método (usando checkUrl()) mira la primera parte de la url después home_url(), y si coincide con el nonce correcto, verifica si el formulario ya se envió, si es así, usando el Saverobjeto, valida y guarda los datos de usuario, de lo contrario simplemente imprima el formulario .

init()El método también activa el gancho de acción que 'custom_reg_form_init'pasa la instancia del formulario como argumento: este gancho se debe usar para agregar campos, configurar la plantilla personalizada y también para personalizar el método del formulario.

9: poner las cosas juntas

Ahora tenemos que escribir el archivo de complemento principal, donde podamos

  • requerir todos los archivos
  • cargar el dominio de texto
  • iniciar todo el proceso utilizando una Custom_Regclase de instanciación y un init()método de llamada utilizando un enlace razonablemente temprano
  • use 'custom_reg_form_init' para agregar los campos a la clase de formulario

Asi que:

<?php 
/**
 * Plugin Name: Custom Registration Form
 * Description: Just a rough plugin example to answer a WPSE question
 * 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; // this plugin is all about 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';

/**
* Generate dynamic registration url
*/
function custom_registration_url() {
  $nonce = urlencode( wp_create_nonce( 'registration_url' ) );
  return home_url( $nonce );
}

/**
* Generate dynamic registration link
*/
function custom_registration_link() {
  $format = '<a href="%s">%s</a>';
  printf(
    $format,
    custom_registration_url(), __( 'Register', 'custom_reg_form' )
  );
}

/**
* Setup, show and save the 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 = 'Exception on  ' . __FUNCTION__;
      $msg .= ', Type: ' . get_class( $e ) . ', Message: ';
      $msg .= $e->getMessage() ? : 'Unknown error';
      error_log( $msg );
    }
    wp_safe_redirect( home_url() );
  }
}, 0 );

/**
* Add fields to 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: tareas faltantes

Ahora todo está bastante hecho. Solo tenemos que personalizar la plantilla, probablemente agregando un archivo de plantilla personalizado en nuestro tema.

Podemos agregar estilos y scripts específicos solo a la página de registro personalizada de esta manera

add_action( 'wp_enqueue_scripts', function() {
  // if not on custom registration form do nothing
  if ( did_action('custom_reg_form_init') ) {
    wp_enqueue_style( ... );
    wp_enqueue_script( ... );
  }
});

Usando ese método podemos poner en cola algunos scripts js para manejar la validación del lado del cliente, por ejemplo, este . El marcado necesario para que el script funcione puede manejarse fácilmente editando la Custom_Reg\BaseFieldclase.

Si queremos personalizar el correo electrónico de registro, podemos usar el método estándar y tener datos personalizados guardados en meta, podemos usarlos en el correo electrónico.

La última tarea que probablemente queremos implementar es evitar la solicitud del formulario de registro predeterminado, tan fácil como:

add_action( 'login_form_register', function() { exit(); } );

Todos los archivos se pueden encontrar en un Gist aquí .

gmazzap
fuente
1
¡Guau, este es un rediseño completo de la funcionalidad de registro! Probablemente sea una buena solución si desea anular completamente el proceso de registro incorporado. Creo que no usar el formulario de registro incorporado no es una buena idea porque perderá otras características principales, como el formulario de contraseña perdida. Y luego, un usuario recién registrado necesitaría mostrar el formulario de inicio de sesión tradicional para iniciar sesión.
Fabien Quatravaux
1
@FabienQuatravaux perdió la contraseña y el formulario de inicio de sesión solo se puede usar como de costumbre (backend). Sí, el código es incompleta porque la contraseña perdida y la forma de la conexión no se manejan, pero la pregunta era sólo de OP formulario de inscripción y la respuesta fue ya demasiado tiempo para agregar otras funcionalidades ...
gmazzap
13

TLDR; Ponga el siguiente formulario en su tema, los atributos namey idson importantes:

<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="Register" id="register" />
</form>

Encontré un excelente artículo de Tutsplus sobre Cómo crear un elegante formulario de registro de Wordpress desde cero . Esto pasa mucho tiempo en diseñar el formulario, pero tiene la siguiente sección bastante simple sobre el código de WordPress requerido:

Paso 4. WordPress

No hay nada lujoso aquí; solo necesitamos dos fragmentos de WordPress, ocultos dentro del archivo wp-login.php.

El primer fragmento:

<?php echo site_url('wp-login.php?action=register', 'login_post') ?>  

Y:

<?php do_action('register_form'); ?>

Editar: agregué el bit final adicional del artículo para explicar dónde colocar los fragmentos de código anteriores, es solo un formulario para que pueda ir en cualquier plantilla de página o barra lateral o hacer un código corto. La sección importante es la formque contiene los fragmentos anteriores y los campos obligatorios importantes.

El código final debería verse así:

<div style="display:none"> <!-- Registration -->
        <div id="register-form">
        <div class="title">
            <h1>Register your Account</h1>
            <span>Sign Up with us and Enjoy!</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="Register" id="register" />
            <hr />
            <p class="statement">A password will be e-mailed to you.</p>


            </form>
        </div>
</div><!-- /Registration -->

Tenga en cuenta que es realmente importante y necesario tener user_logincomo namey como idatributo en su entrada de texto; Lo mismo es cierto para la entrada de correo electrónico. De lo contrario, no funcionará.

Y con eso, ¡hemos terminado!

icc97
fuente
¡Gran solución! Simple y eficiente. ¿Pero dónde pones esos fragmentos? En una barra lateral? Este consejo parece funcionar solo con un formulario de registro ajax.
Fabien Quatravaux
1
Gracias @FabienQuatravaux, he actualizado la respuesta para incluir la última sección del artículo. No debería haber necesidad de un formulario AJAX, es solo un formulario POST que se envía a la wp-login.php?action=registerpágina
icc97
4

Hice un sitio web hace algún tiempo que mostraba un formulario de registro personalizado en el lado frontal. Este sitio web ya no está disponible, pero aquí hay algunas capturas de pantalla. formulario de inicio de sesión formulario de inscripción formulario de contraseña perdida

Aquí están los pasos que he seguido:

1) Active la posibilidad de que todos los visitantes soliciten una nueva cuenta a través de la opción Configuración> General> Membresía. La página de registro ahora aparece en la URL /wp-login.php?action=register

2) Personalice el formulario de registro para que se vea como el front-end de su sitio. Esto es más complicado y depende del tema que esté utilizando.

Aquí hay un ejemplo con veintitrés:

// include theme scripts and styles on the login/registration page
add_action('login_enqueue_scripts', 'twentythirteen_scripts_styles');

// remove admin style on the login/registration page
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;
}

// display front-end header and footer on the login/registration page
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( 'Skip to content', 'twentythirteen' ); ?>"><?php _e( 'Skip to content', '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>
        // move the login form into the page main content area
        jQuery('#main').append(jQuery('#login'));
    </script>
    <?php
}

Luego, modifique la hoja de estilo del tema para que el formulario aparezca como desee.

3) Puede modificar aún más el formulario ajustando los mensajes mostrados:

add_filter('login_message', 'user16975_login_message');
function user16975_login_message($message){
    if(strpos($message, 'register') !== false){
        $message = 'custom register message';
    } else {
        $message = 'custom login message';
    }
    return $message;
}

add_action('login_form', 'user16975_login_message2');
function user16975_login_message2(){
    echo 'another custom login message';
}

add_action('register_form', 'user16975_tweak_form');
function user16975_tweak_form(){
    echo 'another custom register message';
}

4) Si necesita un formulario de registro front-end, probablemente no querrá que los usuarios registrados vean el backend cuando inicien sesión.

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()){
        // deny access to WP backend
        $allcaps['read'] = false;
    }

    return $allcaps;
}

add_action('admin_page_access_denied', 'user16975_redirect_dashbord');
function user16975_redirect_dashbord(){
    wp_redirect(home_url());
    die();
}

Hay muchos pasos, ¡pero el resultado está aquí!

Fabien Quatravaux
fuente
0

Mucho más fácil: use una función de WordPress llamada wp_login_form()( página del Codex aquí ).

Puede crear su propio complemento para que pueda usar un shortcode en sus páginas:

<?php
/*
Plugin Name: WP Login Form Shortcode
Description: Use <code>[wp_login_form]</code> to show WordPress' login form.
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' => __( 'Username' ),
        'label_password' => __( 'Password' ),
        'label_remember' => __( 'Remember Me' ),
        'label_log_in'   => __( 'Log In' ),
        '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 is always false
$atts['echo'] = false;

// make real boolean values
$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>';

}

Todo lo que tiene que hacer es diseñar su formulario en la interfaz.

Fluir
fuente
-1

Si está abierto al uso de complementos, he usado el complemento de registro de usuario para Gravity Forms anteriormente, funcionó muy bien:

http://www.gravityforms.com/add-ons/user-registration/

Editar: me doy cuenta de que esta no es una solución muy detallada, pero hace exactamente lo que necesita y es una buena solución.

Editar: para ampliar aún más mi respuesta, el complemento Registro de usuario para formularios de gravedad le permite asignar cualquier campo de un formulario creado usando Gravity Forms a campos específicos del usuario. Por ejemplo, puede crear un formulario con Nombre, Apellido, Correo electrónico, Sitio web, Contraseña. Tras el envío, el complemento asignará esas entradas a los campos de usuario relevantes.

Otra gran cosa al respecto es que puede agregar a cualquier usuario registrado en una cola de aprobación. Sus cuentas de usuario solo se crearían una vez aprobadas en el backend por un administrador.

Si el enlace anterior se rompe, simplemente agregue "Registro de usuario de Google para los formularios de gravedad"

James Kemp
fuente
2
¿Ha leído las notas @kaiser agregadas a la pregunta (negrita mía): "Estamos buscando respuestas largas que brinden alguna explicación y contexto . No solo dé una respuesta de una línea; explique por qué su respuesta es correcta, idealmente con citas. Las respuestas que no incluyen explicaciones pueden eliminarse "
gmazzap
Sí, pero sentí que aún vale la pena mencionar el complemento, ya que el OP no menciona la necesidad de codificarlo de forma personalizada. Feliz de pasarlo a un comentario si lo considera necesario
James Kemp
No soy un mod, así que no puedo moverme para comentar tu respuesta. Solo puedo votar en contra, pero no lo he hecho porque creo que su enlace contiene información útil, sin embargo, la respuesta de solo enlace no es útil, incluso porque ese enlace se puede cambiar fácilmente y su respuesta llega a un 404. Intente informar aquí el código relevante y explique qué hace ese código, entonces su respuesta está bien, supongo.
gmazzap
James, le di la recompensa a una respuesta real que incluye código. Si desea una recompensa adicional, desgarre el complemento y muéstrenos exactamente lo que está haciendo. Gracias.
Kaiser
Hola Kaiser, no busco la recompensa, ¡solo quería compartir mi conocimiento del complemento!
James Kemp