So I am working on converting a previously-standalone Yii 2 app into a Craft module and am having some issues with routing. I wish to keep my old URL structure as much as possible. As such, I created a plugin and register routes. However, I've noticed an issue: When I call Url::to(), I get back URLs that seem to rely on the actionTrigger parameter, even if I explicitly defined routes in my plugin.
Here are the routes as I have them in my plugin:
class CustomerPortal extends \craft\base\Plugin
{
public function init()
{
Event::on(
UrlManager::class,
UrlManager::EVENT_REGISTER_SITE_URL_RULES,
function(\craft\events\RegisterUrlRulesEvent $event) {
$event->rules['portal/<action:[\w-+]>'] = 'customer-portal/portal/<action>';
If I make the call in a controller to redirect to a route, it builds the URL using an action param, not the rules we defined. For example:
class UserController extends \craft\web\Controller
{
public function actionRedirect()
{
echo Url::to(['checkout');
// I'd expect to see '/checkout', but instead we get
// '/actions/customer-portal/user/checkout' since we aren't
// applying either of our rules.
}
public function actionCheckout()
{
}
It seems that the rules are checked when parsing, but not during URL creation, and if you come in with an action prefix, the rules aren't parsed then, but the raw action is attempted.
Am I missing something or is this a bug and either way, can anyone think of a way to work around it?
Edit: Figured out the issue with routes not resolving I had originally, it turns out in the end, my issues was that the regex in the rules wasn't accounting for the fact that many of routes have dashes in them (for example: /user/billing-info). The default Yii docs say to use <action:\w+>
, but that doesn't match the dash character in the URL. Using <action:[\w-]+>
works perfectly and makes this all work.
That said, I'm still not getting Url::to or anything else that references UrlManager to work properly since UrlManager seems to add the action param to the URL before checkout to see if we match existing routes.