Potrzebujesz pomocy z add_rewrite_rule


55

ROZWIĄZANIE


Poszedłem z aktualizacją 3 i mam ją uruchomioną. To, co źle zrozumiałem, to to, że wierzyłem, że reguła przepisywania zmieni się designers/?designer=some-designer&bid=9na /designers/some-designer. Ale oczywiście jest na odwrót.


Przeprowadziłem badania, ale nie do końca rozumiem, jak korzystać z add_rewrite_rule () .

Ten post jest dość blisko tego, czego potrzebuję, ale czy naprawdę potrzebuję tyle kodu?

Mój aktualny link to:
http://www.norwegianfashion.no/designers/?designer=Batlak-og-Selvig&bid=9
Chcę tego
http://www.norwegianfashion.no/designers/Batlak-og-Selvig /

  1. Jak korzystać add_rewrite_rule()?
  2. Muszę przekazać identyfikator projektanta (ofertę). Jak mogę to zrobić, używając reguł re.write bez wyświetlania go w adresie URL?

Aktualizacja 1

Znalazłem to, co jest nieco bardziej wyjaśniające. Ale to nie działa:

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

Aktualizacja 2

Oto inne rozwiązanie, które wypróbowałem, które Jan Fabry zasugerował w innym wątku. Umieszczam to w moim functions.php, ale to nie ma efektu.

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 znalazłem kilka przykładów tutaj również. Ale to też nie działa :(

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

Aktualizacja 4 Próbowałem również tego rozwiązania, ale nadal nie powiodło się.

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

}

Aktualizacja 5
Wygląda na to, że moje reguły przepisywania nie zostały dodane. Wykonanie następujących reguł po nowych regułach:, print_r($wp_rewrite)nie obejmuje moich nowych reguł przepisywania.

