Welcome Guest, Not a member yet? Register   Sign In
So close with a mod_rewrite that changes underscores to hyphens for SEO. Can anyone close it out?


I've been using CI for a while and love it. However, many clients are asking for hyphens in URLs instead of underscores which helps with SEO. I partner with two SEO firms, both of which confirm while having hyphens over underscores is not monumental it does help.

As you know, CI controllers must use underscores as hyphens will not work. I have a mod_rewrite in place that ALMOST works in getting everything converted. Yet the first hyphen in a URL (for the class name) doesn't work. The mod_rewrite looks like this:

Options +FollowSymLinks
RewriteEngine On
RewriteBase /

RewriteRule ([^-]*)-([^-]*)-([^-]*)-?([^-]*)-?([^-]*)-?([^-]*)-?([^-]*)-?([^-]*)-?([^-]*) $1_$2_$3_$4_$5_$6_$7_$8_$9 [L]
RewriteRule ^(.*?)__+(.*) $1$2 [L]
RewriteCond $1 !^(index\.php|css|emails|favicon\.php|flash|img|p\.php|public|scripts|robots\.txt|tmp)
RewriteRule ^(.*)$ index.php?$1 [L]

The issue is that:


throws a 404 while:


does not. So even though a class name works fine when the URL contains children segments, it does not when it's loaded on its own.

If anyone knows how to get CI controllers to behave when hyphens are used instead of underscores, I would GREATLY appreciate the advice.

Thanks in advance for your time.

Does class-name/index work for any of them?

You mean /class-name/index.php ? No, that also throws a 404.

While I don't quite understand why hyphens are more SEO friendly than underscores, I wonder if other characters would suffice for your SEO purposes. If your controllers/functions have underscores you can substitute them with periods or pluses (and probably a few others) in the URL and CI translates automatically, no mod_rewrite needed. Just a though, maybe it'll save you some time and server overhead.

Based on what I've read, it appears that it doesn't have a huge impact one way or the other. That said, Matt Cutts (Google software engineer) just recently mentioned (http://www.youtube.com/GoogleWebmasterHe...3SFVfDIS5k) that while it doesn't make much sense to convert a site from underscores to hyphens, it would be best to use hyphens with any new development. Coupled with a client's request to use hyphens, it's time to figure out how to get CI to oblige.

Does anyone have suggestions about how to get hyphens to work with CI's class names using mod_rewrite? What I posted seems to work with any given URL segment except for the class name (first segment).

Also, thanks for the suggestion about using dots or plus signs. While they may save some time/overhead, as you've mentioned, they won't help at all for SEO purposes.

hi if you want to replace _ with - you can use CI route check this user guide


Finally solved...

First create a "pre-system" hook by adding these lines to your 'config/hooks.php' file:
$hook['pre_system'] = array(
    'class'    => '',
    'function' => 'prettyurls',
    'filename' => 'myhooks.php',
    'filepath' => 'hooks',
    'params'   => array()

Now create a 'myhooks.php' file within the 'application/hooks' folder and add this function (don't forget to open a PHP tag if this is the first hook):
function prettyurls() {
    if (is_array($_GET) && count($_GET) == 1 && trim(key($_GET), '/') != '') {
        $newkey = str_replace('-','_',key($_GET));
        $_GET[$newkey] = $_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']);

You will probably need to edit your 'config/config.php' file to enable hooks (around line 91 for me):
$config['enable_hooks'] = TRUE;

Good luck.

[eluser]Joshua Logsdon[/eluser]
Another solution is here, using one small MY_Router.php file in application/libraries/ with an updated function to override the issue at the source:

b3nst3wart, I've been looking all over trying to figure this out. Your solution worked perfectly! Thanks for sharing!

Here is my solution

Theme © iAndrew 2016 - Forum software by © MyBB