Niestandardowa trasa wtyczek w Wordpress


12

Okej, więc moje pytanie jest dość proste. Muszę zaimplementować niestandardowe reguły routingu dla mojej wtyczki. Te trasy wymagałyby tylko jednego argumentu (więc nic skomplikowanego) i wyglądałyby tak: http://www.example.org/myroute/myargument

Idealnie byłoby to wywołać klasę niestandardową i wyświetlić szablon niestandardowy (który mógłby bezpośrednio uzyskać dostęp do klasy).

Jakie jest najlepsze podejście do tego? Twoje zdrowie

Odpowiedzi:


15

Musisz zrobić trzy ważne rzeczy:

  1. Utwórz niestandardową regułę przepisywania, aby przekształcić części identyfikatora URI w przekazywane wartości index.php.
  2. Dodaj myroutei myargumentdo białej listy zmiennych zapytań WordPress, aby WordPress nie tylko je ignorował, gdy pojawiają się w ciągu zapytania.
  3. Opróżnij reguły przepisywania.

Po pierwsze, zalecam, aby zamiast tego http://www.example.org/myroute/myargumentzdecydować się na jakiś specjalny prefiks lub sufiks, aby określić, kiedy URI należy uznać za jedną z tych specjalnych „tras”. Na potrzeby tego przykładu wybrałem prefiks api, aby był http://www.example.org/api/myroute/myargument. Wybrałem, apiponieważ kiedy zrobiłem coś RESTful, na przykład nad czym wydaje się, że pracujesz, było to dla API.

Kod

add_filter( 'rewrite_rules_array', 'my_insert_rewrite_rules' );
add_filter( 'query_vars', 'my_insert_query_vars' );
add_action( 'wp_loaded', 'my_flush_rules' );

// flush_rules() if our rules are not yet included
function my_flush_rules() {
    $rules = get_option( 'rewrite_rules' );

    if ( ! isset( $rules['api/(.*?)/(.+?)'] ) ) {
        global $wp_rewrite;
        $wp_rewrite->flush_rules();
    }
}

// Adding a new rule
function my_insert_rewrite_rules( $rules ) {
    $newrules = array();
    $newrules['api/(.*?)/(.+?)'] = 'index.php?myroute=$matches[1]&myargument=$matches[2]';
    return $newrules + $rules;
}

// Adding the id var so that WP recognizes it
function my_insert_query_vars( $vars ) {
    array_push( $vars, 'myroute', 'myargument' );
    return $vars;
}

Szybki podział

Wszystko jest dość proste. Wzorzec wyrażenia regularnego jest dodawany do listy wszystkich reguł przepisywania w WordPress, a Twój wzorzec niestandardowy znajduje się na górze listy. Po dopasowaniu wzorca WordPress przestanie przeglądać listę reguł przepisywania i użyje przechwyconych wartości wyrażenia regularnego zamiast odwołań ( $matches[1]i $matches[2]) w przekazanym ciągu zapytania index.php.

Dodanie zmiennych zapytania myroutei myargumentdo białej listy sprawia, że ​​WordPress zwraca na nie uwagę, a nie odrzuca je.

Alternatywny sposób „przestrzeni nazw” na trasie niestandardowej

Jeśli chcesz uniknąć używania /api/jako prefiksu, możesz zamiast tego użyć zmiennej ciąg / zapytanie zapytania. Aby zrobić coś takiego, należy zmienić wyrażenie regularne na coś podobnego, (.*?)/(.+?)\\?api=1a następnie dodać apijako dodatkowy parametr do array_push()wywołanego wywołania my_insert_query_vars().

To zmieniłoby niestandardową trasę, tak aby api=1wyzwalała się w dowolnym momencie, jest pierwszym elementem ciągu zapytania, np. Uruchamiałaby się http://example.com/anytext/anytext?api=1.

Zignoruj ​​użycie terminu „przestrzeń nazw” - po prostu użyłem go dla zwięzłości.

Jeśli nie „przestrzeń nazw” będzie zawierać ani prefiks, ani sufiks, skończy się to kolidowaniem wzorców URI. Wynika to z faktu, że WordPress nie będzie w stanie odróżnić niestandardowego wzorca od wzoru przeznaczonego na post lub stronę. Skąd WordPress miałby wiedzieć, że myroutenie jest to taksonomia, termin ani strona nadrzędna?

