Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Juukie's avatar
Level 22

Using custom name for resource routes.

I'm trying to change the generated routename for the routes by doing this:

Route::resource('photos', 'PhotoController', ['as' => 'images']);

This is the result:

images.photos.index   | PhotoController@index
images.photos.create  | PhotoController@create
images.photos.store   | PhotoController@store
images.photos.show    | PhotoController@show
images.photos.edit    | PhotoController@edit
images.photos.update  | PhotoController@update
images.photos.destroy | PhotoController@destroy

I hoped it to be:

images.index   | PhotoController@index
images.create  | PhotoController@create
images.store   | PhotoController@store
images.show    | PhotoController@show
images.edit    | PhotoController@edit
images.update  | PhotoController@update
images.destroy | PhotoController@destroy

Is it possible to name the routes without adding them manually?

0 likes
24 replies
pmall's avatar

Maybe your photo entity should be named images :-)

Juukie's avatar
Level 22

@nesl247: but then I have to specify each routename seperately, which I prefer not to.

@pmall: this case is a simplified example of something complicater I try to solve. This line is in a route group with a specified domain and I would like to prepend a "domain-reference" to the resource name.

Prullenbak's avatar

Isn't it as simple as

Route::resource('images', 'PhotoController');

? Or is that what @pmall meant?

1 like
Juukie's avatar
Level 22

No, as I mentioned it is a simplified example of what I'm trying to accomplish. I've made a pastebin with a more detailed example: http://laravel.io/bin/mJrnn

The pastebin example doesn't do any change between /photos and /images, but it shows the problem of double dots.

Juukie's avatar
Level 22

Thanks DivDax, I'm aware of this option, but I prefer not to have to specify each name seperately.

bashy's avatar

I'm guessing your pastebin is wrong and you meant admin..images.index etc?

Why do they HAVE to be named as images? I can't see a reason why you'd want to name it something different to what you've called the controller.

Juukie's avatar
Level 22

As I mentioned, the example in my initial post is a simplified example of what I'm trying to accomplish. The pastebin example ( http://laravel.io/bin/mJrnn ) shows my real problem: admin.photos..photos instead of admin.photos. The renaming from photos/images is not an issue.

bashy's avatar

Oh okay, tried this then?

Route::resource('photos', 'PhotoController', ['as' => 'admin']);

You should be using namespaces and a prefix though so you get the admin. at the start through that.

4 likes
Juukie's avatar
Level 22

Thanks for the idea Bashy, I've tried it but didn't work.

bashy's avatar

I have it working so not sure why it's not for you.

Juukie's avatar
Level 22

Did you copy the code from the pastebin? I'm on 4.2..

bashy's avatar
bashy
Best Answer
Level 65

I use my own code on a website, I use a prefix and that gets added into the named routes

Maybe it's because you are using a domain and not a prefix but, I get this; prefix.route.method

3 likes
jjudge's avatar

@Juukie Did you ever find a solution to this? It seems to be the same on L5.1

The route names that the RESTful route creates for you have the URL path in. To my mind, the names you give routes are internal identifiers and have nothing to do with the external paths that are exposed. I realise they can each be renamed individually, but can the route names be given a base name in bulk, that is independent of the URL path without that hassle? You have a RESTful controller with a name, and you have a base path at which that controller is presented to the world. Two different things.

Looking at the replies, I'm not sure any of the other responders understood what you were asking here.

1 like
jjudge's avatar

Looking through the L5.1 source, it looks like the resource name is very much locked onto the resource path. The only way to override that is to use the names option to override each individual resource action with a full custom name.

Route::resource('my/path/to/whereever/I/like', 'MyController', [
    'names' => [
        'index' => 'my_route_base_name.index',
        'edit' => 'my_route_base_name.edit',
        'create' => 'my_route_base_name.create',
        etc...
    ],
])

Without over-riding those actions like that, the names of the routes above would automatically take the form my.path.to.whereever.i.like.index etc.

A 'basename' option would be great.

2 likes
Juukie's avatar
Level 22

He @consil, I've read your message quickly (will read it back when I have a bit more time) and it seems you understand what my problem is. I didn't found a solution to it.

hootlex's avatar

It would be very useful to be able to define a name for the whole resource but unfortunately there isn't. :(

Pendo's avatar

Same issue here, the routes I'm using are Dutch but I'd like to keep the resource in English for readability for other developers. Besides, if I even was to rename the routes it's just strange that I would have to look up all route() functions inside my application and change them. For instance, I have the following route:

Route::resource('groepen', 'GroupController');

Which gives me the ability to use

route('groepen.index')

But I want to use English as leading language inside the code, so I'd expect this to work:

Route::resource('groepen', 'GroupController', ['name' => 'groups']);

But that gives me routes like:

route('groups.groepen.index');

Instead of what would be more useful:

route('groups.index');

