¿Necesita ayuda con add_rewrite_rule

55

SOLUCIÓN


Fui con la Actualización 3 y la tengo funcionando. Lo que tenía mal entendido, era que yo creía que una regla de reescritura cambiaría designers/?designer=some-designer&bid=9a /designers/some-designer. Pero, por supuesto, es al revés.


He estado investigando un poco, pero no entiendo cómo usar add_rewrite_rule () .

Esta publicación está bastante cerca de lo que necesito, pero ¿realmente necesito tanto código?

Mi enlace actual es este:
http://www.norwegianfashion.no/designers/?designer=Batlak-og-Selvig&bid=9
Lo que quiero es esto
http://www.norwegianfashion.no/designers/Batlak-og-Selvig / /

  1. ¿Cómo lo uso add_rewrite_rule()?
  2. Necesito pasar la identificación del diseñador (oferta). ¿Cómo puedo hacer eso cuando uso las reglas re.write sin que se muestre en la URL?

Actualización 1

Encontré esto que es un poco más explicativo. Pero no está funcionando:

function add_rewrite_rules( $wp_rewrite ) 
{
    $new_rules = array(
        '('.$template_page_name.')/designers/(.*?)/?([0-9]{1,})/?$' => 'designers.php?designer='.
        $wp_rewrite->preg_index(1).'&bid='.
        $wp_rewrite->preg_index(2)
    );
       // Always add your rules to the top, to make sure your rules have priority
    $wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
}
add_action('generate_rewrite_rules', 'add_rewrite_rules');

function query_vars($public_query_vars) {

    $public_query_vars[] = "designer";
    $public_query_vars[] = "bid";
    return $public_query_vars;
}
add_filter('query_vars', 'query_vars')

Actualización 2

Aquí hay otra solución que he probado, que Jan Fabry sugirió en otro hilo. Puse esto en mis functions.php, pero no tiene ningún efecto.

add_action('generate_rewrite_rules', 'add_rewrite_rules');
add_filter('query_vars', 'query_vars');

/* Custom re-write rules for desigenrs
------------------------------------------------------------------------------*/
function add_rewrite_rules( $wp_rewrite ) 
{
    add_rewrite_rule('^designers/([^/]*)/([^/]*)$ /designers/?designer=$1&bid=$2 [L]', 'top');
    flush_rewrite_rules(false);
}


function query_vars($public_query_vars) {

    $public_query_vars[] = "designer";
    $public_query_vars[] = "bid";
    return $public_query_vars;
}

