WordPress

tworzenie wtyczek – Dynamiczne dodawanie reguły przepisywania

  • 14 stycznia, 2022
  • 3 min read
tworzenie wtyczek – Dynamiczne dodawanie reguły przepisywania


Problem ze zaktualizowanym kodem polega na tym, że używasz add_rewrite_rule() wewnątrz filtra, nie może poprawnie dodać go na górę listy. Możesz to zobaczyć, jeśli zrzucisz plik $rules szyk. Ponieważ jest dodawany na końcu pliku $rules list, WP wkracza wcześniej, aby dopasować się do samego ślimaka, używając magii w tle.

Aby obejść ten proces, musisz ręcznie dodać go na górę listy i zwrócić go z filtra.

Konkretnie musisz zmienić add_rewrite_rule() zadzwoń do tego:

$rules = [$new_src => $new_dest] + $rules;

Poniżej zamieściłem pełny zaktualizowany kod.

add_filter('rewrite_rules_array', function($rules) {

    $slug = 'foo';

    // get the request URI
    $uri = $_SERVER['REQUEST_URI'];
    
    // determine whether URI has slug in the first position
    if(preg_match('/^(\/' . $slug . ')/', $uri)){

        // get the base URI by removing the slug
        $base_uri = str_replace("

        // loop through existing rewrite rules
        foreach($rules as $src => $dest){

            // find the rewrite rule for which the base URI would have matched
            $regex_to_match=" . str_replace(",'\/',$src) . ";
            
            preg_match_all($regex_to_match, $base_uri, $matches, PREG_SET_ORDER);


            if(count($matches) > 0){

                // get the specific matching groups
                $matches = $matches[0]; 

                // compile valid regex from URI with slug to create new rewrite source
                $new_src = ($uri[0] == " ? substr($uri, 1) : $uri) . '?$';
                
                // replace match variables with their string values to create new rewrite destination
                for($i=1; $i<count($matches)+1; $i++){
                    $replacement = isset($matches[$i]) ? $matches[$i] : '';
                    $replacement = strpos($replacement, ") === 0 ? substr($replacement, 1) : $replacement;
                    $dest = str_replace('$matches[' . $i . ']', $replacement, $dest);
                }
                $new_dest = $dest;

                // add new rewrite rule to $wp_rewrite rules array
                $rules = [$new_src => $new_dest] + $rules;

                break;
            }
        }
    }

    

    return $rules;

});

Nadal wydaje się to dziwnym sposobem robienia tego i jestem pewien, że istnieje lepszy, ale bez lepszego zrozumienia twojego przypadku użycia nie mogę tak naprawdę podać alternatywnej sugestii. Największym problemem dla mnie jest to, że opróżniasz reguły przepisywania przy każdym żądaniu, co może być kosztowną operacją.

Warto przeczytać!  przekierowanie — Jak zmienić domyślny link do wylogowania w administratorze WordPress

Oryginalna odpowiedź

ja bym się nie przyczepił generate_rewrite_rules dla tego. Możesz po prostu użyć zwykłego interfejsu API reguł przepisywania.

Przetestowałem poniższe i działa w przypadku przekierowania do Można dostosować go do swoich potrzeb. Upuść go w functions.php lub wtyczce funkcjonalności.

add_action( 'init',  function() {
    add_rewrite_rule( 'foo/([a-z0-9-/]+)[/]?$', 'index.php?foo_redirect_to=$matches[1]', 'top' );
} );

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

add_action('template_redirect', function() {
    if ( ( $redirect_to = get_query_var( 'foo_redirect_to' ) ) == false ) {
        return;
    }

    wp_redirect("
});


Źródło