20

I would like to know the simplest solution to changing the underscores of my codeigniter urls to dashes, for seo reasons.

My controllers look like:

public function request_guide() {
...Load view etc...
}

So to browse to this page I would have to go to:

www.domain.com/request_guide

But I want to be more seo friendly and use dashes instead of underscores, like so:

www.domain.com/request-guide

I am under the impression that codeigniter functions require underscores (might be wrong).

In previous projects I have simply used mod_rewrite but I believe that these actions can be performed using routes.

What is the easiest way for me to rewrite the urls replacing the underscores with dashes???

tereško
  • 58,060
  • 25
  • 98
  • 150
hairynuggets
  • 3,191
  • 22
  • 55
  • 90
  • 2
    `request-guide` is not more seo-friendly than `request_guide`. – lanzz Nov 08 '11 at 14:53
  • If you thik about it, that would match a class name, where a dash isn't valid; you would need, in fact, to write the class (or method) name as "request-guide", which is invalid php syntax. Go for a re-routing as suggested in answers below – Damien Pirsy Nov 08 '11 at 15:03
  • 4
    I was under the impression from google that they class dashes as spaces and words containing underscores as a whole word. – hairynuggets Nov 08 '11 at 15:04
  • 1
    @Ianzz request-guide is MUCH more seo-friendly than request_guide. Hyphens are extremely SEO friendly in URLs and Google interprets them as word separators. – Jason Raines Apr 29 '15 at 20:16

8 Answers8

51

It really depends on your intention. If you just want to change only one page, then devrooms' solution is the perfect one indeed:

$route['request-guide'] = "request_guide";

But if you want to make this your website's default behavior you should extend your core Router class like this (source: [Using hyphens instead of underscores in CodeIgniter])

  1. Make a new file in 'application/core' and name it 'MY_Router.php'
  2. Insert this code in it:

    <?php
    
    defined('BASEPATH') || exit('No direct script access allowed');
    
    class MY_Router extends CI_Router {
    
        function _set_request ($seg = array())
        {
            // The str_replace() below goes through all our segments
            // and replaces the hyphens with underscores making it
            // possible to use hyphens in controllers, folder names and
            // function names
            parent::_set_request(str_replace('-', '_', $seg));
        }
    
    }
    
    ?>
    

UPDATE (Oct 26, 2015): There's a better way to do this in CodeIgniter 3, as @Thomas Wood mentioned:

$route['translate_uri_dashes'] = TRUE;
Stan
  • 1,251
  • 1
  • 15
  • 24
  • this doesn't seem to working now. created the file as above but nothing happens. Any ideas? – LiveEn Mar 30 '13 at 05:36
  • @LiveEn You need to include it on every page. I suggest auto loading it. Also don't include the closing '?>'... it's bad practice. – lededje Apr 17 '13 at 17:59
  • 1
    I thought they were forcing closed PHP tags in PHP6? – marksyzm Apr 30 '13 at 09:18
  • this solution is great the only problem is that it doesn't disable **underscores (_)**; request-guide and request_guide now both work – Waqleh Apr 10 '15 at 11:15
  • an additional problem with this solution is that if you have anything that should have a dash in the url, say a parameter, it'll replace it with _ and that'll break any code which relies on the data using dashes and not underscore. so any extension to this idea which only acts on controller/methods would leave the "data" alone, would be better – Christopher Thomas Aug 07 '15 at 09:35
  • I think this might be a better solution: http://stackoverflow.com/questions/2428134/codeigniter-routes-regex-using-dashes-in-controller-method-names – Christopher Thomas Aug 07 '15 at 10:06
  • 2
    @christopher-thomas Thanks for the suggestion! I think that solution is too much writing for doing something that could be done with just one line of code. – Stan Aug 12 '15 at 13:54
  • 1
    the good thing about the link i suggested, is that it works ONLY on classes and methods, so it doesn't touch the other parts of the url, for example, if you have parameters on the end with - in them, they'll get converted too. This way only converts the parts which are needed, so even if it's a few more lines, it's actually more targetted and overall more complete – Christopher Thomas Aug 12 '15 at 21:16
  • 1
    shouldnt it be set to TRUE? – CodeGodie May 17 '16 at 13:18
