views:

812

answers:

4

looking for a one line route to route dashed controller and method names to the actual underscored controller and method names.

url

/controller-name/method-name-which-is-long/

would route to

/controller_name/method_name_which_is_long/

see: http://codeigniter.com/forums/viewreply/696690/ which gave me the idea to ask :)

A: 

I'm not sure if you could do that with a route...

However, somewhere in the Codeigniter core libraries (possibly Router or URI) will be something that converts the underscored uris into a camelcase class name.

I had a quick look and couldn't find it, but if you do, just copy that library to your application/libraries folder, and modify it there.

Josh
+1  A: 

I believe what you are looking for is a either a pre-system or else a pre-controller hook that will take the requested URI and update it.

Sean Vieira
+7  A: 

That is exactly my requirement too and I was using routes like

$route['logued/presse-access'] = "logued/presse_access";

In my previous project I needed to create 300-400 routing rules, most of them are due to dash to underscore conversion.

For my next project I eagerly want to avoid it. I have done some quick hack and tested it, though have not used in any live server, its working for me. Do the following..

Make sure the subclass_prefix is as follows in your system/application/config/config.php

$config['subclass_prefix'] = 'MY_';

Then upload a file named MY_Router.php in system/application/libraries directory.

<?php

class MY_Router extends CI_Router { 
    function set_class($class) 
    {
        //$this->class = $class;
        $this->class = str_replace('-', '_', $class);
        //echo 'class:'.$this->class;
    }

    function set_method($method) 
    {
//      $this->method = $method;
        $this->method = str_replace('-', '_', $method);
    }

    function _validate_request($segments)
    {
        // Does the requested controller exist in the root folder?
        if (file_exists(APPPATH.'controllers/'.str_replace('-', '_', $segments[0]).EXT))
        {
            return $segments;
        }
        // Is the controller in a sub-folder?
        if (is_dir(APPPATH.'controllers/'.$segments[0]))
        {       
            // Set the directory and remove it from the segment array
            $this->set_directory($segments[0]);
            $segments = array_slice($segments, 1);

            if (count($segments) > 0)
            {
                // Does the requested controller exist in the sub-folder?
                if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().str_replace('-', '_', $segments[0]).EXT))
                {
                    show_404($this->fetch_directory().$segments[0]);
                }
            }
            else
            {
                $this->set_class($this->default_controller);
                $this->set_method('index');

                // Does the default controller exist in the sub-folder?
                if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$this->default_controller.EXT))
                {
                    $this->directory = '';
                    return array();
                }

            }

            return $segments;
        }

        // Can't find the requested controller...
        show_404($segments[0]);
    }
}

Now you can freely use url like http://example.com/logued/presse-access and it will call the proper controller and function by automatically converting dash to underscore.

sumanchalki
+1 that's the solution, it is almost the same way used to get command line arguments properly routed to controller methods
Benoit
+1  A: 
<?php
class MY_Router extends CI_Router
{
 function _set_request($segments = array()) {
  parent::_set_request(str_replace('-', '_', $segments));
 }
}
?>

Put this file MY_Router.php inside /application/libraries (CI1) or /application/core (CI2) Remember that this will effect all segments, not only module, controller and method.

Alternative to this extend is to add each segment to router.php $route['this-is-a-module-or-controler'] = 'this_is_a_module_or_controller';

As you can see the extend method would be easier to use. You can choose to make the function also to handle only the first two or three segments so that the other segments are not affected with the _ replacement.

e-mike