Aktualizacja 6
Przetestowałem rozwiązanie Jana. Ale URL się nie zmienia :(

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

Byłbym bardzo wdzięczny, gdyby ktoś był w stanie pomóc mi rozwiązać ten problem.


Wygląda to bardzo podobnie do pierwszego pytania, które tu zadałeś i na które dałem odpowiedź . Czy sytuacja zmieniła się od tego czasu, więc moja odpowiedź nie jest już aktualna? Jeśli nie chcesz identyfikatora projektanta w swoim adresie URL, musisz przekonwertować „ślimak” na identyfikator, WordPress nie może zrobić tego za Ciebie. Czy projektanci wciąż są obiektem zewnętrznym?
Jan Fabry,

@Jan Fabry Tak, odkryłem, że po tym, jak to opublikowałem (zapomniałem). Teraz lepiej rozumiem twoją sugestię. Zobacz mój zaktualizowany kod tutaj. Moi projektanci wciąż są wpisami do niestandardowej bazy danych. Czy można użyć funkcji POST insteed og GET, aby przekazać dalej bid?
Steven

Korzystanie z żądania POST nie będzie działać, jeśli skopiuję link i wyślę go komuś innemu. Czy sprawienie, by ślimak był unikalny i czy wyszukiwanie danych stamtąd było problemem?
Jan Fabry,

@Jan Fabry: Co masz na myśli slug? `Odzyskiwanie danych projektanta jest o wiele łatwiejsze przy użyciu bidniżdesigner
Steven

Odpowiedzi:


87

Niektóre informacje o przepisywaniu reguł

System WP Rewrite wygląda na skomplikowany, ale tak naprawdę nie jest tak trudno zrozumieć, jak działa. Służy do analizowania ładnych adresów URL ( /designers/) tak, jakby były nie-ładne ( /index.php?pagename=designers). Podstawową ideą jest to, że masz listę reguł przepisywania , wyrażeń regularnych, które mogą pasować do przychodzących adresów URL, i przepisuj je na inne adresy URL, głównie w postaci index.phpniektórych zmiennych zapytań. Te zmienne są ustawione na części wyrażenia regularnego, które pasują do adresu URL. Reguły są oceniane od góry do dołu, więc jeśli dwie reguły mogą się zgadzać, pierwsza „wygrywa”.

Te reguły przepisywania są przechowywane w bazie danych przez wywołanie flush_rewrite_rules(), ale ponieważ generowanie i pisanie tych reguł jest kosztowną operacją, nie powinieneś robić tego za każdym razem init. Zamiast tego robisz to tylko wtedy, gdy zmieniasz reguły: prawdopodobnie przy aktywacji wtyczki (przy użyciu register_activation_hook()) lub ręcznie, odwiedzając stronę ustawień Permalinks ( ponieważ trudno jest to zrobić automatycznie przy aktywacji motywu ). Jeśli nie opróżnisz reguł, sprawdzanie add_rewrite_rule()nie ma żadnego efektu. Nie ma problemu z wzywaniem add_rewrite_rule()każdego init, nawet po wyczyszczeniu zasad.

Istnieje wiele sposobów dodawania reguł przepisywania, a jeśli chcesz dodać tylko jedną regułę, możesz to zrobić add_rewrite_rule(). Ponieważ przepisy dotyczące postów, stron, taksonomii, ... skutkować wieloma przepisami, są one tworzone z funkcjami wysokiego poziomu jak add_rewrite_tag(), add_permastruct()... Ale nie są one potrzebne do prostego przypadku mamy tutaj.

Istnieje również kilka filtrów, więc możesz również dodawać reguły za pomocą haczyków generate_rewrite_ruleslub generate_rewrite_rules_array. Dają one bardzo szczegółową kontrolę nad kompletnymi regułami, ale znowu add_rewrite_rule()wystarczy, jeśli chcesz tylko dodać jedną regułę.

Stworzyłem małą wtyczkę, która pozwala analizować bieżące reguły przepisywania i (oczywiście) zalecam korzystanie z niej, gdy próbujesz coś zmienić.

Uzyskiwanie dodatkowych informacji z adresu URL

Oprzyjmy się na podanym przykładzie. Masz markową markę Batlak og Selvigz numerycznym identyfikatorem ( bid) 9. Nie chcesz tego identyfikatora w adresie URL, a tylko nazwę. Nazywamy wersję URL przyjazne nazwy (bez spacji lub znaków specjalnych) do ślimaka : Batlak-og-Selvig.

Ogólnie adres URL powinien zawierać wszystkie informacje umożliwiające identyfikację treści, które chcesz wyświetlić na stronie. Możesz użyć plików cookie lub żądań POST do przechowywania rzeczywistego identyfikatora projektanta, który chcesz wyświetlić, ale to się zepsuje, jeśli ktoś udostępni link, wysyłając go pocztą, na Facebooku, Twitterze lub po prostu czytając go na głos przez telefon. Jeśli nie chcesz używać identyfikatora numerycznego w adresie URL, powinieneś upewnić się, że ślimak jest unikalny: najpierw najpierw sprawdź identyfikator na podstawie ślimaka i kontynuuj, jak wcześniej.

Nauczyliśmy się teraz, że chcemy dodać regułę przepisywania dla wzorca /designers/po którym następuje cokolwiek do następnego / i zapisać to „cokolwiek” w designer_slugzmiennej zapytania. W twoim przypadku uważam, że chcesz również użyć strony ze ślimakiem designersjako ogólnej zawartości strony, więc powiemy to również 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' );
}

Jedyne, co pozostało do zrobienia, to powiedzieć WordPressowi, aby zachowywał również designer_slugzmienne zapytania, aby można było uzyskać do niego dostęp później. WordPress używa białej listy dozwolonych zmiennych zapytań, aby uniemożliwić modyfikowanie każdego parametru zapytania postów za pomocą adresu URL. Wszystko, czego nie ma na tej liście, jest ignorowane. Wystarczy zaczepić query_varshak i dodać swoją dodatkową zmienną:

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

Jak widać, ta odpowiedź jest w zasadzie taka sama, jak moja poprzednia odpowiedź , ale bez reguły opróżniania kodu w kodzie (dzięki czemu można go używać w motywie functions.phpzamiast wtyczki) oraz z nieco większą pewnością i wyjaśnieniem, ponieważ nauczyłem się dużo o przepisywaniu reguł od (i z powodu) odpowiedzi na twoje pierwsze pytanie.

Dyskusja na czacie

Ostateczne problemy dotyczące tego pytania wyjaśniliśmy na czacie . Ostatecznie Steven użył generate_rewrite_ruleshaka, ponieważ ta add_rewrite_rule()funkcja nie działała dla niego.


2
@Steven: pagenameto informacja o stronie WordPress, którą chcesz wyświetlić (nagrać w bazie danych). Ta strona może następnie wskazać, że chce użyć designers.phppliku szablonu w obszarze administracyjnym WP. Wskazujesz więc informacje o stronie, a nie nazwę szablonu, ponieważ ten sam szablon może być używany na wielu stronach: w tym przypadku WordPress nie wie, co chcesz zrobić.
Jan Fabry,

1
@Steven: Myślę, że nadmiernie komplikujesz sposób ustawiania haków. Usuń add_rewrite_rules()funkcję i zadzwoń add_filter()/add_action()bezpośrednio. Jeśli jest to plik motywu, usuń flush_rewrite_rules()i po prostu odwiedź stronę ustawień permalinks, aby opróżnić reguły (lub dodaj je wpse5413_init()i usuń później). A moja wtyczka wyświetla aktualne reguły przepisywania. Pamiętaj, że zmienia to tylko sposób obsługi przychodzących adresów URL, a nie sposób, w jaki kod będzie zapisywać adresy URL w kodzie HTML.
Jan Fabry,

1
@Steven: Nie sądzę, że musisz nawet nacisnąć przycisk zapisywania, samo otwarcie strony permalinks również ją opróżni. I znowu, to tylko doda możliwość akceptowania /designers/designer-slug/adresów URL przez WordPress , musisz sam zmienić miejsca, w których piszesz te adresy URL w swoim HTML. Przetestuj to, przechodząc do /designers/Batlak-og-Selvig/siebie, jeśli to zadziała, znajdź wszystkie miejsca, które generują te adresy URL i zmień je, aby korzystały z nowej struktury.
Jan Fabry

1
Ach, teraz myślę, że zaczynam udnerstand. Myślałem, że reguły przepisywania zmieniłyby sposób wyświetlania adresu URL w polu adresu URL przeglądarki. Ale oznacza to, że muszę wyprowadzić adres URL, www.mysite.com/batlat-og-selvig/9a następnie jest on „przetłumaczony” na/?designer=Batlak-og-Selvig&bid=9
Steven

1
@Steven: Tak, rzeczywiście: reguły przepisywania obsługują linki przychodzące i (tylko w kilku wybranych przypadkach) nie wpływają na generowane linki w kodzie.
Jan Fabry
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.