29

Code Ignitor 3 has this in built:

$route['translate_uri_dashes'] = FALSE;

Just change to TRUE and you can use either _ or -.

Documentation

Thomas Wood
  • 799
  • 7
  • 12
  • I am not sure, but it still exists in the [documentation](http://www.codeigniter.com/user_guide/general/routing.html?highlight=translate_uri_dashes) (right down the bottom) – Thomas Wood Oct 11 '15 at 22:42
  • This seems **not to be working** if you have controllers inside directories or folders like `application/controllers/my_folder/About_us.php`. – CodeGodie May 20 '16 at 16:51
29

The routes config found in

config/routes.php

is your friend here.

A simple

$route['request-guide'] = "request_guide" ;

will do this for you.

devrooms
  • 3,119
  • 19
  • 24
10

Open application/config/routes.php and change

$route['translate_uri_dashes'] = TRUE;

Now when you access www.domain.com/**request-guide**, it will instantiate request_guide controller.

It will work with all controllers with name containing _ (underscore).

Usman Ahmed
  • 2,392
  • 1
  • 20
  • 17
2

Have a look at Codeigniter's custom routing http://codeigniter.com/user_guide/general/routing.html

Andrei Serdeliuc ॐ
  • 5,828
  • 5
  • 39
  • 66
2
$route['request-guide'] = "request_guide";
sdot257
  • 10,046
  • 26
  • 88
  • 122
1

What you could do is create a custom hook (PST... you need basic CodeIgniter skills): for more information regarding CodeIgniter Hooks - Extending the Framework Core

/*
 * the hooks must be enabled from the config file
 * replace underscore with dashes (hyphens) for SEO
 */

function prettyurls() {
    if (is_array($_GET) && count($_GET) == 1 && trim(key($_GET), '/') != '') {
        $newkey = str_replace('-', '_', key($_GET));
        $_GET[$newkey] = $_GET[key($_GET)];
        unset($_GET[key($_GET)]);
    }
    if (isset($_SERVER['PATH_INFO']))
        $_SERVER['PATH_INFO'] = str_replace('-', '_', $_SERVER['PATH_INFO']);
    if (isset($_SERVER['QUERY_STRING']))
        $_SERVER['QUERY_STRING'] = str_replace('-', '_', $_SERVER['QUERY_STRING']);
    if (isset($_SERVER['ORIG_PATH_INFO']))
        $_SERVER['ORIG_PATH_INFO'] = str_replace('-', '_', $_SERVER['ORIG_PATH_INFO']);
    if (isset($_SERVER['REQUEST_URI']))
        $_SERVER['REQUEST_URI'] = str_replace('-', '_', $_SERVER['REQUEST_URI']);
}

I named the file customhooks.php.

Then add this to the hooks.php file in application/config:

$hook['pre_system'] = array(
    'class' => '',
    'function' => 'prettyurls',
    'filename' => 'customhooks.php',
    'filepath' => 'hooks',
    'params' => array()
);

You will need to edit your application/config/config.php file to enable hooks

$config['enable_hooks'] = TRUE;

EXTRA:

so that when you use $this->uri->uri_string() it stays hyphenated do the following Creating Core System Classes

class MY_URI extends CI_URI {

    function uri_string() {
        return str_replace('_', '-', $this->uri_string);
    }

}
Waqleh
  • 9,741
  • 8
  • 65
  • 103
0

You can use this _remap() method to handle such behavior. Place this method in your controllers or create a core controller and place it in.

public function _remap($method, $params = array()){
    if(method_exists($this, $method)){
        return call_user_func_array(array($this, $method), $params);
    }else{
        $method = str_replace("-", "_", $method);
        if(method_exists($this, $method)){
            return call_user_func_array(array($this, $method), $params);
        }
    }
    show_404();
}
Sajjad Ashraf
  • 3,754
  • 1
  • 34
  • 35