CodeIgniter Forums

Full Version: mod_rewrite changing URI segment order
You're currently viewing a stripped down version of our content. View the full version with proper formatting.

El Forum

[eluser]Resorath[/eluser]
Hi,

I am trying to make apache mod_rewrite move the third (first parameter of codeigniter) to the front of the URL. In my example case, I have the "variable name" as the first parameter of the URI, followed by the usual pattern of controller, method and additional parameters.

So in the case of:
http://www.example.com/myname/controller/method/1/2/

It would be rewritten to

http://www.example.com/controller/method/myname/1/2

My mod_rewrite rule seems to be doing the job, but codeigniter gives me a "404 Page Not Found" when trying to use the URL.

Here is my htaccess file (with most of the lines from the wiki omitted for clarity):

Code:
RewriteEngine On
    RewriteBase /mysite/

...

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^([^/]+)/([^/]+)/([^/]+)/?$         index.php?/$2/$3/$1    [L]  
    RewriteRule ^(.*)$ index.php?/$1 [L]

This appears to work correctly when I turn on mod_rewrite logging (lines trimmed for clarity):

(In this case, the url is http://localhost/firstweddingsite/home/runsite/, where ultimately, "firstweddingsite" is to become a parameter, "home" is a controller and "runsite" is a function that accepts the parameter "firstweddingsite")

Code:
[rid#5358118/initial] (3) [perdir E:/xampp/htdocs/unnamedweddingsite/] add path info postfix: E:/xampp/htdocs/unnamedweddingsite/firstweddingsite -> E:/xampp/htdocs/unnamedweddingsite/firstweddingsite/home/runsite/
[rid#5358118/initial] (3) [perdir E:/xampp/htdocs/unnamedweddingsite/] strip per-dir prefix: E:/xampp/htdocs/unnamedweddingsite/firstweddingsite/home/runsite/ -> firstweddingsite/home/runsite/
[rid#5358118/initial] (3) [perdir E:/xampp/htdocs/unnamedweddingsite/] applying pattern '^(.*)$' to uri 'firstweddingsite/home/runsite/'
[rid#5358118/initial] (3) [perdir E:/xampp/htdocs/unnamedweddingsite/] add path info postfix: E:/xampp/htdocs/unnamedweddingsite/firstweddingsite -> E:/xampp/htdocs/unnamedweddingsite/firstweddingsite/home/runsite/
[rid#5358118/initial] (3) [perdir E:/xampp/htdocs/unnamedweddingsite/] strip per-dir prefix: E:/xampp/htdocs/unnamedweddingsite/firstweddingsite/home/runsite/ -> firstweddingsite/home/runsite/
[rid#5358118/initial] (3) [perdir E:/xampp/htdocs/unnamedweddingsite/] applying pattern '^(.*)$' to uri 'firstweddingsite/home/runsite/'
[rid#5358118/initial] (3) [perdir E:/xampp/htdocs/unnamedweddingsite/] add path info postfix: E:/xampp/htdocs/unnamedweddingsite/firstweddingsite -> E:/xampp/htdocs/unnamedweddingsite/firstweddingsite/home/runsite/
[rid#5358118/initial] (3) [perdir E:/xampp/htdocs/unnamedweddingsite/] strip per-dir prefix: E:/xampp/htdocs/unnamedweddingsite/firstweddingsite/home/runsite/ -> firstweddingsite/home/runsite/
[rid#5358118/initial] (3) [perdir E:/xampp/htdocs/unnamedweddingsite/] applying pattern '^([^/]+)/([^/]+)/([^/]+)/?$' to uri 'firstweddingsite/home/runsite/'
[rid#5358118/initial] (2) [perdir E:/xampp/htdocs/unnamedweddingsite/] rewrite 'firstweddingsite/home/runsite/' -> 'index.php?/home/runsite/firstweddingsite'
[rid#5358118/initial] (3) split uri=index.php?/home/runsite/firstweddingsite -> uri=index.php, args=/home/runsite/firstweddingsite
[rid#5358118/initial] (3) [perdir E:/xampp/htdocs/unnamedweddingsite/] add per-dir prefix: index.php -> E:/xampp/htdocs/unnamedweddingsite/index.php
[rid#5358118/initial] (2) [perdir E:/xampp/htdocs/unnamedweddingsite/] trying to replace prefix E:/xampp/htdocs/unnamedweddingsite/ with /unnamedweddingsite/
[rid#5358118/initial] (1) [perdir E:/xampp/htdocs/unnamedweddingsite/] internal redirect with /unnamedweddingsite/index.php [INTERNAL REDIRECT]
[rid#536acb0/initial/redir#1] (3) [perdir E:/xampp/htdocs/unnamedweddingsite/] strip per-dir prefix: E:/xampp/htdocs/unnamedweddingsite/index.php -> index.php
[rid#536acb0/initial/redir#1] (3) [perdir E:/xampp/htdocs/unnamedweddingsite/] applying pattern '^(.*)$' to uri 'index.php'
[rid#536acb0/initial/redir#1] (3) [perdir E:/xampp/htdocs/unnamedweddingsite/] strip per-dir prefix: E:/xampp/htdocs/unnamedweddingsite/index.php -> index.php
[rid#536acb0/initial/redir#1] (3) [perdir E:/xampp/htdocs/unnamedweddingsite/] applying pattern '^(.*)$' to uri 'index.php'
[rid#536acb0/initial/redir#1] (3) [perdir E:/xampp/htdocs/unnamedweddingsite/] strip per-dir prefix: E:/xampp/htdocs/unnamedweddingsite/index.php -> index.php
[rid#536acb0/initial/redir#1] (3) [perdir E:/xampp/htdocs/unnamedweddingsite/] applying pattern '^([^/]+)/([^/]+)/([^/]+)/?$' to uri 'index.php'
[rid#536acb0/initial/redir#1] (3) [perdir E:/xampp/htdocs/unnamedweddingsite/] strip per-dir prefix: E:/xampp/htdocs/unnamedweddingsite/index.php -> index.php
[rid#536acb0/initial/redir#1] (3) [perdir E:/xampp/htdocs/unnamedweddingsite/] applying pattern '^(.*)$' to uri 'index.php'
[rid#536acb0/initial/redir#1] (2) [perdir E:/xampp/htdocs/unnamedweddingsite/] rewrite 'index.php' -> 'index.php?/index.php'
[rid#536acb0/initial/redir#1] (3) split uri=index.php?/index.php -> uri=index.php, args=/index.php
[rid#536acb0/initial/redir#1] (3) [perdir E:/xampp/htdocs/unnamedweddingsite/] add per-dir prefix: index.php -> E:/xampp/htdocs/unnamedweddingsite/index.php
[rid#536acb0/initial/redir#1] (1) [perdir E:/xampp/htdocs/unnamedweddingsite/] initial URL equal rewritten URL: E:/xampp/htdocs/unnamedweddingsite/index.php [IGNORING REWRITE]

It appears to be rewriting the URL (given by "rewrite 'firstweddingsite/home/runsite/' -> 'index.php?/home/runsite/firstweddingsite'")


codeigniter log just gives:

Code:
ERROR - 2012-07-04 07:11:16 --> 404 Page Not Found --> firstweddingsite

Is my rewrite working incorrectly, or is codeigniter not accepting the rewrite in the way that I expected?

Thanks!

El Forum

[eluser]Aken[/eluser]
What's the end goal here? Ideally, you shouldn't need to add additional .htaccess rules - CI's routes should take care of most things. You should explain the actual functionality behind it, and maybe we can suggest something better or help fix your solution if it's appropriate.

El Forum

[eluser]Resorath[/eluser]
[quote author="Aken" date="1341383782"]What's the end goal here? Ideally, you shouldn't need to add additional .htaccess rules - CI's routes should take care of most things. You should explain the actual functionality behind it, and maybe we can suggest something better or help fix your solution if it's appropriate.[/quote]

Hi Aken,

The end goal is an application that generates websites with an URL that appears more natural.

Each entry function inside of a controller will have the site name as the first parameter to act accordingly based on the site that was selected

Code:
public index($site)
{
   ...
}

for example, a gallery and a catalog controller for each site (with three user's different sites) would normally look like:

http://www.example.com/gallery/index/mysite/
http://www.example.com/gallery/index/someothersite/
http://www.example.com/gallery/index/athirdsite/

http://www.example.com/catalog/index/mysite/
http://www.example.com/catalog/index/someothersite/
http://www.example.com/catalog/index/athirdsite/

etc..

However, it makes more sense from a user standpoint (each user having their own website) to have the site name come first, as the "root" of the URL. So the URL would look like:

http://www.example.com/mysite/gallery/index
http://www.example.com/mysite/catalog/index

http://www.example.com/someothersite/gallery/index
http://www.example.com/someothersite/catalog/index

http://www.example.com/athirdsite/gallery/index
http://www.example.com/athirdsite/catalog/index

(and ideally, able to omit the "index" part of the URL)

I tried using routing, this was my solution (which does work):

Code:
$route['(:any)/gallery/(:any)'] = "gallery/$2/$1";
$route['(:any)/catalog/(:any)'] = "catalog/$2/$1";

However this has some issues.

First, each controller now needs to have an entry in the routes file. This removes any elegance from the design of the controllers.

Second, this may have adverse effects if additional parameters need to be passed to functions. This also may impede the ability to remove the "/index/" from the path for the default index function.

El Forum

[eluser]Aken[/eluser]
1) Set up a route that basically tells CodeIgniter to ignore the first segment, along with a route that makes sure if only the website name exists, it loads the homepage controller.

Code:
$route['[a-zA-Z0-9\-\.]+/(:any)'] = '$1'; // Add any potential characters that will be in the website segment.
$route['[a-zA-Z0-9\-\.]+'] = 'home'; // Whatever your site's index controller is.

2) Use a base controller (also known as MY_Controller) to get the first URI segment, and use that to figure out what website is viewed and do any appropriate logic. This allows you to use method parameters as normal. All your other controllers will then extend MY_Controller instead of CI_Controller.

Give that a shot and let us know if you run into any specific problems.

El Forum

[eluser]Resorath[/eluser]
Hi Aken,

Fantastic, this works exactly how I want it to.

Thanks for the elegant solution.

El Forum

[eluser]Aken[/eluser]
Sweet Smile