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

Fran
źródło

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.

eddiemoya
źródło
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' ) );
Matt Keys
źródło
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