Yii DataProvider Pagination and Parameterized URLs

As it stands, the Yii2 ActiveDataProvider::$pagination property creates urls like this:

www.example.com/controller/index?page=2&per-page=10

Id rather it look like this:

www.example.com/controller/index/2 (or www.example.com/controllerIndex/2/10)

Im setting my $pagination-pageSize property inside my own custom data provider, so I dont need that in the URL at all. FYI setting $this->pagination->pageSizeParam to NULL makes for one ugly query string:

?page=2&=10 (* $this is my CustomDataProvider)

Though setting $pagination->pageSizeParam to FALSE does make it disappear as expected.

So I figured I just need to create a route in my application urlManager for the pagination for this controller action, and it would be all done, like this:


//main.php config

urlManager' => [

            'enablePrettyUrl'     => TRUE,

            'showScriptName'      => FALSE,

            'class'               => 'yii\web\UrlManager',

            'rules'               => [

                ...

                'controller' => 'controller/index',

                'controller/<page:\d+>' => 'controller/index'

                ...

            ]

        ]

        ...

but no, it had no effect on the urls created by the pagination links. If I type the url in directly, it navigates to the correct page, but displays links with the query string Im trying to avoid.

So then I read the documentation on pagination, and it states the following with regards to $pagination->urlManager:

The $pagination->urlManager is always NULL when I dont set it, but I do see in the source code that it falls back to the application urlManager. It still doesnt seem to be using the rules Ive set though.

So i set it anyway, as follows (again, $this is CustomDataProvider, an extension of ActiveDataProvider) :


$this->pagination->urlManager = Yii::$app->urlManager;

I did some debugging to make sure that this was the urlManager I expect, and that it is configured with the routes I expect, and the output of the $pagination->urlManager is as I expect (I can see all the paginated routes Ive defined).

However, the urls for pagination dont change, they just continue using a query string instead of the route Ive created.

How can I force the pagination to use the routes Ive defined? How can I customize the routes to look more modern, like www.example.com/controller/action/2 ?

Also, the default $pagination->pageSizeParam shouldnt have a dash in it. It makes it harder to define a url rule (assuming one can be done in the first place). Either the $pageSizeParam needs to be overridden to remove the dash, or custom urlManager regex has to be applied to the route to make use of the param name (default is ‘per-page’, so I tried setting it to ‘perpage’ to use with my route - fail).

Ok I figured this out. In the Route guide:

I simply had to reverse the rules for the controller/index route and controller/index/pageNum route. Apparently when Pagination::createUrl() is called, it hits the app UrlManager, saw that "controller/index" matched, and chose that route (then appended query string). If "controller/index/pageNumber" is placed before "controller/index", Pagination::createUrl() finds that first, then makes all its pagination links pretty.

Note: I have ‘enablePrettyUrl’ TRUE in my application UrlManager.