Cómo crear un perfil de usuario en el frontend con un permalink amigable
Quiero crear una página pública de perfil en el frontend con una URL amigable en este formato:
misitio.com/usuario/nombredeusuario
¿Alguna idea sobre cómo puedo lograrlo? Sé que tiene que ver con las reglas de reescritura pero no tengo idea de cómo hacerlo. Si tienes algún enlace o tutorial sería genial.
¡Gracias!

He descubierto dos formas de hacer esto:
- Página de autor con una regla de reescritura personalizada
- Archivos de plantilla personalizados junto con una regla de reescritura
La primera es más simple de implementar, pero puede que no funcione en todas las circunstancias (una de las cuales describiré pronto).
Regla de reescritura personalizada
Encontré esta solución hace unos días aquí: URL Rewriting
Y aquí está el código, con comentarios:
// Define los niveles de autor que deseas usar
$custom_author_levels = array( 'user', 'leader' );
// En init, agrega una nueva etiqueta de reescritura author_level y añádela a la propiedad author_base de wp_rewrite
add_action( 'init', 'wpleet_init' );
function wpleet_init()
{
global $wp_rewrite;
$author_levels = $GLOBALS['custom_author_levels'];
// Define la etiqueta y úsala en la regla de reescritura
add_rewrite_tag( '%author_level%', '(' . implode( '|', $author_levels ) . ')' );
$wp_rewrite->author_base = '%author_level%';
}
// La función anterior crea reglas de reescritura author_name adicionales que son innecesarias.
// Esta función las detecta y elimina
add_filter( 'author_rewrite_rules', 'wpleet_author_rewrite_rules' );
function wpleet_author_rewrite_rules( $author_rewrite_rules )
{
foreach ( $author_rewrite_rules as $pattern => $substitution ) {
if ( FALSE === strpos( $substitution, 'author_name' ) ) {
unset( $author_rewrite_rules[$pattern] );
}
}
return $author_rewrite_rules;
}
Luego puedes usar la plantilla author.php integrada, modificándola a tu gusto.
Te recomiendo revisar el enlace mencionado arriba, ya que Jan Fabry hace un excelente trabajo explicando todo.
Variables de consulta y plantillas de página
Para el tema en el que estaba trabajando al descubrir estas soluciones, necesitaba servir una página personalizada basada en un valor de metadato de usuario (un ID separado). Mi cliente no quería que el nombre de usuario o el ID fueran visibles públicamente, así que creamos una capa separada.
¿El único problema? Actualmente no hay una forma clara de usar la API de reescritura para consultar por claves/valores de metadatos. Afortunadamente, había una solución.
En tu archivo functions.php...
// Crea la variable de consulta para que WP capture tu URL personalizada /user/nombredeusuario
add_filter( 'query_vars', 'wpleet_rewrite_add_var' );
function wpleet_rewrite_add_var( $vars )
{
$vars[] = 'user';
return $vars;
}
Luego, necesitas crear una nueva etiqueta y regla de reescritura para que sepa cuándo y cómo manejar la nueva variable de consulta.
add_rewrite_tag( '%user%', '([^&]+)' );
add_rewrite_rule(
'^user/([^/]*)/?',
'index.php?user=$matches[1]',
'top'
);
Una vez hecho esto, solo necesitas "capturar" cuando se está usando la variable de consulta y redirigir a la plantilla de tu elección:
add_action( 'template_redirect', 'wpleet_rewrite_catch' );
function wpleet_rewrite_catch()
{
global $wp_query;
if ( array_key_exists( 'user', $wp_query->query_vars ) ) {
include (TEMPLATEPATH . '/user-profile.php');
exit;
}
}
Solo asegúrate de haber creado user-profile.php.
En mi ejemplo, creé una tercera función que emparejaba el "ID de usuario público" con el user_id real a través de la tabla $wpdb->usermeta, y pasaba la información a la plantilla.
Si necesitas crear una plantilla diferente al resto de tu tema, recuerda que con get_header puedes especificar un nombre:
get_header( 'user' );
Lo cual llamará al archivo header-user.php.
Conclusión
Ambas son soluciones válidas y funcionales. La segunda ofrece una capa adicional de "seguridad" ya que no revela IDs de usuario o nombres de usuario, si otras personas podrán navegar los perfiles.
Espero que ayude, avísame si tienes alguna pregunta.

@bybloggers Sé que esta publicación es un poco antigua, pero tenía curiosidad por saber si podrías compartir tu tercera función para pasar el nombre de usuario en la URL a la plantilla?

@Pat No estoy seguro de dónde está la función exacta en todo mi código en este momento (como dijiste, fue hace un tiempo), pero el formato seguiría muy de cerca la función wpleet_rewrite_catch(). En lugar de array_key_exists('user'), estaba verificando el ID público del usuario, y luego haciendo una búsqueda en la tabla wp_usermeta para ver qué usuario tenía asociado ese ID público. Espero que el algoritmo ayude, incluso si el código no está disponible.

Encontré esto hoy temprano y realicé algunas modificaciones al código de @bybloggers con la diferencia de que en lugar de usar template_redirect cambié la solicitud para mostrar una página estática, lo que significa que ahora puedes agregar lo que quieras a una plantilla de página y usarlo en esa página.
class ProfilePage {
function __construct() {
add_filter( 'init',array($this,'rw_init'));
add_filter( 'query_vars', array($this,'wpleet_rewrite_add_var') );
add_filter( 'request', array($this,'change_requests'));
}
function wpleet_rewrite_add_var( $vars ) {
$vars[] = 'usuario';
return $vars;
}
function rw_init(){
add_rewrite_tag( '%usuario%', '([^&]+)' );
add_rewrite_rule(
'^usuario/([^/]*)/?',
'index.php?usuario=$matches[1]',
'top'
);
}
function change_requests($query_vars) {
//ir a una página específica cuando la clave usuario está configurada
$query_vars['page_id'] = isset($query_vars['usuario']) ? 7581 : $query_vars['page_id'];
return $query_vars;
}
}
new ProfilePage();
Español -> usuario = user <- Inglés

Este es mi código funcional basado en la respuesta de @bybloggers (gracias por cierto).
Acabo de aprender que no deberíamos usar el hook template_redirect y luego salir de PHP, porque algunas cosas pueden dejar de funcionar debido a la interrupción abrupta de la ejecución del código PHP.
La explicación está aquí: https://markjaquith.wordpress.com/2014/02/19/template_redirect-is-not-for-loading-templates/
Por lo tanto, deberíamos usar el hook template_include. Con este hook, no es necesario usar el método de redirección y salida.
Y la otra diferencia es que solo necesitaba www.server.com/micuenta sin el /userid.
Este es el código:
add_filter( 'query_vars', 'wp58683_userprofile_var' );
function wp58683_userprofile_var( $vars )
{
$vars[] = 'myprofile';
return $vars;
}
add_rewrite_tag( '%myprofile%', '([^&]+)' );
add_rewrite_rule(
'^myprofile/?',
'index.php?myprofile',
'top'
);
add_action( 'template_include', 'wp58683_userprofile_page' );
function wp58683_userprofile_page($original_template)
{
global $wp_query;
if ( array_key_exists( 'myprofile', $wp_query->query_vars ) ) {
if (is_user_logged_in() ){
return TEMPLATEPATH . '/user-profile.php';
}
}
else {
return $original_template;
}
}

Otra forma es utilizar Buddypress que tiene esta funcionalidad integrada, aunque el plugin tiene aún más características que pueden no ser de interés.
