Precisa de ajuda com add_rewrite_rule

55

SOLUÇÃO


Fiz a atualização 3 e a fiz funcionar. O que eu havia entendido errado era que acreditava que uma regra de reescrita mudaria designers/?designer=some-designer&bid=9para /designers/some-designer. Mas é claro que é o contrário.


Estou pesquisando, mas não entendo muito bem como usar add_rewrite_rule () .

Esta postagem está bem próxima do que eu preciso, mas eu realmente preciso de tanto código?

Meu link atual é este:
http://www.norwegianfashion.no/designers/?designer=Batlak-og-Selvig&bid=9
O que eu quero é esse
http://www.norwegianfashion.no/designers/Batlak-og-Selvig /

  1. Como eu uso add_rewrite_rule()?
  2. Preciso passar o ID do designer (lance). Como posso fazer isso ao usar regras de reescrita sem que sejam exibidas no URL?

Atualização 1

Achei isso um pouco mais explicativo. Mas não 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')

Atualização 2

Aqui está outra solução que eu tentei, que Jan Fabry sugeriu em outro tópico. Coloquei isso no meu functions.php, mas não tem efeito.

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

Update 3
I encontrados alguns exemplos aqui também. Mas isso também não está funcionando :(

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

Atualização 4 Eu também tentei esta solução, mas ainda sem sucesso.

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 );

}

Atualização 5
Parece que minhas regras de reescrita não foram adicionadas. Executar o seguinte depois de aplicar novas regras:, print_r($wp_rewrite)não inclui minhas novas regras de reescrita.

