FusionCMS is currently in an open beta state and under heavy active development.

Theme Routing

Routes are URL patterns that can map to specific view templates, return data as and api endpoint and more! Routes can be set to explicit values or set to match a dynamic pattern. Customized routes can be configured through your theme with the use of a route service provider.

FusionCMS utilizes Laravel's native routing system. Though we'll be covering much of what's in Laravel's routing documentation here for quick reference and convenience, please be sure to check out their official docs for full context and details on working with routing.

Creating a Route Service Provider

If you're not yet familiar with setting up service providers for your theme, please see our documentation before proceeding.

We can extend the FusionCMS route service provider by creating a new src/Providers/RouteServiceProvider.php file in your theme.

// Please replace {MyTheme} with the namespace of your theme
<?php

namespace Themes\{MyTheme}\Providers;

use Illuminate\Support\Facades\Route;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;

class RouteServiceProvider extends ServiceProvider
{
    /**
     * This namespace is applied to your controller routes.
     *
     * In addition, it is set as the URL generator's root namespace.
     *
     * @var string
     */
    protected $namespace = 'Themes\{MyTheme}\Http\Controllers';

    /**
     * Define your route model bindings, pattern filters, etc.
     *
     * @return void
     */
    public function boot()
    {
        parent::boot();
    }

    /**
     * Define the routes for the application.
     *
     * @return void
     */
    public function map()
    {
        $this->mapApiRoutes();

        $this->mapWebRoutes();

    }

    /**
     * Define the "web" routes for the application.
     *
     * These routes all receive session state, CSRF protection, etc.
     *
     * @return void
     */
    protected function mapWebRoutes()
    {
        Route::middleware('web')
            ->namespace($this->namespace)
            ->group(__DIR__ . '/../../routes/web.php');
    }

    /**
     * Define the "api" routes for the application.
     *
     * These routes are typically stateless.
     *
     * @return void
     */
    protected function mapApiRoutes()
    {
        Route::prefix('api')
            ->middleware('api')
            ->namespace($this->namespace)
            ->group(__DIR__ . '/../../routes/api.php');
    }
}

Register this new service through your src/Providers/ThemeServiceProvider.php file.

// Please replace {MyTheme} with the namespace of your theme
<?php

namespace Themes\{MyTheme}\Providers;

use Illuminate\Support\ServiceProvider;

class ThemeServiceProvider extends ServiceProvider
{
    public function boot()
    {}

    public function register()
    {
        $this->app->register(RouteServiceProvider::class);
    }
}

Routing Files

There are two types of routes we can define here, web routes and api routes.

Web routes can be added and configured through a routes/web.php file in your theme and assume a web interface. These routes are assigned the web middleware group, which provides features like session state and CSRF protection. The routes defined in routes/web.php may be accessed by entering the defined route's URL in your browser.

Api routes can be added and configured through a routes/api.php file in your theme and extend the FusionCMS api. The routes in routes/api.php are stateless and assigned the api middleware group. The /api URI prefix is automatically applied to these routes so you do not need to manually apply it for each one.

Routing Methods

The most basic routes accept a URI and a Closure, providing a very simple and expressive method of defining routes:

Route::get('hello', function () {
    return 'Hello World';
})

HTTP Verbs

The router allows you to register routes that respond to any HTTP verb

Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);

Any HTML forms pointing to POSTPUTPATCH, or DELETE routes that are defined in the web routes file should include a CSRF token field. Otherwise, the request will be rejected. You can read more about CSRF protection in Laravel's CSRF documentation:

<form method="POST" action="/profile">
    @csrf
    ...
</form>

Match

Sometimes you may need to register a route that responds to multiple HTTP verbs. You may do so using the match method.

Route::match(['get', 'post'], '/', function () {
    //
});

Any

You may even register a route that responds to all HTTP verbs using the any method:

Route::any('/', function () {
    //
});

Redirects

If you are defining a route that redirects to another URI, you may use the Route::redirect method. This method provides a convenient shortcut so that you do not have to define a full route or controller for performing a simple redirect:

Route::redirect('/here', '/there');

By default, Route::redirect returns a 302 status code. You may customize the status code using the optional third parameter:

Route::redirect('/here', '/there', 301);

You may use the Route::permanentRedirect method to return a 301 status code:

Route::permanentRedirect('/here', '/there');

Views

If your route only needs to return a view, you may use the Route::view method. Like the redirect method, this method provides a simple shortcut so that you do not have to define a full route or controller. The view method accepts a URI as its first argument and a view name as its second argument. In addition, you may provide an array of data to pass to the view as an optional third argument:

Route::view('/welcome', 'welcome');

Route::view('/welcome', 'welcome', ['name' => 'Taylor']);

Fallbacks

Using the Route::fallback method, you may define a route that will be executed when no other route matches the incoming request. Typically, unhandled requests will automatically render a "404" page via your application's exception handler. However, since you may define the fallback route within your routes/web.php file, all middleware in the web middleware group will apply to the route. You are free to add additional middleware to this route as needed:

Route::fallback(function () {
    //
});
  • The fallback route should always be the last route registered by your theme.

Route Parameters

Sometimes you will need to capture segments of the URI within your route. For example, you may need to capture a user's ID from the URL. You may do so by defining route parameters:

Route::get('user/{id}', function ($id) {
    return 'User '.$id;
});

You may define as many route parameters as required by your route:

Route::get('posts/{post}/comments/{comment}', function ($postId, $commentId) {
    //
});

Route parameters are always encased within {} braces and should consist of alphabetic characters, and may not contain a - character. Instead of using the - character, use an underscore (_). Route parameters are injected into route callbacks / controllers based on their order - the names of the callback / controller arguments do not matter.

Optional Parameters

Occasionally you may need to specify a route parameter, but make the presence of that route parameter optional. You may do so by placing a ? mark after the parameter name. Make sure to give the route's corresponding variable a default value:

Route::get('user/{name?}', function ($name = null) {
    return $name;
});

Route::get('user/{name?}', function ($name = 'John') {
    return $name;
});

Regular Expression Constraints

You may constrain the format of your route parameters using the where method on a route instance. The where method accepts the name of the parameter and a regular expression defining how the parameter should be constrained:

Route::get('user/{name}', function ($name) {
    //
})->where('name', '[A-Za-z]+');

Route::get('user/{id}', function ($id) {
    //
})->where('id', '[0-9]+');

Route::get('user/{id}/{name}', function ($id, $name) {
    //
})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);

Global Constraints

If you would like a route parameter to always be constrained by a given regular expression, you may use the pattern method. You should define these patterns in the boot method of your RouteServiceProvider:

/**
 * Define your route model bindings, pattern filters, etc.
 *
 * @return void
 */
public function boot()
{
    Route::pattern('id', '[0-9]+');

    parent::boot();
}

Once the pattern has been defined, it is automatically applied to all routes using that parameter name:

Route::get('user/{id}', function ($id) {
    // Only executed if {id} is numeric...
});

Encoded Forward Slashes

The routing component allows all characters except /. You must explicitly allow / to be part of your placeholder using a where condition regular expression:

Route::get('search/{search}', function ($search) {
    return $search;
})->where('search', '.*');

Encoded forward slashes are only supported within the last route segment.

Have questions?

We're always happy to help with code or other questions you might have. Contact support or chat live with us on Discord.

Last edited on Thursday, July 16, 2020 (1 year ago)