Поддержка Проблемы и решения Настройка Friendly URL для результатов фильтра в htaccess

  • Помогите решить проблему, нужно настроить в адресной строке дружественный урл для отфильтрованной выборки. Сейчас выглядит так — /?filter_vendor=some-text, а нужно чтобы было так — /filter_vendor/some-text.

    Работаю в локалке. Перепробовал кучу вариантов с .htaccess, но ни один из них не сработал.

    Вот некоторые из вариантов:

    
    RewriteCond %{QUERY_STRING} ^filter_vendor=(.+)
    RewriteRule ^$ /filter_vendor/%1? [R=301,L]
    

    или вот так

    
    RewriteRule ^([_0-9a-zA-Z-]+/)?filter_vendor([_=0-9a-zA-Z-]+)$ $1filter_vendor/$2 [R=301,L]
    

    Вообщем было много версий, все без результата. Помогите пожалуйста решить этот задачу

Просмотр 13 ответов — с 1 по 13 (всего 13)
  • Модератор Denis Yanchevskiy

    (@denisco)

    WordPress-разработчик, denisco.pro

    Не знаю к чему именно Вы добавляете, поэтому оставлю EP_ALL, по ссылке дополнительные параметры.

    
    function dco_init() {
        add_rewrite_endpoint('filter_vendor', EP_ALL);
    }
    
    add_action('init', 'dco_init');
    

    Ну и потом в нужном месте get_query_var('filter_vendor'); или global $wp_query; $wp_query->query_vars['filter_vendor'];

    Если добавляете к таксономии, то вероятно придется с помощью add_rewrite_rule.
    На примере WooCommerce

    
    function dco_add_rewrite_rules() {
        add_rewrite_rule('product_cat/(.+?)/filter_vendor(/(.*))?/?$', 'index.php?product_cat=$matches[1]&filter_vendor=$matches[3]', 'top');
    }
    
    add_action('init', 'dco_add_rewrite_rules');
    
    function dco_add_query_vars($vars) {
        $vars[] = 'filter_vendor';
        return $vars;
    }
    
    add_filter('query_vars', 'dco_add_query_vars');
    

    Использовать аналогично первому варианту.

    Спасибо большое за этот пример. Толчок в новое русло. Вопрос лирический но всё же, почему не работает в htaccess? WP что игнорирует этот файл?

    ммм и вот ещё &filter_vendor=$matches[3]' почему в этом месте стоит 3 а не 2? очипятка или так должно быть?

    вообщем добавил в functions.php такой код

    
    function dco_add_rewrite_rules() {
        add_rewrite_rule('cat/(.+?)/filter_vendor(/(.*))?/?$', 'index.php?cat=$matches[1]&filter_vendor=$matches[2]', 'top');
    }
    
    add_action('init', 'dco_add_rewrite_rules');
    
    function dco_add_query_vars($vars) {
        $vars[] = 'filter_vendor';
        return $vars;
    }
    
    add_filter('query_vars', 'dco_add_query_vars');
    

    не работает. где ошибка? в настройки постоянных ссылок зашёл, сохранил. flush_rewrite_rules() по идее сбросил. что не так?

    Модератор Yuri

    (@yube)

    почему не работает в htaccess? WP что игнорирует этот файл?

    Разумеется! .htaccess предназначен исключительно для Апача.

    WP может его прочитать или перезаписать, но инструкция там не для него.

    • Ответ изменён 6 лет, 4 месяца назад пользователем Yuri.

    WP может его прочитать или перезаписать, но инструкция там не для него

    спасибо, буду иметь в виду этот момент, но всё же, не то чтобы я спорил, разве конструкция вида

    
    # BEGIN WordPress
    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /testWP/
    RewriteRule ^index\.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /testWP/index.php [L]
    </IfModule>
    
    # END WordPress
    

    не содержит инструкций для WP?
    как бы там ни было, более важно решить основную задачу. первый ответ был прекрасен, но я видимо не туда или не совсем так его применил. хотелось бы знать, где нутупил.

    Модератор Yuri

    (@yube)

    разве конструкция вида

    НЕТ
    Данная конструкция содержит инструкции для Апача, необходимые для работы ЧПУ wordpress.

    Юрий, означает ли это, что когда я применил add_rewrite_rule, необходимо теперь продублировать это правило и для Apacha, чтобы он правильно прочитал это ЧПУ?

    Модератор Yuri

    (@yube)

    Вышеозначенные правила в .htaccess указывают Апачу, что все запросы несуществующих «физически» файлов и директорий нужно отправлять на /index.php, а дальше уже дело движка разбираться с запросом. Получив запрос, WP сверяет его со своей таблицей реврайтов, и если соответствие найдено, формирует соответствующую выборку из БД, которая выводится посредством соответствующих шаблонов. Если соответствия нет — 404.

    Модератор Sergey Biryukov

    (@sergeybiryukov)

    Live and Learn

    и вот ещё &filter_vendor=$matches[3]' почему в этом месте стоит 3 а не 2? очипятка или так должно быть?

    Так и должно быть. 'cat/(.+?)/filter_vendor(/(.*))?/?$' — здесь три группы, третья из которых — (.*) — и должна подставляться после &filter_vendor=.

    вообщем добавил в functions.php такой код… не работает. где ошибка?

    Исправьте $matches[2] на $matches[3] и снова пересохраните постоянные ссылки.

    Юрий, спасибо за подробное описание механики. Учту.
    Сергей, изменил. Не помогло.
    По порядку. Я открыл файл functions.php по следующему пути: wp-include/themes/some theme/functions.php и на самом верху вписал вышеозначенный код с исправленным номером элемента массива. Принципиально ли местонахождения этого файла? Просто он встречается в нескольких местах и я подумал, может я не туда делаю запись?
    Как я себе это представляю, фильтр, работу которого я пытаюсь скорректировать, относится к виджету «WooCommerce Навигационные фильтры». Класс class-wc-widget-layered-nav.php вроде описывающий этот виджет, лежит по следующему пути wp-content\themes\some theme\woocommerce\includes\widgets. Может там же нужно и functions.php редактировать? Или не суть?

    • Ответ изменён 6 лет, 4 месяца назад пользователем kapitoxapux. Причина: уточнение

    вот пример с рабочего сайта каталога товаров.

    ЧПУ для категория+бренд(вендор)
    catalog и brand это таксономии.

    add_action('init', 'rewritecat');
    function rewritecat(){
    
    //правило категория + бренд
    add_rewrite_rule( '^catalog/([^/]+)/brand/([^/]+)/?$', 'index.php?catalog=$matches[1]&brand=$matches[2]', 'top' );
    
    //правило категория + бренд + пагинация
    add_rewrite_rule( '^catalog/([^/]+)/brand/([^/]+)/page/([0-9]{1,})/?$', 'index.php?catalog=$matches[1]&brand=$matches[2]&paged=$matches[3]', 'top' );
    
    }

    Но это влияет на запрос, когда в адресной строке уже набран урл вида: site.ru/catalog/auto/brand/bmw/

    А вы, я так понял хотите чтобы после отправки get запроса из формы/фильтра сразу такой урл генерился.

    спасибо за пример, попробую его применить, но на первый взгляд вроде всё тоже самое… касательно того, как оно должно работать, Вы правы, адрес генерится после выбора определённого значения и собственно хочется чтобы происходила подмена одного урла на другой.

    А зачем вам нужен чпу при выборе значений в форме? ведь там могут быть выбраны и другие параметры и/или выбрано например сразу несколько категорий или брендов. Тогда как быть?

    Если хотите продвигать страницы категория+бренд, то наверное нужно сделать так, чтобы в шаблоне где-то выводились такие ссылки уже сформированные. Ну и к тому же настроить в шаблоне генерацию title

    ничего не получается. попробую по другому поставить вопрос.

    На примере WooCommerce

    function dco_add_rewrite_rules() {
    add_rewrite_rule(‘product_cat/(.+?)/filter_vendor(/(.*))?/?$’, ‘index.php?product_cat=$matches[1]&filter_vendor=$matches[3]’, ‘top’);
    }
    add_action(‘init’, ‘dco_add_rewrite_rules’);

    это правило будет работать для пути вида
    http://localhost:8080/some-site/wp-admin/edit-tags.php?taxonomy=pa_vendor
    где вместо edit-tags.php у нас будет нечто вроде /some-tag/some-tag/ ??

    Просто все варианты регулярных выражений что я пробовал не дают нужный результат. Максимум что у меня получалось это пустой блок внутри контент части (то место где выводятся результаты работы фильтра). Возможно правила были верны, но был конфликт с WooComm?

Просмотр 13 ответов — с 1 по 13 (всего 13)
  • Тема «Настройка Friendly URL для результатов фильтра в htaccess» закрыта для новых ответов.