Потрібна допомога з add_rewrite_rule


55

РІШЕННЯ


Я пішов з оновленням 3, і він працював. Те , що я зрозумів, було те , що я вважав , що правило переписування зміниться designers/?designer=some-designer&bid=9на /designers/some-designer. Але це, звичайно, навпаки.


Я займався деякими дослідженнями, але мені не зовсім зрозуміло, як використовувати add_rewrite_rule () .

Ця публікація досить близька до того, що мені потрібно, але чи дійсно мені потрібен стільки код?

Моє поточне посилання таке:
http://www.norwegianfashion.no/designers/?designer=Batlak-og-Selvig&bid=9
Я хочу це
http://www.norwegianfashion.no/designers/Batlak-og-Selvig /

  1. Як я можу використовувати add_rewrite_rule()?
  2. Мені потрібно здати ідентифікатор дизайнера (ставка). Як я можу це зробити при використанні правил перезапису, відображаючи його в URL-адресі?

Оновлення 1

Я знайшов це, що є трохи більш пояснювальним. Але це не працює:

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

Оновлення 2

Ось ще одне рішення, яке я спробував, що Ян Фабрі запропонував в іншій темі. Я ставлю це до своїх функцій.php, але це не має ефекту.

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

Оновлення 3
Я також знайшов кілька прикладів тут . Але це також не працює :(

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

Оновлення 4 Я також спробував це рішення, але успіху все ще не було.

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

}

Оновлення 5
Схоже, мої правила перезапису не додані. Виконання наступних правил після написання нових правил:, print_r($wp_rewrite)не включає мої нові правила перезапису.

