Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
How to disable 'routed mode' for modules?
  • On the FuelPHP documentation located here http://fuelphp.com/docs/general/modules.html it states:

    "When you use modules in routed mode,..."

    This implies there's a non-routed mode for modules.

    Basically i don't want fuel to route to modules automatically, i have implemented a basic 'bootstrapping' system for modules, and i explicitly define the routes for my modules in the bootstrap files.

    This works but when i enter the default route / url for the module like:  /myrealmodulename/controllername/method it still loads my module, my custom route defined in my bootstrapping files also works, but i want to stop FuelPHP from automatically routing to my modules, how do i disable this behaviour?

    I have read over the documentation several times and i am pretty sure i've not missed it, it's just not mentioned on there apart from in the link supplied above. Is there a way to disable automatic routing?
  • Eh, well, no, it was meant to be "as opposed to HMVC calls to a module".

    If you have modules, but you don't want them to be routed to, what exactly do they do? Are they serving HMVC calls only?
  • Some of the modules are HMVC, like sidebar and dashboard 'widgets', i know i can do a check to see if it's a HMVC request, but i have other modules which aren't HMVC, and that's where i'm really running into problems.

    Basically it's so i can have control over the URL's, for example i have a 'settings' controller in my application, which can be accessed via /settings/. Then i have 'content_pages' as a module, the bootstrap file for that module hooks into an API i've built for my system, so it can add itself to the navigation structure, define it's routing, add 'widgets' to the system etc...

    The content_pages module also has a 'settings' section, which would normally be accessed via something like: /content_pages/pages/settings which isnt ideal, by defining the routing manually i can change that url to /settings/content/pages/. I also have other modules like content_forums, content_blog, content_kb, content_galleries etc.. as well as a 'content' module, i would route things like this:

    content = /content

    content_pages/pages = /content/pages
    content_pages/pages/add = /content/pages/add
    content_pages/pages/settings = /settings/content/pages

    content_forums/forums = /content/forums
    content_forums/forums/topics = /content/forums/topics
    content_forums/forums/topics/add = /content/forums/topics/add
    content_forums/forums/settings = /settings/content/forums

    i can currently achieve the routing above, but all of these requests will be non-HMVC, so filtering them out with a HMVC check won't be possible, it's also a pain if i have to check for this in every single controller using code, so disabling the automatic routing seems like the easiest option, i don't mind defining the routes manually. 

    The other advantage is i'm assigning a unique name to each route, this means if i need to write a plugin for a client in the future that needs to change that route to a custom controller for example, i can do this easily without having to change the core systems code, rather then trying to make everything work through the automatic routing.
  • I'm a bit confused.

    How can you route manually without it being HMVC? Are you calling controllers cross-module yourself?

    This is exactly what Fuel's routing system is designed to do, so I'm completely puzzled why you would have something custom for it.

    Our application framework does something similar, but it just loads the routes table from the database (and caches it so it doesn't hit the db every page request).

    It then uses standard Fuel routing to do what you're doing, and it ends the routing table with a route:

    '*' => 'base/404',

    which routes all requests not matched to a route to our 404 controller.

    We have added a bootstrap to modules (easy by overloading the Module controller load() method, and look in Package::load() to see how a bootstrap is loaded), and every module has a setup controller that allows the site admin to add the module to the app, or remove it (similar to what you call plugin).
  • From what i understand, to get the routes i want using the automatic routing in Fuel i would have to lay my files out like this:

    application/
    modules/
    pages/
    classes/
    controller/
    pages.php (containling methods for CRUD)
    settings/
    classes/
    controller/
    settings.php (top 'settings page')
    pages.php (settings page for 'pages' functionality)

    I know you can specify routes using config files inside each module, but from what i understood the routes in modules/pages would only be 'auto-loaded' when the user navigates to /pages. The routes for each module in my application all need to be accessible by other modules.

    My aim is to keep everything, including the 'settings' page inside the 'page' module.

    Is my understanding of the above wrong? If so this could be where im getting lost.

    The reason i have named my modules in this way:

    application/
    modules/
    content/
    content_pages/
    content_blog/
    content_forums/ etc...

    is purely for organisational and reading purposes, the 'content' area of this system will have between 10-15 modules in total, and the 'content' area is just one of 20'ish areas in the system, it makes it easier for me to manage.

    These modules could be added / removed in any combination depending on the clients needs, the clients themselfs wont be installing the 'modules' or 'plugins' as i've refered to them above, so there is no need for any setup controllers, this will all be handled by a dev team.

    I tried your suggestion about the 404 in the routes config, but i get the following error:

    "preg_match(): Compilation failed: nothing to repeat at offset 1"

    the routes.php file contains:

    <?php
    return array(
    '_root_' => 'login', // The default route
    '_404_' => 'errormsg/show404', // The main 404 route
    '*'=>'errormsg/show404'
    );

    errormsg is a simple controller that shows some of the error pages.
    i have also tried setting it to 'base/404' and get the same error. I was hoping this would route any undefined & unmatched routes to a 404 page, is this what was meant to happen?

    I hope this makes sense, i don't explain things very well sometimes :P

  • So if I understand it correctly, you have modules each having their own settings controller, but you want it to appear all under the same /settings/... URI structure?

    So you want to route /settings/modulename/bla/bla to /modulename/settings/bla/bla ?

    As to the route, sorry for the typo. It should be a regex, so it's missinng the dot: ".*" in front of the star.
  • The way you've described the routing is how i want the routing to go, more or less, there will be some differences later down the road, i am currently doing this by defining the routes manually (but not in the routes.php file), and also assigning each route a 'name' so it's easier to grab later on. This works fine, but when i go to /content_pages/pages/add i still get the page load up rather then a 404, which makes sense because it's the 'automatic' route, this is what i'm trying to change.

    I changed my code to include the dot, which has resolved the PHP error, but now everything, including my custom routes points towards the 404 page, i'm not sure why, but i think it's because the route is defined in application/config/routes.php and is loaded very early on, before any of my custom routes are loaded, so it's always the first one to match.
  • HarroHarro
    Accepted Answer
    Ok, so that is easy:

    'settings/(:segment)(:any)' => '$1/settings$2',

    So, like in a regex, you can create back references in your routes, where $1 point to the first regex in brackets, and $2 to the second one. This allows you to reorder segments.

    the ".*" catch-all route must be the last route in your routes definition. Routes are processed sequentially, so once it gets to the ".*" route, everything matches and all others will never be checked anymore.

    I don't know what you mean by "custom routes", and how you define them, so I can't comment on that atm. You need to explain how you define custom rules, and possibly alter the way you define them.

    If all else fails, you can always overload the Router class, the parse_match() method. If you check the core class, you'll see it checks if the first segment is a module. Copy the method to your overloaded class, and remove that if. Now auto-routing to modules is no longer possible at all...
  • I think i may have found a work-around, the custom routes are defined during the module bootstrapping process, which takes place in application/bootstrap.php,

    i removed the ".*" route from the routes.php and added this after the module bootstrapping code using:

    Router::add('.*', 'errormsg/show404');

    Now my defined routes work fine, and the automatic routing seems to redirect to a 404 page as i wanted :) I will have to try and not define routes after this point in the code, otherwise i suspect i will run into issues.

    Another other nice advantage is now all the modules which are 'widgets', which are basically partials and only called via HMVC are now also non-routable via the browser, but still work fine during a HMVC call, so i don't need to have if() statements in all of them to check for whether it's a HMVC request or not :D

    If there's any big downsides to using this method that i'm not seeing?

    Thank you for helping me find a solution though Harro, you've been awesome.
  • Brillant find! Hadn't even thought of that solution.

    Happy coding... ;-)

Howdy, Stranger!

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

In this Discussion