How to change the default posts url in PyroCMS

By: William
Category: PyroCMS

Change the default URL structure of PyroCMS posts to something else.

From start when you install PyroCMS, they use /posts and /posts/slug to display the blog/posts pages. I use /blog and /blog/slug on my site. This is quick fix if you would like to change it yourself.

I choose to add a new routes file, but you could also set them in your theme service provider. Depends on your needs. Just remember that if you do set them in your theme service provider, if you set them to something else in the new routes file we create they will override your routes in the service provider.

First step is to create a new routes.php under project-root/resources/app-name.

Step 2) In routes.php you will need to defined your own named routes as well as disable the default ones used by pyro.

// Your new routes
Route::get("blog/rss/categories/{category}.xml", [
    'as'   => 'anomaly.module.posts::categories.rss',
    'uses' => 'Anomaly\PostsModule\Http\Controller\RssController@category',
]);
Route::get("blog/rss/tags/{tag}.xml", [
    'as'   => 'anomaly.module.posts::tags.rss',
    'uses' => 'Anomaly\PostsModule\Http\Controller\RssController@tag',
]);
Route::get("blog/rss.xml", [
    'as'   => 'anomaly.module.posts::posts.rss',
    'uses' => 'Anomaly\PostsModule\Http\Controller\RssController@recent',
]);
Route::get("blog",[
    'as'   => 'anomaly.module.posts::posts.index',
    'uses' => 'Anomaly\PostsModule\Http\Controller\PostsController@index',
]);
Route::get("blog/preview/{str_id}", [
    'as'   => 'anomaly.module.posts::posts.preview',
    'uses' => 'Anomaly\PostsModule\Http\Controller\PostsController@preview',
]);
Route::get("blog/tags/{tag}", [
    'as'   => 'anomaly.module.posts::tags.view',
    'uses' => 'Anomaly\PostsModule\Http\Controller\TagsController@index',
]);
Route::get("blog/categories/{slug}", [
    'as'   => 'anomaly.module.posts::categories.view',
    'uses' => 'Anomaly\PostsModule\Http\Controller\CategoriesController@index',
]);
Route::get("blog/archive/{year}/{month?}", [
    'as'   => 'anomaly.module.posts::tags.archive',
    'uses' => 'Anomaly\PostsModule\Http\Controller\ArchiveController@index',
]);
Route::get("blog/{slug}", [
    'as'   => 'anomaly.module.posts::posts.view',
    'uses' => 'Anomaly\PostsModule\Http\Controller\PostsController@view',
]);

Step 3) Finally you wanna override the original routes and abort if someone tries accessing them:

// Disable old routes.
Route::get("posts/rss/categories/{category}.xml", function() {
		abort(404);
	});
Route::get("posts/rss/tags/{tag}.xml",function(){
		abort(404);
	});
Route::get("posts/rss.xml",function(){
		abort(404);
	});
Route::get("posts",function(){
		abort(404);
	});
Route::get("posts/preview/{str_id}",function(){
		abort(404);
	});
Route::get("posts/tags/{tag}",function(){
		abort(404);
	});
Route::get("posts/categories/{slug}",function(){
		abort(404);
	});
Route::get("posts/archive/{year}/{month?}",function(){
		abort(404);
	});
Route::get("posts/{slug}",function(){
		abort(404);
	});
	
// Or a cleaner way, (Creds Craigberry)
Route::get('/posts/{all}', function($route) {
    abort(404);
})->where('all', '.*');

// And creds to Piterden for this..
public function map(Router $router)
    {
        $routeCollection = $router->getRoutes();

        $copy    = $routeCollection->getIterator()->getArrayCopy();
        $mutated = new RouteCollection;

        foreach ($copy as $route)
        {
            $uri = str_replace('posts', 'news', $route->getUri());

            $route->setUri($uri);
            $mutated->add($route);
        }

        $router->setRoutes($mutated);
    }