Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
Dynamic 404 route
  • I have a question regarding 404 routes. I have a site where I have a few different modules. For example, I have an admin module, and it has it's own routes.php file that defines it's _404_ controller, which in turn displays the admin module's 404 view.

    Now, where things get tricky for me is in the default 404 routes. I have 2 modules (corppage and clientsite) that share the default routes.php file. The corppage module defines all of our company's static pages. The default 404 route points to the 404 method in the corppage module's httpexception controller. This works perfectly fine.

    The clientsite module is dynamic based on the first URI segment. Long story short, customers can setup their own site using our platform and define their own URI that gets appended to our domain. For example: https://mydomain.com/my-uri. Based on the first URI segment, I fetch their site from the database and display specific pages for their site. Here is an example of my default routes.php file:

    $routes['_root_'] = 'corppage/corppage/index';
    $routes['_403_'] = 'corppage/httpexception/403';
    $routes['_404_'] = 'corppage/httpexception/404';
    $routes['_500_'] = 'corppage/httpexception/500';
    $routes['about'] = 'corppage/corppage/about';
    $routes['contact'] = 'corppage/corppage/contact';
    $routes['terms'] = 'corppage/corppage/terms';
    $routes['privacy'] = 'corppage/corppage/privacy';
    $routes['(:segment)'] = 'clientsite/index/story/$1';
    $routes['(:segment)/events'] = 'clientsite/tickets/events/$1';
    $routes['(:segment)/donate'] = 'clientsite/index/donate/$1';
    $routes['(:segment)/cart'] = 'clientsite/ecommerce/cart/$1';
    $routes['(:segment)/(:any)'] = 'clientsite/index/custom_page/$1';

    If a clientsite is not found in the database, I can easily throw a HttpNotFoundException which routes to my corppage's httpexception controller and displays the 404 page accordingly (meaning the client site was not found). The issue arises when our clients create custom pages (see my last route above).
    A client can define a custom page for their site and define URI segments for it that fall under their main URI segment. For example, a client can create a custom about page and define the URL https://mydomain.com/my-uri/about-us for it. I should also note that our clients have custom headers and footers so that their sites have unique branding and they do not look like our corppages.

    Now, if somebody goes to a clientsite URL that doesn't exist, https://mydomain.com/my-uri/XXX, a 404 will be thrown, however it's the 404 page for our corppage module which uses our company's branding, not the client's branding because the code runs through the corppage module. All of the clientsite branding is lost as it is done through the clientsite base controller once the site is found in the database.

    Is there anyway that I can change thew 404 route "on the fly" to point to a clientsite module's controller instead of the corppage module's httpexception controller so that I can keep all of my clientsite base logic (bradning, etc) intact?
  • HarroHarro
    Accepted Answer
    There is only one route table, so you can't have unique per-module routes.

    What should be possible is to have a per-module base controller (one that all controllers in that module extend), and in its constructor replace the _404_ route in the router. so construct a Route object, and then call Router::add('_404_', $mymodroute).

    You'll probably have to do some Router debugging to see how it is exactly stored and how this can be done, I haven't tried this yet, so I'm writing this from memory.

    We don't use routes at all, we basically have a single :any rule that points to a custom loader controller, which uses HMVC to load the page found in the database, and handles any errors that occur alone the way. So we don't have this issue...

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion