¿Necesita ayuda con add_rewrite_rule

52

SOLUCIÓN

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

He estado haciendo algunas investigaciones, pero no entiendo bien 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:
enlace
Lo que quiero es esto
enlace

  1. ¿Cómo 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 muestren 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 sugerencia de Jan Fabry en otro hilo. Pongo esto en mi functions.php, pero no tiene 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 tengo é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 están agregadas. Ejecutar las siguientes reglas nuevas de seguimiento: 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;
}

Realmente agradecería que alguien me ayudara a resolver este problema.

    
pregunta Steven 13.04.2017 - 14:37

1 respuesta

85

Algunos antecedentes sobre las reglas de reescritura

El sistema WP Rewrite parece complicado, pero en realidad no es tan difícil entender cómo funciona. Se utiliza para analizar las 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 las reescribe en otras URL, principalmente en forma de index.php con algunas variables de consulta. Estas variables se configuran en partes de la expresión regular que coinciden con la URL. Las reglas se evalúan de arriba a abajo, por lo que si dos reglas pueden coincidir, la primera "gana".

Estas reglas de reescritura se almacenan en la base de datos llamando a flush_rewrite_rules() , pero como generar y escribir estas reglas es una operación costosa, no debe hacerlo en cada init . En su lugar, 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 hacer esto automáticamente en la activación del tema ). Si no borras las reglas, llamar a add_rewrite_rule() no tiene efecto. No es un problema llamar a add_rewrite_rule() en cada 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 para publicaciones, páginas, taxonomías, ... resultan en reglas múltiples, se crean con funciones de alto nivel como add_rewrite_tag() , add_permastruct() , ... Pero estas no son necesarias para el caso simple que tenemos aquí.

También hay algunos filtros, por lo que también puedes agregar tus reglas usando los enlaces generate_rewrite_rules o generate_rewrite_rules_array . Esto le da 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 te permite analizar las reglas de reescritura actuales y (por supuesto) te recomiendo que lo utilices cuando intentas cambiar algo.

Obteniendo su información adicional de la URL

Vamos a construir sobre el ejemplo que dio. Tiene la marca de diseñador Batlak og Selvig , con el ID numérico ( bid ) 9 . No desea esta ID en la URL, solo el nombre. Llamamos a la versión del nombre compatible con URL (sin espacios ni caracteres especiales) la slug : 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 del 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 la ID numérica en su URL, debe asegurarse de que la bala sea única: primero debe hacer una búsqueda de la ID en función de la bala y continuar 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 eso "cualquier cosa" en la variable de consulta designer_slug . En su caso, creo que también desea utilizar la página con el slug designers como 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 el designer_slug en las variables de consulta, para que pueda acceder a él más tarde. WordPress utiliza una lista blanca de variables de consulta permitidas, para evitar que las personas modifiquen todos los parámetros 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 gancho query_vars 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 que borra el código (para que pueda usarlo en functions.php de su tema en lugar 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 a su primera pregunta.

Discusión en la sala de chat

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

    
respondido por el Jan Fabry 16.12.2010 - 11:07

Lea otras preguntas en las etiquetas