Оновлення 6
Я перевірив рішення Яна. Але URL-адреса не змінюється :(

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

Я дуже вдячний, якби хтось зміг допомогти мені вирішити це питання.


Це дуже схоже на перше питання, яке ви тут задали, і на яке я дав відповідь . Чи змінилася ситуація з тих пір, тому моя відповідь вже не дійсна? Якщо ви не хочете ідентифікатора дизайнера у своїй URL-адресі, вам потрібно буде самостійно перетворити "кулі" в ідентифікатор, WordPress не може зробити це за вас. Чи дизайнери все ще є зовнішнім об’єктом?
Ян Фабрі

@Jan Fabry Так, я виявив, що опублікував це (забув). Тепер я краще розумію ваші пропозиції. Дивіться мій оновлений код тут. Мої дизайнери все ще входять у користувацьку БД. Чи можливо за допомогою POST, знятого та GET, щоб пройти уздовж bid?
Стівен

Використання запиту POST не буде загрожує, якщо я скопіюю посилання та надішлю його комусь іншому. Чи є проблема зробити слизову унікальною та зробити пошук даних звідти?
Ян Фабрі

@Jan Fabry: Що ти маєш на увазі під собою slug? `Отримати дані дизайнера набагато простіше за допомогою bid, ніжdesigner
Стівен

Відповіді:


87

Деякі відомості про правила перезапису

Система WP Rewrite виглядає складною, але насправді не так складно зрозуміти, як вона працює. Він використовується для аналізу симпатичних URL-адрес ( /designers/), як ніби вони не дуже ( /index.php?pagename=designers). Основна ідея полягає у тому, що у вас є список правил перезапису , регулярні вирази, які можуть відповідати вхідним URL-адресам, і переписувати їх на інші URL-адреси, переважно у вигляді index.phpзмінних запитів. Ці змінні встановлені на частини регулярного виразу, які відповідають URL-адресі. Правила оцінюються зверху вниз, тож якщо два правила можуть збігатися, перше "виграє".

Ці правила перезапису зберігаються в базі даних за допомогою виклику flush_rewrite_rules(), але оскільки створення та запис цих правил - це дорога операція, не слід робити це на кожному init. Натомість ви робите це лише при зміні правил: можливо, під час активації плагіну (використання register_activation_hook()) або вручну, відвідавши сторінку налаштувань Постійних посилань ( оскільки важко зробити це автоматично під час активації теми ). Якщо ви не add_rewrite_rule()дотримуєтесь правил, дзвінок не впливає. Не проблема зателефонувати add_rewrite_rule()на кожного init, навіть після того, як ви пропрасували правила.

Існує багато способів додати свої правила перезапису, і якщо ви хочете додати лише одне правило, ви можете це зробити add_rewrite_rule(). Оскільки правила для повідомлень, сторінок, таксономії ... привести кількох правил, вони створені з функціями високого рівня як add_rewrite_tag(), add_permastruct()... Але вони не потрібні для простого випадку ми маємо тут.

Також є кілька фільтрів, тому ви також можете додати свої правила за допомогою гачків generate_rewrite_rulesабо generate_rewrite_rules_array. Вони дають вам дуже детальний контроль над повними правилами, але знову ж таки, add_rewrite_rule()достатньо, якщо ви просто хочете додати одне правило.

Я створив невеликий плагін, який дозволяє проаналізувати поточні правила перезапису , і (звичайно) рекомендую використовувати його, коли ви намагаєтесь щось змінити.

Отримання додаткової інформації з URL-адреси

Давайте побудуємо на прикладі, який ви дали. У вас є бренд дизайнера Batlak og Selvigз цифровим ідентифікатором ( bid) 9. Ви не хочете цього ідентифікатора в URL-адресі, а лише ім'я. Ми називаємо URL-дружній варіант назви (без пробілів і спеціальних символів) на слимака : Batlak-og-Selvig.

Загалом, URL-адреса повинна містити всю інформацію, щоб визначити вміст, який ви хочете показати на сторінці. Ви можете використовувати файли cookie або POST-запити для зберігання фактичного ідентифікатора дизайнера, який ви хочете відобразити, але це вийде з ладу, якщо хтось поділиться посиланням, надіславши його поштою, Facebook, Twitter або просто прочитавши його вголос по телефону. Якщо ви не хочете використовувати числовий ідентифікатор у своїй URL-адресі, ви повинні переконатися, що куля унікальна: тоді спочатку робіть пошук ідентифікатора на основі слизи, і продовжуйте так, як ви робили раніше.

Тож, про що ми дізналися зараз, це те, що ми хочемо додати правило перезапису для шаблону /designers/наступним чим завгодно до наступного /" і зберегти це "все" у designer_slugзмінній запиту. У вашому випадку я вважаю, що ви також хочете використовувати сторінку зі слизом designersяк загальний вміст сторінки, тому ми скажемо і 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' );
}

Залишилося лише сказати WordPress також зберігати designer_slugзмінні запиту, щоб ви могли отримати доступ до нього пізніше. WordPress використовує білий список дозволених змінних запитів, щоб не дозволяти людям змінювати кожен параметр запиту публікацій за допомогою URL-адреси. Все, що не в цьому списку, ігнорується. Просто підключіть query_varsгачок і додайте додаткову змінну:

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

Як бачите, ця відповідь в основному така ж, як і в попередній моїй відповіді , але без правила прошивки в коді (так що ви можете використовувати її в темі functions.phpзамість плагіна), і з трохи більшою визначеністю та поясненнями, тому що я дізнався багато про правила переписання з моменту (і через) відповіді на ваше перше запитання.

Обговорення в чаті

Ми вирішили остаточні питання цього питання в чаті . Зрештою, Стівен використав generate_rewrite_rulesгачок, бо add_rewrite_rule()функція, здавалося, не працювала на нього.


2
@Steven: pagenameце слима сторінки WordPress, яку ви хочете відобразити (запис у базі даних). Потім ця сторінка може вказати, що вона хоче використовувати designers.phpфайл шаблону в області адміністратора WP. Отже, ви вказуєте на слизьку сторінки, а не на назву шаблону, оскільки один і той же шаблон може використовуватися для кількох сторінок: у цьому випадку WordPress не знає, що ви хочете зробити.
Ян Фабрі

1
@Steven: Я думаю, ви надто ускладнюєте спосіб встановлення гачків. Видаліть add_rewrite_rules()функцію та подзвоніть add_filter()/add_action()безпосередньо. Якщо це в тематичному файлі, видаліть flush_rewrite_rules()та просто перейдіть на сторінку налаштувань постійних посилань, щоб виправити правила (або додайте їх wpse5413_init()і видаліть пізніше). І мій плагін відображає поточні правила перезапису. Пам'ятайте, що це лише змінює спосіб обробки вхідних URL-адрес, а не те, як ваш код буде записувати URL-адреси в HTML.
Ян Фабрі

1
@Steven: Я не думаю, що вам навіть не потрібно натиснути кнопку збереження, просто відкриття сторінки постійних посилань також змине її. Знову ж таки, це лише додасть можливості WordPress приймати /designers/designer-slug/URL-адреси, вам потрібно змінити місця, де ви самі пишете ці URL-адреси у своєму HTML. Перевірте це, перейшовши на /designers/Batlak-og-Selvig/себе, якщо це працює, знайдіть усі місця, які генерують ці URL-адреси, та змініть їх, щоб використовувати нову структуру.
Ян Фабрі

1
Ага, зараз я думаю, що я починаю ундерстандарт. Я думав, що правила перезапису змінять спосіб розсилки URL-адреси у полі URL-адреси веб-переглядачів. Але що означає, що я маю фактично вивести URL-адресу, www.mysite.com/batlat-og-selvig/9і тоді це "перекладено" на/?designer=Batlak-og-Selvig&bid=9
Стівен

1
@Steven: Так, так: правила перезапису обробляють вхідні посилання, і (лише в декількох вибраних випадках) не впливають на створені посилання у вашому коді.
Ян Фабрі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.