Actualización 3
También encontré algunos ejemplos aquí . Pero esto tampoco funciona :(

add_filter('rewrite_rules_array','wp_insertMyRewriteRules');
add_filter('query_vars','wp_insertMyRewriteQueryVars');
add_filter('init','flushRules');  

// Remember to flush_rules() when adding rules
function flushRules(){
    global $wp_rewrite;
    $wp_rewrite->flush_rules();
}

// Adding a new rule
function wp_insertMyRewriteRules($rules)
{
    $newrules = array();
    $newrules['(designers)/(\d*)$'] = 'index.php?pagename=designers&designer=$matches[1]';
    return $newrules + $rules;
}

// Adding the bid var so that WP recognizes it
function wp_insertMyRewriteQueryVars($vars)
{
    array_push($vars, 'designer');
    return $vars;
}

Actualización 4 También probé esta solución, pero aún no tuve éxito.

add_filter('search_rewrite_rules', 'designers_createRewriteRules');

function designers_createRewriteRules($rewrite) {
global $wp_rewrite;

// add rewrite tokens
$designer_token = '%designers%';
$wp_rewrite->add_rewrite_tag($designer_token, '(.+)', 'designers=');

$bid_token = '%bid%';
$wp_rewrite->add_rewrite_tag($bid_token, '(.+)', 'bid=');

$keywords_structure = $wp_rewrite->root . "designers/$designer_token/$bid_token";
$keywords_rewrite = $wp_rewrite->generate_rewrite_rules($keywords_structure);

return ( $rewrite + $keywords_rewrite );

}

Actualización 5
Parece que mis reglas de reescritura no se han agregado. Ejecutar las siguientes reglas nuevas después de radding: print_r($wp_rewrite)no incluye mis nuevas reglas de reescritura.

Actualización 6
Probé la solución de Jan. Pero la URL no cambia :(

/* Initiation script for NF template
------------------------------------------------------------------------------*/   
add_action('after_setup_theme','norwegianfashion_setup');

if ( ! function_exists( 'norwegianfashion_setup' ) ):

  function norwegianfashion_setup() { 
    /* Here I do a lot of stuff */

    // SEO friendly URL for desigenrs
    add_action( 'init', 'wpa5413_init' );
    add_filter( 'query_vars', 'wpa5413_query_vars' );
  }

endif;


/* Custom re-write rules for desigenrs
------------------------------------------------------------------------------*/
function wpa5413_init()
{
    // Remember to flush the rules once manually after you added this code!
    add_rewrite_rule(
        'designers/([^/]+)/?',
        'index.php?pagename=designers&designer=$matches[1]',
        'top' );
}

function wpa5413_query_vars( $query_vars )
{
    $query_vars[] = 'designer';
    return $query_vars;
}

Yo realmente apreciaría si alguien fuera capaz de ayudar a resolver este problema.

Steven
fuente
Esto se parece mucho a la primera pregunta que hizo aquí, y para la que le respondí . ¿Ha cambiado la situación desde entonces, por lo que mi respuesta ya no es válida? Si no desea la identificación del diseñador en su URL, deberá convertir la "babosa" a la identificación usted mismo, WordPress no puede hacer esto por usted. ¿Los diseñadores siguen siendo un objeto externo?
Jan Fabry
@ Jan Fabry Sí, descubrí que después de publicar esto (lo había olvidado). Ahora entiendo mejor tu sugerencia. Vea mi código actualizado aquí. Mis diseñadores siguen siendo entradas en una base de datos personalizada. ¿Es posible usar POST insteed og GET para pasar bid?
Steven
El uso de una solicitud POST no funcionará si copio el enlace y se lo envío a otra persona. ¿Es un problema hacer que la babosa sea única y buscar datos desde allí?
Jan Fabry
@ Jan Fabry: ¿Qué quieres decir con slug? `Recuperación de datos de diseño es mucho más fácil utilizar biden lugar dedesigner
Steven

Respuestas:

87

Algunos antecedentes sobre las reglas de reescritura

El sistema WP Rewrite parece complicado, pero de hecho no es tan difícil de entender cómo funciona. Se utiliza para analizar URL bonitas ( /designers/) como si no fueran bonitas ( /index.php?pagename=designers). La idea básica es que tiene una lista de reglas de reescritura , expresiones regulares que pueden coincidir con las URL entrantes, y reescribirlas en otras URL, principalmente en forma de index.phpalgunas variables de consulta. Estas variables se establecen en partes de la expresión regular que coincide con la URL. Las reglas se evalúan de arriba abajo, por lo que si dos reglas pueden coincidir, la primera "gana".

Estas reglas de reescritura se almacenan en la base de datos mediante una llamada flush_rewrite_rules(), pero dado que generar y escribir estas reglas es una operación costosa, no debe hacerlo en todos init. En cambio, solo lo hace cuando cambia las reglas: probablemente en la activación del complemento (usando register_activation_hook()), o manualmente visitando la página de configuración de Permalinks ( porque es difícil hacerlo automáticamente en la activación del tema ). Si no elimina las reglas, las llamadas add_rewrite_rule()no tienen efecto. No es ningún problema recurrir add_rewrite_rule()a todos init, incluso después de haber eliminado las reglas.

Hay muchas formas de agregar sus reglas de reescritura, y si solo desea agregar una regla, puede hacerlo con add_rewrite_rule(). Debido a que las reglas de mensajes, páginas, taxonomías, ... resultado en varias reglas, que se crean con las funciones de alto nivel como add_rewrite_tag(), add_permastruct(), ... Pero estos no son necesarios para el caso simple que tenemos aquí.

También hay algunos filtros, por lo que también puede agregar sus reglas usando los generate_rewrite_ruleso generate_rewrite_rules_arrayganchos. Estos le dan un control muy detallado sobre las reglas completas, pero nuevamente, add_rewrite_rule()es suficiente si solo desea agregar una regla.

Creé un pequeño complemento que le permite analizar las reglas de reescritura actuales , y (por supuesto) le recomiendo que lo use cuando intente cambiar algo.

Obteniendo su información extra de la URL

Construyamos sobre el ejemplo que diste. Tiene la marca del diseñador Batlak og Selvig, con la identificación numérica ( bid) 9. No desea esta ID en la URL, sino solo el nombre. Llamamos a la versión de URL amigable del nombre (sin espacios ni caracteres especiales) la babosa : Batlak-og-Selvig.

En general, la URL debe contener toda la información para identificar el contenido que desea mostrar en la página. Puede usar cookies o solicitudes POST para almacenar la ID de diseñador real que desea mostrar, pero esto se romperá si alguien comparte el enlace, enviándolo por correo, Facebook, Twitter, o simplemente leyéndolo en voz alta por teléfono. Si no desea utilizar el ID numérico en su URL, debe asegurarse de que el slug sea único: primero haga una búsqueda del ID en función del slug y continúe como lo hizo antes.

Entonces, lo que hemos aprendido ahora es que queremos agregar una regla de reescritura para el patrón " /designers/seguido de cualquier cosa hasta el siguiente /" , y guardar ese "cualquier cosa" en la designer_slugvariable de consulta. En su caso, creo que también desea usar la página con la babosa designerscomo contenido general de la página, así que también se lo diremos a WordPress.

add_action( 'init', 'wpa5413_init' );
function wpa5413_init()
{
    // Remember to flush the rules once manually after you added this code!
    add_rewrite_rule(
        // The regex to match the incoming URL
        'designers/([^/]+)/?',
        // The resulting internal URL: `index.php` because we still use WordPress
        // `pagename` because we use this WordPress page
        // `designer_slug` because we assign the first captured regex part to this variable
        'index.php?pagename=designers&designer_slug=$matches[1]',
        // This is a rather specific URL, so we add it to the top of the list
        // Otherwise, the "catch-all" rules at the bottom (for pages and attachments) will "win"
        'top' );
}

Lo único que queda por hacer es decirle a WordPress que también mantenga las designer_slugvariables de consulta, para que pueda acceder más tarde. WordPress utiliza una lista blanca de variables de consulta permitidas, para evitar que las personas modifiquen cada parámetro de la consulta de publicaciones a través de la URL. Todo lo que no está en esta lista se ignora. Simplemente enganche en el query_varsgancho y agregue su variable adicional:

add_filter( 'query_vars', 'wpa5413_query_vars' );
function wpa5413_query_vars( $query_vars )
{
    $query_vars[] = 'designer_slug';
    return $query_vars;
}

Como puede ver, esta respuesta es básicamente la misma que mi respuesta anterior , pero sin la regla en el código (para que pueda usarla en su tema en functions.phplugar de un complemento), y con un poco más de certeza y explicación porque aprendí mucho sobre las reglas de reescritura desde (y debido a) responder su primera pregunta.

Discusión en la sala de chat

Resolvimos problemas finales para esta pregunta en la sala de chat . Al final, Steven usó el generate_rewrite_rulesgancho, porque la add_rewrite_rule()función no parecía funcionar para él.

Jan Fabry
fuente
2
@ Steven: pagenamees el slug de la página de WordPress que desea mostrar (registrar en la base de datos). Esta página puede indicar que quiere usar el designers.phparchivo de plantilla en el área de administración de WP. Entonces, señala la ficha de la página, no el nombre de la plantilla, ya que la misma plantilla se puede usar para varias páginas: en este caso, WordPress no sabe lo que quiere hacer.
Jan Fabry
1
@ Steven: Creo que complica demasiado la forma en que configura los ganchos. Elimina la add_rewrite_rules()función y llama add_filter()/add_action()directamente. Si está en un archivo de tema, elimine el flush_rewrite_rules()y simplemente visite la página de configuración de enlaces permanentes para eliminar las reglas (o agréguelos wpse5413_init()y elimínelos más adelante). Y mi complemento muestra las reglas de reescritura actuales. Recuerde que esto solo cambia la forma en que se manejan las URL entrantes, no cómo su código escribirá las URL en el HTML.
Jan Fabry
1
@ Steven: No creo que tenga que presionar el botón Guardar, solo abrir la página de enlaces permanentes también lo vaciará. Y de nuevo, esto solo agregará la capacidad de WordPress para aceptar /designers/designer-slug/URL, debe cambiar los lugares donde escribe estas URL en su HTML. Pruébelo yendo a /designers/Batlak-og-Selvig/usted mismo, si eso funciona, encuentre todos los lugares que generan estas URL y cámbielas para usar la nueva estructura.
Jan Fabry
1
Ah, ahora creo que estoy empezando a entender. Pensé que las reglas de reescritura cambiarían la forma en que se mostraba la URL en el campo URL de los navegadores. Pero lo que es quiere decir es que tengo que realmente salida de la URL www.mysite.com/batlat-og-selvig/9y entonces esto es "traducido" a/?designer=Batlak-og-Selvig&bid=9
Steven
1
@Steven: Sí, de hecho: las reglas de reescritura manejan los enlaces entrantes y (solo en algunos casos seleccionados) no afectan los enlaces generados en su código.
Jan Fabry