Don’t wait until your customer or … your browser(!) start to mention that your URL is way to big from the usually title.
Well the first thing that you realize when you install Codeigntier is that the URLs are really huge, not SEO friendly and not user friendly.
Let’s try to minimize as much as we can for your dynamic created URLs. Below we will explain and give solutions to minimize the URLs as much as possible with htaccess, some route tricks and the _remap() method of Codeigniter.
1. Removing the index.php
Let’s start with our big URL:
http://mycustomproject.com/index.php/webpages/view/my-url-title-of-the-post
The first thing that you usually do for your Codeigniter project is to remove the index.php file from the URL. To do it so, it’s really easy:
1st step
Add this code to your .htaccess file to your root of your project.
<IfModule mod_rewrite.c> # Turn on URL rewriting RewriteEngine On # If your website begins from a folder e.g localhost/my_project then # you have to change it to: RewriteBase /my_project/ # If your site begins from the root e.g. example.local/ then # let it as it is RewriteBase / # Protect application and system files from being viewed when the index.php is missing RewriteCond $1 ^(application|system|private|logs) # Rewrite to index.php/access_denied/URL RewriteRule ^(.*)$ index.php/access_denied/$1 [PT,L] # Allow these directories and files to be displayed directly: RewriteCond $1 ^(index\.php|robots\.txt|favicon\.ico|public|assets|css|js|images) # No rewriting RewriteRule ^(.*)$ - [PT,L] # Rewrite to index.php/URL RewriteRule ^(.*)$ index.php/$1 [PT,L] </IfModule>
After the creation of the .htaccess file your project structure will have to look like this:
website_folder/ –––– application/ –––– assets/ –––– system/ –––– user_guide/ ---- .htaccess <------------------------- –––– index.php –––– license.txt
2nd step
Now go to : application/config/config.php and change the:
to
So now your URL will look like this:
http://mycustomproject.com/webpages/view/my-url-title-of-the-post
Note 1: If you are running in your local machine and your don't have configured the virtual host for example to be :
http://mycustomproject.com/webpages/view/my-url-title-of-the-post
but your URLs looks more than this:
http://localhost/website_folder/webpages/view/my-url-title-of-the-post
don't forget to change your RewriteBase from:
to
or something similar it depends of where your Codeigniter project starts.
Note 2: In some cases perhaps you will realize that your .htaccess simply doesn't work and all the webpages URLs show the index webpage. If this happens to you then go to application/config/config.php and change the:
to:
or:
it depends of your server's configuration. To try it just change it and see if the URL works for you correctly
Note 3: If you prefer to add a less secure .htaccess for your project, much more minimal and you don't want to write each time the exceptions of the files that you don't want to included them to the rules, you can simply use this code:
<IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule>
This is the most common .htaccess (it is also used from the default installation of WordPress) thought it is not suggested as you don't protect your folders if the index.php is missing or a new file/folder is added to your project without knowing it.
2. Removing 1st URL segment
So now that we removed the annoying index.php from URL let's minimize our URLs with the routes.
Our basic example that we will work with is the below:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); class Webpages extends CI_Controller { function __construct() { parent::__construct(); } function index() { } function about() { } function blog($url_title = '') { } function view($url_title = '') { } }
To remove our first segment we have to choose which our base Controller will be. In our case we will choose that Webpages will be our basic Controller. The Controllers Admin and Forums will be our secondary let's say Controllers
There are two ways to minimize your URLs:
- Routing by hand
- Routing automatically (I always prefer this one)
Routing by hand
So let's see how we can can minimize our URLs by hand. This means that everytime we add or edit a function at our Controller we have to go to : application/config/routes.php
and change the routes in each case. So let's have an example of our basic controller:
Go to application/config/routes.php and add something like this:
$route['default_controller'] = 'webpages'; //Our default Controller //Get rid of the first segment (in our case we get rid of webpages) $route["about"] = 'webpages/about'; $route["blog/(.*)"] = 'webpages/blog/$1'; $route["view/(.*)"] = 'webpages/view/$1';
So now with this simple code we have get rid of the first controller name from our basic webpages.
Routing automatically
Many of you probably already know it but it is really boring to create the routes every time by hand. So that's why I created an automatically routing that actually removes the controller of your default controller. The below code is written to handle all the scenarions. Simple URLs and multilingual URLs. Let's go and take a look of our routes how it will look like.
If you don't have a multilingual website the routes are easy. You can simply copy the below code to application/config/routes.php:
$default_controller = "webpages"; $controller_exceptions = array('admin','forums'); $route['default_controller'] = $default_controller; $route["^((?!\b".implode('\b|\b', $controller_exceptions)."\b).*)$"] = $default_controller.'/$1'; $route['404_override'] = '';
If you are having a multilingual website, it is a bit more complicated as you have lot of scenarios to cover. However don't worry about it as you can simply copy the below lines of code to application/config/routes.php:
$default_controller = "webpages"; $language_alias = array('gr','fr'); $controller_exceptions = array('admin','forums'); $route['default_controller'] = $default_controller; $route["^(".implode('|', $language_alias).")/(".implode('|', $controller_exceptions).")(.*)"] = '$2'; $route["^(".implode('|', $language_alias).")?/(.*)"] = $default_controller.'/$2'; $route["^((?!\b".implode('\b|\b', $controller_exceptions)."\b).*)$"] = $default_controller.'/$1'; foreach($language_alias as $language) $route[$language] = $default_controller.'/index'; $route['404_override'] = '';
So let me explain how it works.
The only thing that you will actually care to change is the first three lines of code:
$default_controller = "webpages"; $language_alias = array('gr','fr'); $controller_exceptions = array('admin','forums');
As it is the only one that you actually need to change. So how it works? It's really easy.
You add your default controller to your variable $default_contoller.
The $language_alias is the language element that you want to add if you have a multilingual website for example:
http://mycustomproject.com/blog
http://mycustomproject.com/gr/blog
http://mycustomproject.com/fr/blog
And of course the http://mycustomproject.com/gr and http://mycustomproject.com/fr are routing to the index of your basic Controller.
The $controller_exceptions are the controllers that will NOT follow this routing structure. For example:
http://mycustomproject.com/admin/
http://mycustomproject.com/forums/
So you can easily use the controller with name Admin and controller with name Forums with the same way as you used it before.
Now we removed our first segment so our dynamic URLs will look like this:
- http://mycustomproject.com/about
- http://mycustomproject.com/view/my-url-title-of-the-post
- http://mycustomproject.com/blog/url-title-of-post
3. Removing 2nd URL segment
One way to do it is by using the _remap() method of Codeigniter. For more go to Controllers User Guide and search for the _remap() method. Let's have an example of how to use it:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); class Webpages extends CI_Controller { function __construct() { parent::__construct(); } function _remap() { $segment_1 = $this->uri->segment(1); switch ($segment_1) { case null: case false: case '': $this->index(); break; case 'about': $this->about(); break; case 'blog': $this->blog($this->uri->segment(2)); break; default: //This is just an example to show //the 404 page if the page doesn't exist $this->db->where('url_title',$segment_1); $db_result = $this->db->get('webpages'); if($db_result->num_rows() == 1) { $this->view($segment_1); } else { show_404(); } break; } } function index() { } function about() { } function blog($url_title = '') { } function view($url_title = '') { } }
So when you are using the _remap function of Codeigniter you have to decide which method will use every time. The good part is that you will have full control of what to do with each method. However it can take lot of time if you have many functions in your controller. So now your URLs will look like this:
- http://mycustomproject.com/my-url-title
- http://mycustomproject.com/about
- http://mycustomproject.com/blog/url-title-of-post
Are you done with reading? Well you can now download the files that we used at this post or you can view the files from github
Lsg2
Super!
Thx
How about short links in Laravel?
Mahmoud Mohamed Ali
very nice
gonna try it
thank you
Zaman A Piri Pasa
nice article 🙂
Qsr
…
case ‘about’:
$this->search(); // <= it is correct?
…
web_and_development
You are right thank you for that.
Sheikh
how about if we want to use more than one controller?
Muhammad Owais Akbar
very nice article i need this today i will implement this Inshallah
Ram krishna dhakad
This is working for me.Thank You.
Satnam Singh
Really Awesome !!! Thanks !!!!!!
Jean-Pierre
OMFG this saved me sooo much time && grief. Way to be thorough by the by. You sir are a gentleman and a scholar.
Fathur Rohman
thank you for ur tutorial, very helpfull
jawwad ahmed
sooooooooooooper
frz
great post, helped me alot
Prabu Karana
Thanks it work, but my css doesnt running.. if i put .htaccses how i write my css
this my code
<link rel="stylesheet" href="css/style.css” type=”text/css” media=”screen” />
web_and_development
You can add your folders at the:
# Allow these directories and files to be displayed directly:
RewriteCond $1 ^(index.php|robots.txt|opensearch.xml|favicon.ico|assets|forums)
for example in your case you can have:
# Allow these directories and files to be displayed directly:
RewriteCond $1 ^(index.php|css|js|images|robots.txt|opensearch.xml|favicon.ico|assets|forums)
Prabu Karana
It Work, Thx a lot man….
hien
thank!
hien
hi. Thank for post
It work with me. But i have a little problem.
My structure folder:
root
— application
— system
— public
——css
———-style.css
When i change like u. My website find path of the css file.
please help me.
sorry, my english is bad
hein
In the view. i config path of the css:
<link rel="stylesheet" href="/public/default/css/style.css” type=”text/css” />
hien
sorry. My website can not find path of the css file
web_and_development
Guys it is pretty clear that you can add as many folders you like as an exception. For example in your case you will have:
# Allow these directories and files to be displayed directly:
RewriteCond $1 ^(index.php|robots.txt|opensearch.xml|favicon.ico|css|js|images|public)
So for example if at the future you want to add the folder let’s say “forums” you can do it like this:
# Allow these directories and files to be displayed directly:
RewriteCond $1 ^(index.php|robots.txt|opensearch.xml|favicon.ico|css|js|images|public|forums)
and so on…
prabukarana
hey bro, when i upload website. i have problem, website will be 404 not found.
example helloworld.com, how should i write my RewriteBase / … ?
web_and_development
Can you please be more specific? What did you try? Did you try to remove the .htaccess to see if this is causing the 404 not found? Moreover is your website with this structure? localhost/helloworld . If yes you have to change the RewriteBase / to RewriteBase /helloworld
prabukarana
i’ve been solved that…
i wrote this in my web directory in server..
RewriteEngine On
RewriteBase /
RewriteRule ^index.php$ – [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
blank my rewritebase.. and it work, btw thx bro…
akhunzada
i do all the steps as you mention but
Not Found
The requested URL /codeIgniter/welcome/khan was not found on this server.
display this message
web_and_development
Hello there, can you try “RewriteBase /codeigniter/”
rdiksa
hay, i can remove the annoying index.php . i’ve followed your tutorial step by step. does any version of XAMPP efects your method?
rdiksa
sori misstype, i mean “i can not remove the anoying index.php”
web_and_development
You have to enable the mod_rewrite in order to make it work. You can check this small tutorial of how to it so http://www.leonardaustin.com/technical/enable-mod_rewrite-in-xampp
pujiew
thanks, good post
Razvan
Can you explain me how can I redirect from web pages Controller to admin Controller? redirect(admin/home); didn’t work for me
Tanks!
ayan sil
thanks for this post. it’s a great post and is quite helpful.
Costin Beiu
Nice one! I have a a problem with this re routing. Instead of my_site.com/index.php/admin/admin (css works), I set to my_site.com/admin but the css doesn’t work anymore. The css is in application/css/style.css. I tried ../application/css/style.css and /application/css/style.css, but still not working. Any advice?
web_and_development
Hello Costin,
You need to actually move your css outside the application folder. The application folder is a good practice to not be accessible from the web. This way you prevent hacking. Try to move the css folder outside the application folder and then try mysite.com/css/style.com
Anthony
Thanks, this is what i needed to remove the pesky default controller name!
Silencer
Hi, without my .htaccess file website already routes pages. However, since there is no folder with that name i get the error not found. In my config file index.php is deleted and im working on local. Note that I downloaded website from live server and it’s working properly there. When I delete inside of the .htaccess or .htaccess nothing is changed. Let’s say I’m trying to route that page “website_name”/about and I’m already routing but I get that not found error. However, when I change the link on browser like “website_name/index.php/about” it opens without problems. But when I click on “About” on website it goes to “website_name/about” and couldn’t found the page. Since live version is without index.php, I’m trying to opening it up but it seems whatever I do just doesn’t working. If you could help me that would be great. Thanks!
armstrong
hi thnks for ur guide with this redirect my images are not displaying which are in images folders
Sara Abdalaziz
how to route someting like this to get ride of function and .jpg
http://localhost/ci_alcwea/produacts/get_prodact/antic_Coil.jpg
Bloginfo Citstudio
Great Posts. Helped me a lot.
Have you article about multiple 404 Pages ?
I have 2 section, frontpage and admin page, if visitor type wrong URL, I want to redirect to 404 front’s page, and if I in administrator section, when I type wrong URL, it must redirect to 404 admin’s page.
can it handled by routing like these ?
Thanks
Waqas
Excellent write up, deserve a spicy biryani!
web_and_development
Thank you very much. However, I don’t like spicy foods 🙂
suraj waghmare
really helpful dear
Dilip
Perfect Example. Thanks
xubayerpantho
hellow bro i can’t remove my 1st url segment from my default controller. I am using CI version 2.1.4 Plz help, if you want i can send my code in your mail.
Nagu Yallu
i did same as above but its not working for me Please any body help me
HeartDisk
not working at my side
$route[‘default_controller’] = “welcome”;
$route[“about”] = ‘welcome/contactus’;
$route[“content/(.*)”] = ‘webpages/content/$1’;
$route[‘404_override’] = ”;
mohammed
check your controller function
bakoscsaba
thanks
kendra
I have a question. what is (gr&fr) AND (admin&forum) there? what is the function? looking forward to your response 🙂
Sanjay
Is this applicable only for one controller? I want to do this type route for all my rest controller. Suggest me the d way to do it for all other controller too. thanks in advance.
ip_man
thanks for the file, it’s really save my day
Sam KaNghoshi Naholo
Thank you.
amit
same page is opening if i add the unwanted text after Slash for example
In this Page http://www.example/kb/article/mac-data/
or in this Page http://www.example/kb/article/mac-data/72riwgffffg
in codeigniter
Sharma Aunj
same page is opening if i add the unwanted text after Slash for example
In this Page http://www.example/kb/article/mac-data/
or in this Page http://www.example/kb/article/mac-data/72riwgffffg
in codeigniter
Avinash
this code is note working
Alpheus Tech
Thank you for this awesome snippet. All worked until I decided to pass other segments.
Works: http://site.tld/_remap/uri_segment
Not working: http://site.tld/_remap/userid/1/email/user@site.tld
My route
$default_controller = “directory/controller/method”;
$controller_exceptions = array(‘test’, ‘test2’);
$route[‘directory/controller/method’] = $default_controller;
Max Joe
Nice Post , I will also refer following for removing index.php from codeigniter.
http://tutsway.com/remove-index.php-from-url-in-codeigniter.php
freddy
i’m trying to remove auth from url but those url still exist, i used this code, where is wrong
$default_controller = “auth”;
$controller_exceptions = array(‘admin’,’member’);
$route[‘default_controller’] = $default_controller;
$route[“^((?!b”.implode(‘b|b’, $controller_exceptions).”b).*)$”] = $default_controller.’/$1′;
$route[‘404_override’] = ”;
D.
Awesome! Just saved my life.
Haroon @WebSight
$default_controller = “admin”;
$controller_exceptions = array(‘auth’,’user’);
$route[‘default_controller’] = $default_controller;
$route[“^((?!b”.implode(‘b|b’, $controller_exceptions).”b).*)$”] = $default_controller.’/$1′;
$route[‘404_override’] = ”;
from admin controller which is default .i called a method but my view is not loading.
กีรติพร ลีลาวันทนพันธุ์
Thank You Very much
rahhul
I did the same as told, the index.php is removed from the url but the pages is not opening its showing object not found,
means the default controller is opening, but when i jumping to another controller its showing object not found
geat
thanks this turtorial its very great..
Mahesh Sharma
It was really helpful. Thank you.
hardik
what if i define base url and including index.php ?
Andi
Thanks it’s help me !