yiisoft / yii2

Yii 2: The Fast, Secure and Professional PHP Framework
http://www.yiiframework.com
BSD 3-Clause "New" or "Revised" License
14.24k stars 6.9k forks source link

URL Routing #2920

Closed bSushil closed 10 years ago

bSushil commented 10 years ago

I think url routing in Yii 1.* is not that good. After working in Laravel, I really liked how it handles url routing. I wish if something like that is implemented in Yii 2.

Ragazzo commented 10 years ago

yeah, i think it would be useful, but can you describe in particular what you want to bring here ? would be great if you will provide list with examples .

bSushil commented 10 years ago

The url routing in laravel is very interesting. It uses a separate file for handling routing. We can group urls and add filters for the urls. Below is the url routes that I used in one of my projects. If we can have this kind of url handling in Yii, it would certainly make Yii even better framework.

Route::group(array('prefix' => 'admin', 'before' => 'auth.admin'), function()
{
    Route::get('notallowed', array('as'=>'admin.notallowed', 'uses'=>'App\Controllers\Admin\AdminController@notAllowed'));
    Route::get('dashboard', array('as'=>'admin.dashboard', 'uses'=>'App\Controllers\Admin\AdminController@showDashboard'));

    /**
     * routes for logged in user
     */
    Route::get('changepassword', array('as'=>'admin.changepassword', 'uses'=>'App\Controllers\Admin\UserController@changePassword'));
    Route::post('changepassword', array('as'=>'admin.postchangepassword', 'uses'=>'App\Controllers\Admin\UserController@postChangePassword'));

    Route::group(array('before'=>'sentry'), function()
    {
        /**
         * routes for units
         */
        Route::get('units', array('as'=>'admin.units', 'uses'=>'App\Controllers\Admin\UnitController@showIndex'));
        Route::get('units/create', array('as'=>'admin.units.create', 'uses'=>'App\Controllers\Admin\UnitController@getCreate'));
        Route::post('units/create', array('as'=>'admin.units.postCreate', 'uses'=>'App\Controllers\Admin\UnitController@postCreate'));
        Route::get('units/update/{id}', array('as'=>'admin.units.update', 'uses'=>'App\Controllers\Admin\UnitController@get_update'));
        Route::post('units/update/{id}', array('as'=>'admin.units.postUpdate', 'uses'=>'App\Controllers\Admin\UnitController@postupdate'));
        Route::post('units/delete/{id}', array('as'=>'admin.units.delete', 'uses'=>'App\Controllers\Admin\UnitController@postDelete'));
        Route::post('units/deleteAll/{id}', array('as'=>'admin.units.deleteAll', 'uses'=>'App\Controllers\Admin\UnitController@deleteAll'));
        Route::get('units/listunits', array('as'=>'admin.units.listunits', 'uses'=>'App\Controllers\Admin\UnitController@listunits'));
}
}

This way, we can have same url performing different action based upon the request method. And also, have a certain code run before or after the action is performed.

I had difficulty in managing/handling urls in Yii 1.13 in one of the projects I did.

Another interesting feature can be different configuration files based upon the setup environment. Developers tend to have their own configuration. When collaborating in a project, the configuration file often tends to be overwritten. So, if there was system specific configuration file, then it would make life easier for the developers.

Installation via composer is definitely a good news.

samdark commented 10 years ago

It uses a separate file for handling routing.

Easily done with Yii via simple include statement in config.

'as'=>'admin.changepassword'

Is it assigning internal ID for a route? I'd not implement it since it's hard to manage these associations. In Yii it is assigned automatically to controller/action or module/controller/action.

'uses'=>'App\Controllers\Admin\AdminController@notAllowed'

That seems to be mapping route to controller action. Again, in Yii there's convention for it i.e. site/index is automatically mapped to SiteController::actionIndex() and I think that's better than allowing to map to arbitrary named methods since it may cause significant confusion.

array('before'=>'sentry')

Looks handy. Currently can be achieved with beforeAction but it can be wise to move it to rules. Not sure about it yet.

array('prefix' => 'admin',

What is it for?

This way, we can have same url performing different action based upon the request method.

Yii supports it as well. The form is different though:

['pattern' => 'changepassword', 'route' => 'user/changePassword', 'verb' => 'GET'],
['pattern' => 'changepassword', 'route' => 'user/postChangePassword', 'verb' => 'POST'],

different configuration files based upon the setup environment.

Already implemented in advanced app template.

bSushil commented 10 years ago

Thanks. Your email gave me new ideas.

array('prefix' => 'admin',

This groups the urls so that we don't have to make same kind of rules. For example, in stead of writing:

Route::get('admin/units', array('as'=>'admin.units', 
'uses'=>'App\Controllers\Admin\UnitController@showIndex'));
Route::get('admin/units/create', array('as'=>'admin.units.create', 
'uses'=>'App\Controllers\Admin\UnitController@getCreate'));
Route::post('admin/units/create', 
array('as'=>'admin.units.postCreate', 
'uses'=>'App\Controllers\Admin\UnitController@postCreate'));

We can write like:

Route::group(array('prefix' => 'admin', 'before' => 'auth.admin'), 
function()
{
        Route::get('units', array('as'=>'admin.units', 
'uses'=>'App\Controllers\Admin\UnitController@showIndex'));
        Route::get('units/create', array('as'=>'admin.units.create', 
'uses'=>'App\Controllers\Admin\UnitController@getCreate'));
        Route::post('admin/units/create', 
array('as'=>'admin.units.postCreate', 
'uses'=>'App\Controllers\Admin\UnitController@postCreate'));
});

I also like the automatic mapping of actions into url, but I think how laravel does it more handy and beautiful.

Ragazzo commented 10 years ago

@samdark example with controller is about how explicitly match route to the given controller. In Yii2 currently this is not possible, only with controllerMapt + rules, however as for me this feature is useful, for example for extensiins and other solutions that already have controllers in them. I would like to see that in Yii2. Also can you point where in yii2-advanced custom routes are implemented ?

bSushil commented 10 years ago

Is this available in Yii 1.13?

['pattern' => 'changepassword', 'route' => 'user/changePassword', 'verb' => 'GET'], ['pattern' => 'changepassword', 'route' => 'user/postChangePassword', 'verb' => 'POST'],

samdark commented 10 years ago

@bSushil yes.

samdark commented 10 years ago

@Ragazzo

example with controller is about how explicitly match route to the given controller. In Yii2 currently this is not possible

yes, Yii2 always follows convention and I think that's cleaner, leaves less space for errors and easier to work with project.

Also can you point where in yii2-advanced custom routes are implemented ?

The question was about different route config files depending on environments. Implementation is here: https://github.com/yiisoft/yii2/blob/master/apps/advanced/init

Ragazzo commented 10 years ago

@samdark not sure about first one, it can be useful for already existing solutions or modules that have controllers, and user will not be needed to change things in 2 places: controllerMap + rules, he can simply make it in rules, so i think this is useful.

Ragazzo commented 10 years ago

Related with #1763 i think )

qiangxue commented 10 years ago

Closed as we do not have plan to change our existing URL routing. The design described here has its own pros and cons.