Adding Rules Dynamically
Adding Rules Dynamically
Добрый день.
Вопрос в задании паттернов.
Реализация:
К примеру есть несколько страниц и их роуты
1) /computer
2) /computer/motherboard
3) /computer/keyboard
В бутстрапе в цикле я добавляю правила
$app
->getUrlManager()
->addRules(
[
[
'pattern' => $page['route'],
'route' => "product/category"
]
],
false
);
на странице /computer класс Sort в составе dataProvider'a создает ссылку /computer/motherboard?sort=price а не /computer?sort=price (как должно быть)
Подскажите плиз как правильно сформулировать pattern, заранее спасибо!
Вопрос в задании паттернов.
Реализация:
К примеру есть несколько страниц и их роуты
1) /computer
2) /computer/motherboard
3) /computer/keyboard
В бутстрапе в цикле я добавляю правила
$app
->getUrlManager()
->addRules(
[
[
'pattern' => $page['route'],
'route' => "product/category"
]
],
false
);
на странице /computer класс Sort в составе dataProvider'a создает ссылку /computer/motherboard?sort=price а не /computer?sort=price (как должно быть)
Подскажите плиз как правильно сформулировать pattern, заранее спасибо!
Re: Adding Rules Dynamically
Попробуйте у формы action прописать
Re: Adding Rules Dynamically
Маршрутизатор смотрит маршруты "product/category" и берёт первый попавшийся, а они у вас все к одному и тому же маршруту привязаны. Поэтому и получается путаница - ведь он не знает, как их различать.
Если у вас категории не вложенные, и имеют лишь один уровень, можно сделать так.
1. Завести два маршрута с параметрами, цикл в бутстрапе убрать.
Обращаю внимание, что порядок важен! Чтобы всё правильно решалось, сначала должен идти самый специфичный маршрут, потом более общий.
2. При создании ссылки указывать соответствующие параметры.
Теперь эти маршруты для самого маршрутизатора будут различаться, потому что помимо строки контроллер-действие "product/category", он ещё будет хранить параметры, и по ним построит уже всё правильно.
Если у вас категории не вложенные, и имеют лишь один уровень, можно сделать так.
1. Завести два маршрута с параметрами, цикл в бутстрапе убрать.
Код: Выделить всё
'<product:[0-9a-zA-Z\-]+>/<category:[0-9a-zA-Z\-]+>' => 'product/category',
'<product:[0-9a-zA-Z\-]+>' => 'product/category',
2. При создании ссылки указывать соответствующие параметры.
Код: Выделить всё
Url:to(['product/category', 'product' => 'computer'])
Url:to(['product/category', 'product' => 'computer', 'category' => 'motherboard'])
Re: Adding Rules Dynamically
Про первый попавшийся, я понял, а нельзя задать что бы он смотрел на всю строку целиком а не на часть "/computer"
Есть же к примеру в регулярке ^строка$ - такое правило от начала строки и до конца что бы сравнивал, но я так пробовал не сработало...
Есть же к примеру в регулярке ^строка$ - такое правило от начала строки и до конца что бы сравнивал, но я так пробовал не сработало...
Re: Adding Rules Dynamically
Так он и смотрит. Регулярка здесь не поможет, проблема не в ней. Просто ты не понимаешь, как оно работает.
Смотри как получается.
Твой пример с циклом.
Вот у тебя три правила, по первому примеру с циклом.
URL "/computer" соответствует маршруту "product/category"
URL "/computer/motherboard" соответствует маршруту "product/category"
URL "/computer/keyboard" соответствует маршруту "product/category"
Все они привязаны к одному маршруту.
Поэтому при разборе URL, всё корректно определяется - по первому совпавшему URL мы определяем маршрут "product/category", который нам и нужен.
Далее, что происходит при генерации ссылки на сортировку во вьюшке?
Весь процесс идёт в обратном порядке.
1. Берётся текущий маршрут - "product/category".
2. Для него ищется подходящее правило для генерации URL.
3. Но для маршрута "product/category" уже существует три равнозначных правила, с точки зрения маршрутизатора. Они все указывают на тот же маршрут. Поэтому он и выбирает любое из них, первое попавшееся.
Маршрутизатор при генерации URL различает правила по конечным маршрутам и параметрам. Конечный маршрут у тебя одинаковый, а параметров нет. Поэтому и различий между правилами нет.
Мой пример с параметрами.
Есть два правила.
Помимо самого URL, указаны параметры.
При разборе URL, маршрутизатор будет хранить не только текущий маршрут 'product/category', но и значения параметров - какой выбран продукт и какая выбрана категория для текущей страницы.
Поэтому, для генерации URL он обратно его построит корректно - "ага, сейчас выбран маршрут "product/category", значит в шаблон "<product:[0-9a-zA-Z\-]+>/<category:[0-9a-zA-Z\-]+>" подставляем значение параметра "product"="computer", значение параметра "category"="keyboard", получим "/computer/keyboard", вуаля!"
Смотри как получается.
Твой пример с циклом.
Вот у тебя три правила, по первому примеру с циклом.
URL "/computer" соответствует маршруту "product/category"
URL "/computer/motherboard" соответствует маршруту "product/category"
URL "/computer/keyboard" соответствует маршруту "product/category"
Все они привязаны к одному маршруту.
Поэтому при разборе URL, всё корректно определяется - по первому совпавшему URL мы определяем маршрут "product/category", который нам и нужен.
Далее, что происходит при генерации ссылки на сортировку во вьюшке?
Весь процесс идёт в обратном порядке.
1. Берётся текущий маршрут - "product/category".
2. Для него ищется подходящее правило для генерации URL.
3. Но для маршрута "product/category" уже существует три равнозначных правила, с точки зрения маршрутизатора. Они все указывают на тот же маршрут. Поэтому он и выбирает любое из них, первое попавшееся.
Маршрутизатор при генерации URL различает правила по конечным маршрутам и параметрам. Конечный маршрут у тебя одинаковый, а параметров нет. Поэтому и различий между правилами нет.
Мой пример с параметрами.
Есть два правила.
Код: Выделить всё
'<product:[0-9a-zA-Z\-]+>/<category:[0-9a-zA-Z\-]+>' => 'product/category',
'<product:[0-9a-zA-Z\-]+>' => 'product/category',
При разборе URL, маршрутизатор будет хранить не только текущий маршрут 'product/category', но и значения параметров - какой выбран продукт и какая выбрана категория для текущей страницы.
Поэтому, для генерации URL он обратно его построит корректно - "ага, сейчас выбран маршрут "product/category", значит в шаблон "<product:[0-9a-zA-Z\-]+>/<category:[0-9a-zA-Z\-]+>" подставляем значение параметра "product"="computer", значение параметра "category"="keyboard", получим "/computer/keyboard", вуаля!"
Re: Adding Rules Dynamically
Я вас понял, спасибо за разъяснения.
Но это не раешает задачи)
Дело в том что структура которую я привел ранее
1) /computer
2) /computer/motherboard
3) /computer/keyboard
Может отличаться
к примеру добавиться 3 уровень
3) /computer/keyboard/logitech
или добавиться 4 страница (статическая страница, а не страница каталога)
4) /contacts
все это, менеджер в любой момент может поменять (вложенность, slug - из за которого измениться роут страницы, и др)
но при этом у страницы есть "модуль" - по которому мы определяем что это "старическая страница" или "страница каталога" и можем задать роут в rules urlManger
так вот, может быть есть возможность передать "/computer/keyboard/logitech" как параметр?
Поскольку так это рабоать не будет:
'<product:[0-9a-zA-Z\-]+>' => 'product/category',
'<page:[0-9a-zA-Z\-]+>' => 'page/view
Заранее спасибо)
Но это не раешает задачи)
Дело в том что структура которую я привел ранее
1) /computer
2) /computer/motherboard
3) /computer/keyboard
Может отличаться
к примеру добавиться 3 уровень
3) /computer/keyboard/logitech
или добавиться 4 страница (статическая страница, а не страница каталога)
4) /contacts
все это, менеджер в любой момент может поменять (вложенность, slug - из за которого измениться роут страницы, и др)
но при этом у страницы есть "модуль" - по которому мы определяем что это "старическая страница" или "страница каталога" и можем задать роут в rules urlManger
так вот, может быть есть возможность передать "/computer/keyboard/logitech" как параметр?
Поскольку так это рабоать не будет:
'<product:[0-9a-zA-Z\-]+>' => 'product/category',
'<page:[0-9a-zA-Z\-]+>' => 'page/view
Заранее спасибо)
Re: Adding Rules Dynamically
Пишите свой класс для правила в таком случае. Не так уж это и сложно, я делал )
Re: Adding Rules Dynamically
Спасибо в любом случае)
Сделал так
Сделал так
Код: Выделить всё
$slugs = explode('/', $page['route']);
unset($slugs[0]);
$patternSlugs = [];
foreach ($slugs as $key => $slug) {
$patternSlugs[] = "<{$key}:{$slug}>";
}
$rules = [
[
'pattern' => implode('/', $patternSlugs),
'route' => "product/category"
]
];