Global URL prefix

I have need to have all application URL prefixed with a value. I can do this with route rules like the following:




  ...

  '<prefix>/<controller:\w+>' => '<controller>/index',

  '<prefix>/<controller:\w+>/<id:\d+>' => '<controller>/view',

  ...



…and that all works for going to a URL and getting the page to display. However for Nav menu links, button clicks (create/update), hyperlinks, etc, it looks like EVERY one has to get or be passed the ‘prefix’ param to work correctly. That makes using something like gii useless since it does not generate the params. Is there a way to globally pass the prefix to all URL’s regardless of how the are generated/referenced?

It should be such that clicking a a button, menu link, hyperlink or whatever to create an item (or any other controller/action combo) anywhere in the application should point to <prefix>/item/create not just item/create. Again I can pass the params but that requires modifying EVERY link in the entire application. I have tried playing with overriding UrlRule using route rule like those in the snippet above, but am not sure if that is the best place to try to tackle something like this and the params are blank (even though the it seems the routes should have a ‘prefix’ param):




class UrlRule implements UrlRuleInterface

{


    public function createUrl($manager, $route, $params)

    {

      echo "<pre>";

      var_dump($params); //<-- this is empty

      echo "</pre>";

      die();

    }

}



I thought if I could get the prefix here, I could override the URL creations to auto-add it (and override parseRequest int he other direction), but I don’t seem to be able to get it and again am not sure if this is the best approach or not.

I also know that I could store the ‘prefix’ value in the DB or session, or whatever instead of passing it via the URL, but my client has a hard requirement that the URL’s MUST follow this format due to legacy integrations with other applications and for other reasons. Any thoughts are appreciated. We are brand new to Yii, but have quickly figured out some pretty complex stuff. We just can’t quite seem to figure this one out - if can even be done.

Global url prefix can be done on server level

I assume you mean via .htaccess (or similar)? The issue is with that the prefix is dynamic (different for every org/user). So the need is the url needs to be something like orgA/<controller>/<action> OR orgB/<controller>/<action>, but they need to link to the same physical files (which is why modules and/or sub-domains are not being used for each suffix).

We really need this to work as indicated (via Yii routing) or we’re going to have to use one of the many other frameworks that do support something like this out of the box. We’d hate to do that because we have invested heavily in Yii already or it has other benefits (like performance) that blow the others away. If we had control over using something other than a URL prefix for this, we would consider them, but our hands are tied - this is a HARD requirement for us.

You could override the UrlManager - probably the best option?

Actually what we ended up trying (and it seems to work OK so far) is adding a ‘parent’ controller that overrides Controller and in that we set a param:


Yii::$app->params['prefix'] = Yii::$app->request->get('prefix');

Then we can reference that param in views views and/or layouts:




...

$prefix = Yii::$app->params['prefix'];

...

echo Nav::widget([

        'options' => ['class' => 'navbar-nav navbar-right'],

        'items' => [

            ['label' => 'Home', 'url' => ['/site/index', 'prefix' => $prefix]],

       ...

...



… and the URL’s resolve back correctly (in the above case to ‘<prefix>/site/index’ because of the rules from the original forum post.

Yes that would also work. And a lot simpler!

Most of the time, the simplest solution is the best option.