Mam nadzieję że to pomoże.


1
Przydatna uwaga: reguły zdefiniowane my_insert_rewrite_ruleszgodnie z kolejnością definicji! Najpierw zacznij od najdłuższej reguły, a następnie przejdź do najprostszej, w przeciwnym razie / api / myroute zastąpi / api / myroute / myargument.
emc

1
@npc Jest to ważna kwestia, o której należy pamiętać, tworząc niestandardowe reguły przepisywania, mogą one również kolidować w ten sposób. W powyższym przykładzie nie stanowi to problemu, ponieważ / api / myroute po prostu nie byłaby prawidłową ścieżką.
eddiemoya,

Jak ktoś może załadować niestandardowy szablon z katalogu wtyczek, ilekroć zażądano strony example.org/api/myroute/myargument ?
Matt Keys,

1
Oto aktualne i kompletne rozwiązanie wordpress: codex.wordpress.org/Rewrite_API/add_rewrite_rule
Imran Zahoor

6

Aby rozwinąć nieco to, co eddiemoya zrobiło powyżej:

Podobnie jak oryginalny plakat tego pytania, chciałem utworzyć niestandardowe przepisywanie, a także dostarczyć niestandardowy szablon dla tej strony przepisywania. Kod z edditmoya pomógł mi zacząć w dobrym kierunku i dodałem dodatkową funkcję do obsługi mojego niestandardowego szablonu po wejściu na stronę.

Szablon niestandardowy może znajdować się w dowolnym miejscu, w moim przypadku jest przechowywany w katalogu wtyczek.

Chciałem też tylko sprawdzić, czy reguły przepisywania muszą zostać wyczyszczone podczas aktywacji wtyczki, więc umieściłem to na haku register_activation_hook

Zobacz poniżej pełny przykład tego, co zrobiłem:

AKTUALIZACJA uproszczona w oparciu o porady od milo

class Your_Class
{

    public function init()
    {
        add_filter( 'template_include', array( $this, 'include_template' ) );
        add_filter( 'init', array( $this, 'rewrite_rules' ) );
    }

    public function include_template( $template )
    {
        //try and get the query var we registered in our query_vars() function
        $account_page = get_query_var( 'account_page' );

        //if the query var has data, we must be on the right page, load our custom template
        if ( $account_page ) {
            return PATH_TO_PLUGIN_TEMPLATES_DIR . 'register.php';
        }

        return $template;
    }

    public function flush_rules()
    {
        $this->rewrite_rules();

        flush_rewrite_rules();
    }

    public function rewrite_rules()
    {
        add_rewrite_rule( 'account/(.+?)/?$', 'index.php?account_page=$matches[1]', 'top');
        add_rewrite_tag( '%account_page%', '([^&]+)' );
    }

}

add_action( 'plugins_loaded', array( new Your_Class, 'init' ) );

// One time activation functions
register_activation_hook( PATH_TO_PLUGIN_FILE, array( new Your_Class, 'flush_rules' ) );

1
możesz także użyć add_rewrite_endpoint, który wygeneruje regułę i doda zapytanie var za jednym razem. także jeśli dodajesz własne reguły przepisywania, sugeruję add_rewrite_rulefunkcję zamiast filtrowania rewrite_rules_array.
Milo

Dzięki Milo, zaktualizowałem kod, aby używał add_rewrite_rule zamiast filtrować tablicę przepisywania. Patrzyłem na add_rewrite_endpoint, ale myślę, że add_rewrite_tag może lepiej pasować do moich potrzeb. Wygląda na to, że add_rewrite_endpoint jest najbardziej użyteczny, jeśli chcesz dodać dodatkowy argument do istniejących zapisów WP. Popraw mnie, jeśli się tu mylę.
Matt Keys

1
Lubię podejście obiektowe. Zbyt wielu programistów WP wciąż nie wie, jak korzystać z OOP. Dzięki za próbę przywrócenia mojej wiary programistom PHP. ;)
Arvid
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.