Of course you can rename them all, but wouldn't it be more convenient to be able to swap the key? Because if you ever where to rename the route from /groepen to /communities all names routes would change from groepen.index to communities.index.

Hopefully the issue is more clear. I can't figure any option out either besides having to manually name every single route in a resource.

3 likes
jasekiw's avatar

The way I got around this issue was to create a helper method. create a function like so

function getResourceRoutesForNameHelper($name)
    {
        return [
            'index' => $name . ".index",
            'create' => $name . ".create",
            'store' => $name . ".store",
            'show' => $name . ".show",
            'edit' => $name . ".edit",
            'update' => $name . ".update",
            'destroy' => $name . ".destroy",
        ];
    }

then call the function in your routes

Route::resource('photos', 'PhotoController', ['names' => getResourceRoutesForNameHelper('images') ]);

you can put the function before you call your route or somewhere more eloquent.

3 likes
joelcuevas's avatar

In my case, this lead me to a solution:

http://laravel.io/forum/06-21-2014-resource-route-names-without-prefix?page=1#reply-28094

"The real solution requires overriding a single ResourceRegistrar method with my own so that the URL prefix in the group does not affect named routes."

For L5.2 and tweaking a little the original answer, create an app/Registrars/ResourceWithoutPrefixRegistrar.php file.

<?php

namespace app\Registrars;

use Illuminate\Routing\ResourceRegistrar;

class ResourceWithoutPrefixRegistrar extends ResourceRegistrar
{
    protected function getGroupResourceName($prefix, $resource, $method)
    {
        return trim("{$resource}.{$method}", '.');
    }
}

And then in the app/Providers/RouteServiceProvider.php file:

public function boot(Router $router)
{
    $this->app->bind('Illuminate\Routing\ResourceRegistrar', 'App\Registrars\ResourceWithoutPrefixRegistrar');

    parent::boot($router);
}

Hope it helps.

joaoguilherme's avatar

Hey @Juukie. You may use explicit binding for that. https://laravel.com/docs/master/routing#explicit-binding (Also available for 5.2, not sure about previous versions)

Add the following to the boot function inside /App/Providers/RouteServiceProvider.php

Route::model('images', 'App\Photo');

Then on your routes files you can (https://laravel.com/docs/5.2/controllers#restful-naming-resource-route-parameters)

Route::resource('images', 'PhotosController', ['parameters' => [
        'images' => 'photo'
    ]]);
Juukie's avatar
Level 22

@joelcuevas's solution (with the custom registrar) trimmed of the admin. so it results in duplicate routes being registered.

Route::group(['domain' => 'admin.example.com'], function () {
    Route::resource('photos', 'PhotoController', ['as' => 'admin.photos']);
});

Route::resource('photos', 'PhotoController');

// photos.index (twice)
// photos.show (twice)
// etc.

Tried @bashy's idea and on a fresh 4.2 and 5.2 project it resulted in the expected route names.

Route::group(['domain' => 'admin.example.com'], function () {
    Route::resource('photos', 'PhotoController', ['as' => 'admin']);
});

// admin.photos.index
// admin.photos.show
// etc.

Other examples:

Route::group(['domain' => 'admin.example.com', 'prefix' => 'v1'], function () {
    Route::resource('photos', 'PhotoController', ['as' => 'admin']);
});

// admin.v1.photos.index
// admin.v1.photos.show
// etc.
Route::group(['prefix' => 'v1'], function () {
    Route::resource('photos', 'PhotoController', ['as' => 'admin']);
});

// admin.v1.photos.index
// admin.v1.photos.show
// etc.
Route::group(['prefix' => 'v1'], function () {
    Route::resource('photos', 'PhotoController');
});

// v1.photos.index
// v1.photos.show
// etc.
Route::group(['middleware' => 'something'], function () {
    Route::resource('photos', 'PhotoController');
});

// photos.index
// photos.show
// etc.
Route::resource('photos', 'PhotoController');

// photos.index
// photos.show
// etc.

The specified domain won't change the route name as one can see. A prefix will.

1 like
Willder's avatar

For those searching for an answer in 2023 (because we are in Laravel 10 and we do not have this option...)

On RouteServiceProvider.php create a macro for Illuminate\Routing\PendingResourceRegistration as below

PendingResourceRegistration::macro('as', function ($prefix) {
            return $this->names([
                'index'   => "{$prefix}.index",
                'show'    => "{$prefix}.show",
                'create'  => "{$prefix}.create",
                'store'   => "{$prefix}.store",
                'edit'    => "{$prefix}.edit",
                'update'  => "{$prefix}.update",
                'destroy' => "{$prefix}.destroy"
            ]);
});

and in web.php on your route do as below:

Route::resource('funcoes', \App\Http\Controllers\RoleController::class)
        ->parameters(['funcoes' => 'role'])
        ->as('roles')
;

You can name your macro with any name you want...

Please or to participate in this conversation.