CodeIgniter 4: Helper route() function for multilingual urls like in Laravel

CodeIgniter 4: Helper route() function for multilingual urls like in Laravel

Published at: 12/16/2022
Updated at: 12/28/2022
Categories
Tags

Helper function for making multilingual urls on CodeIgniter 4

This can be useful when you have Named Routes for multiple languages. In general, you want to use the same route name for different languages, but to do this we have to prefix the language. Let's see how.

Writing the helper function route()

Let's create the file app/Helpers/route_helper.php:

// app/Helpers/route_helper.php

use CodeIgniter\Router\Exceptions\RouterException;

if (!function_exists('route')) {
    function route(string $routeName, ...$params) {
        $locale = service('request')->getLocale();
        $routes = service('routes');

        if (strpos($routeName, '{locale}') !== false) {
            $routeName = strtr($routeName, ['{locale}' => $locale]);
        } else {
            $routeName = $locale . '.' . $routeName;
        }
        
        $reverseRoute = $routes->reverseRoute($routeName, ...$params);

        if (!$reverseRoute) {
            throw RouterException::forInvalidRoute($routeName);
        }

        return $reverseRoute;
    }
}

If we use a route name like {locale}.posts.index or even just posts.index we will obtain the link to the named route, if it is configured in our routes list of course.

Registering the helper

Then we add the new helper in our BaseController.php:

// app/Controllers/BaseController.php
// other code...
protected $helpers = [
        // other helpers...
        'route'
    ];
// other code...

Setting the multilingual routes

The following is just an example of how you could set up your routes:

// app/Config/development/Routes.php
# English
$routes->group('en', function() use ($routes) {
    $routes->get('/', [HomeController::class, 'index'], ['as' => 'en.home']);

    $routes->get('posts', [PostController::class, 'index'], ['as' => 'en.posts.index']);
    $routes->get('posts/new', [PostController::class, 'new'], ['as' => 'en.posts.new']);
    $routes->get('posts/(:num)', [PostController::class, 'show/$1'], ['as' => 'en.posts.show']);
    $routes->post('posts/create', [PostController::class, 'create'], ['as' => 'en.posts.create']);
});

# Italian
$routes->group('it', function() use ($routes) {
    $routes->get('/', [HomeController::class, 'index'], ['as' => 'it.home']);

    $routes->get('annunci', [PostController::class, 'index'], ['as' => 'it.posts.index']);
    $routes->get('annunci/nuovo', [PostController::class, 'new'], ['as' => 'it.posts.new']);
    $routes->get('annunci/(:num)', [PostController::class, 'show/$1'], ['as' => 'it.posts.show']);
    $routes->post('annunci/crea', [PostController::class, 'create'], ['as' => 'it.posts.create']);
});

Creating the link to the named route in our views

Now we can create the link in the views:

// app/Views/Login/form.php
// We could make a form like this:
<?= form_open_multipart(route('login')) ?>
...
<?= form_close() ?>

// And links like this:
// app/Views/layouts/base.php
<ul class="navbar">
    <li>
        <a href="<?= route('home') ?>">Homepage</a>
    </li>
    <li>
        <a href="<?= route('posts.index') ?>">All posts</a>
    </li>
    <li>
        <a href="<?= route('posts.new') ?>">New post</a>
    </li>
</ul>

This way we can replicate on CodeIgniter 4 the same behaviour that Laravel offers with its own route() function.

Passing parameters to the route function

Since we added the possibility to have parameters, we can easily pass them like this:

<?= route('posts.show', $post->id) ?>

What do you think? Let me know in a comment below! If you like this article, follow me on Facebook and Youtube!

Leave a comment

All comments will be subject to approval after being sent. They might be published after several hours.

You can just use a random nickname, it is usefull to allow me to at least answer your comments. And if you choose to submit your email, you can receive a notification whenever I reply to your comment.

No comments have been written so far on this article. Be the first to share your thoughts!

*