Спеціальний маршрут плагіна в Wordpress


12

Гаразд, моє запитання досить просте. Мені потрібно реалізувати деякі власні правила маршрутизації для мого плагіна. Ці маршрути брали б лише один аргумент (так нічого складного) і виглядали б так: http://www.example.org/myroute/myargument

І в ідеалі це буде викликати користувацький клас та відображати користувацький шаблон (який міг би безпосередньо мати доступ до класу).

Який найкращий підхід для цього? Ура

Відповіді:


15

Вам потрібно зробити три важливі речі:

  1. Створіть спеціальне правило перезапису, щоб перетворити частини URI у значення, передані index.php.
  2. Додати myrouteі myargumentв змінних запиту WordPress в білий список, так що WordPress не просто ігнорувати їх , коли вони з'являються в рядку запиту.
  3. Скиньте правила перезапису.

По-перше, я порекомендую замість цього http://www.example.org/myroute/myargumentвстановити якийсь спеціальний префікс або суфікс, щоб позначити, коли URI слід вважати одним із цих спеціальних "маршрутів". Заради цього прикладу я вибрав префікс api, щоб він був http://www.example.org/api/myroute/myargument. Я вибрав це apiтому, що коли я робив щось ВИПУСКЕ, як те, над чим ти працюєш, це було для API.

Кодекс

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

Швидка поломка

Це все досить прямо вперед. Шаблон регулярного вираження додається до списку всіх правил перезапису в WordPress, а ваш власний шаблон знаходиться у верхній частині списку. Коли узор збігається, WordPress перестане переглядати список правил перезапису та використовуватиме захоплені значення regex замість посилань ( $matches[1]та $matches[2]) у рядку запиту, переданому до index.php.

Додавання змінних запитів myrouteта myargumentбілого списку просто змушує WordPress звертати на них увагу, а не відкидати їх.

Альтернативний спосіб "простору імен" вашого власного маршруту

Якщо ви хочете уникати використання /api/в якості префікса, замість цього ви можете використовувати змінну / поле рядка запиту. Щоб зробити щось подібне, ви змінили б регулярний вираз на щось подібне, (.*?)/(.+?)\\?api=1а потім додали apiяк додатковий параметр до array_push()дзвінка, здійсненого в my_insert_query_vars().

Це змінило б спеціальний маршрут, щоб він в будь-який момент api=1запускав перший елемент рядка запиту, наприклад, він запустив би http://example.com/anytext/anytext?api=1.

Ігноруйте вживання терміна "простір імен" - щойно використав його для стислості.

Якщо ви не 'простору імен' не будете мати ні префікс, ні суфікс, ви зіткнетеся з шаблонами URI. Це тому, що WordPress не зможе відрізнити вашу власну модель від тієї, яка призначена для публікації чи сторінки. Як WordPress дізнається, що myrouteце не таксономія, термін чи батьківська сторінка?

Сподіваюсь, це допомагає.


1
Зручна примітка: правила, визначені у my_insert_rewrite_rulesпорядку визначення! Почніть спочатку з найдовшого правила, а потім перейдіть до найпростішого, інакше / api / myroute перекриє / api / myroute / myargument.
emc

1
@npc Це важливий момент, про який слід пам’ятати, створюючи власні правила перезапису, вони теж можуть зіткнутися. У наведеному вище прикладі, це не проблема, оскільки / api / myroute просто не буде дійсним шляхом.
eddiemoya

Як хтось може завантажувати користувацький шаблон зі свого каталогу плагінів, коли на сторінку example.org/api/myroute/myargument запитується?
Метт Кіс

1
Ось актуальне та повне рішення wordpress: codex.wordpress.org/Rewrite_API/add_rewrite_rule
Імран

6

Щоб трохи розширити те, що зробив вище Eddiemoya:

Як і в оригінальному плакаті цього питання, я хотів створити власну переписати, а також доставити спеціальний шаблон для цієї сторінки для перезапису. Код від edditmoya запустив мене в правильному напрямку, і я додав додаткову функцію для обслуговування мого користувальницького шаблону, коли доступ до сторінки.

Спеціальний шаблон може бути розміщений у будь-якому місці, в моєму випадку він зберігається в каталозі плагінів.

Я також хотів лише перевірити, чи потрібно переписати правила перезапису під час активації плагіна, тому я ставлю це на register_activation_hook

Нижче див. Повний приклад того, що я зробив:

ОНОВЛЕНО спрощене на основі порад від 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
ви також можете просто скористатися add_rewrite_endpoint, що сформує для вас правило і додасть вар запитів за один раз. також якщо ви додаєте власні правила перезапису, я пропоную add_rewrite_ruleфункцію замість фільтрування rewrite_rules_array.
Міло,

Дякую Міло, я оновив код, щоб використовувати add_rewrite_rule замість фільтрації масиву переписати. Я переглянув add_rewrite_endpoint, але думаю, що add_rewrite_tag може бути найкращим чином підходить для моїх потреб. Здається, що add_rewrite_endpoint в основному корисний, якщо ви хочете додати додатковий аргумент до існуючих перезаписів WP. Виправте мене, якщо я тут помиляюся.
Метт Кіс

1
Мені подобається об’єктно-орієнтований підхід. Забагато розробників WP досі не знають, як користуватися OOP. Дякуємо за спробу відновити мою віру в розробників PHP. ;)
Арвід
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.