Atualização 6
Testei a solução de Jan. Mas o URL não muda :(

/* 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;
}

Eu realmente aprecio isso se alguém puder me ajudar a resolver esse problema.

Steven
fonte
Isso parece muito com a primeira pergunta que você fez aqui e para a qual eu dei uma resposta . A situação mudou desde então, então minha resposta não é mais válida? Se você não deseja o ID do designer no seu URL, precisará converter a "lesma" para o ID, o WordPress não pode fazer isso por você. Os designers ainda são um objeto externo?
Jan Fabry
@ Fabry Jan Sim, eu descobri que depois que eu postei isso (eu tinha esquecido). Agora eu entendo melhor a sua sugestão. Veja meu código atualizado aqui. Meus designers ainda são entradas em um banco de dados personalizado. É possível usar POST insteed og GET para transmitir o bid?
Steven
O uso de uma solicitação POST não funcionará se eu copiar o link e enviá-lo para outra pessoa. É um problema tornar a lesma exclusiva e fazer a pesquisa de dados a partir daí?
Jan Fabry
@ Jan Fabry: Como assim slug? `Recuperar dados do Designer é muito mais fácil de usar biddo quedesigner
Steven

Respostas:

87

Algumas informações sobre regras de reescrita

O sistema WP Rewrite parece complicado, mas na verdade não é tão difícil de entender como ele funciona. É usado para analisar URLs bonitas ( /designers/) como se não fossem bonitas ( /index.php?pagename=designers). A idéia básica é que você tenha uma lista de regras de reescrita , expressões regulares que podem corresponder aos URLs recebidos e reescreva-os em outros URLs, principalmente na forma de index.phpalgumas variáveis ​​de consulta. Essas variáveis ​​são definidas para partes da expressão regular que correspondem à URL. As regras são avaliadas de cima para baixo, portanto, se duas regras corresponderem, a primeira "vence".

Essas regras de reescrita são armazenadas no banco de dados por chamada flush_rewrite_rules(), mas como gerar e escrever essas regras é uma operação cara, você não deve fazer isso em todas as etapas init. Em vez disso, você só o faz quando altera as regras: provavelmente na ativação do plug-in (usando register_activation_hook()) ou manualmente, visitando a página de configurações do Permalinks ( porque é difícil fazer isso automaticamente na ativação do tema ). Se você não liberar as regras, a chamada add_rewrite_rule()não terá efeito. Não há problema em chamar add_rewrite_rule()todos init, mesmo depois de liberar as regras.

Existem várias maneiras de adicionar suas regras de reescrita e, se você quiser adicionar apenas uma regra, poderá fazê-lo add_rewrite_rule(). Porque as regras de posts, páginas, taxonomias, ... resultado em várias regras, elas são criadas com funções de alto nível como add_rewrite_tag(), add_permastruct()... Mas estes não são necessários para o caso simples que temos aqui.

Existem também alguns filtros, para que você também possa adicionar suas regras usando os ganchos generate_rewrite_rulesou generate_rewrite_rules_array. Isso fornece controle muito detalhado sobre as regras completas, mas, novamente, add_rewrite_rule()é suficiente se você quiser apenas adicionar uma regra.

Criei um pequeno plugin que permite analisar as regras de reescrita atuais e (é claro) eu recomendo que você o use quando tentar alterar alguma coisa.

Obtendo suas informações extras do URL

Vamos construir o exemplo que você deu. Você tem a marca de designer Batlak og Selvig, com o ID numérico ( bid) 9. Você não deseja esse ID no URL, mas apenas o nome. Chamamos a versão para URL do nome (sem espaços ou caracteres especiais) a lesma : Batlak-og-Selvig.

Em geral, o URL deve conter todas as informações para identificar o conteúdo que você deseja exibir na página. Você pode usar cookies ou solicitações POST para armazenar o ID de designer real que deseja exibir, mas isso será interrompido se alguém compartilhar o link, enviando-o por correio, Facebook, Twitter ou apenas lendo em voz alta por telefone. Se você não quiser usar o ID numérico no seu URL, verifique se o slug é único: primeiro faça uma pesquisa no ID com base no slug e continue como antes.

Então, o que aprendemos agora é que queremos adicionar uma regra de reescrita para o padrão " /designers/seguido por qualquer coisa até a próxima /" e salvar esse "qualquer coisa" na designer_slugvariável de consulta. No seu caso, acredito que você também deseja usar a página com a lesma designerscomo o conteúdo geral da página, por isso também informaremos o 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' );
}

A única coisa que resta a fazer é dizer ao WordPress para também manter as designer_slugvariáveis ​​de consulta, para que você possa acessá-lo mais tarde. O WordPress usa uma lista de permissões de variáveis ​​de consulta permitidas, para impedir que as pessoas modifiquem todos os parâmetros da consulta de postagens via URL. Tudo o que não está nesta lista é ignorado. Basta conectar o query_varsgancho e adicionar sua variável extra:

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

Como você pode ver, esta resposta é basicamente a mesma que a minha resposta anterior , mas sem a regra de liberação no código (para que você possa usá-lo no tema em functions.phpvez de em um plug-in) e com um pouco mais de certeza e explicação, porque eu aprendi muito sobre reescrever regras desde que (e por causa de) responder à sua primeira pergunta.

Discussão na sala de bate-papo

Resolvemos as questões finais para esta pergunta na sala de bate-papo . No final, Steven usou o generate_rewrite_rulesgancho, porque a add_rewrite_rule()função não parecia funcionar para ele.

Jan Fabry
fonte
2
@Steven: pagenameé a lesma da página do WordPress que você deseja exibir (registro no banco de dados). Esta página pode indicar que deseja usar o designers.phparquivo de modelo na área de administração do WP. Então você aponta para o slug da página, não para o nome do modelo, pois o mesmo modelo pode ser usado para várias páginas: nesse caso, o WordPress não sabe o que você deseja fazer.
Jan Fabry
11
@ Steven: Eu acho que você complica demais a maneira de configurar os ganchos. Remova a add_rewrite_rules()função e ligue add_filter()/add_action()diretamente. Se isso estiver em um arquivo de tema, remova flush_rewrite_rules()e visite a página de configurações de links permanentes para liberar as regras (ou adicione-as wpse5413_init()e remova-as posteriormente). E meu plugin exibe as regras de reescrita atuais. Lembre-se de que isso altera apenas a maneira como os URLs recebidos são manipulados, e não como o seu código gravará os URLs no HTML.
Jan Fabry
11
@ Steven: Eu acho que você nem precisa apertar o botão Salvar, basta abrir a página dos permalinks também para liberá-la. E, novamente, isso adicionará apenas a capacidade do WordPress de aceitar /designers/designer-slug/URLs. Você precisará alterar os locais onde você escreve esses URLs no seu HTML. Teste-o indo para /designers/Batlak-og-Selvig/si mesmo, se isso funcionar, encontre todos os locais que geram esses URLs e altere-os para usar a nova estrutura.
Jan Fabry
11
Ah, agora acho que estou começando a entender. Eu pensei que as regras de reescrita mudariam a forma como a URL foi exibida no campo URL dos navegadores. Mas o que isso significa é que eu tenho que realmente enviar a URL www.mysite.com/batlat-og-selvig/9e isso é "traduzido" para/?designer=Batlak-og-Selvig&bid=9
Steven
11
@ Steven: Sim, de fato: as regras de reescrita lidam com os links recebidos e (apenas em alguns casos selecionados) não afetam os links gerados no seu código.
Jan Fabry