2

I am trying to replace a URL like

mysite.com/uploads:27 

into mysite.com/uploads/upload?upload=27

My original plan was to use a .htaccess file like this:

RewriteRule ^upload:(.+) /uploads/upload?upload=$1 [L]

However, I found that this is not the best idea since cake has several .htaccess files. At any rate the rule did not work.

So I went looking in Cake's routes. However, I can't seem to figure out how to route to a URL with a query string parameter.

I tried:

Router::connect('/upload::upload',
    array('controller' => 'uploads',
          'action' => 'upload',
    '?' => array('upload' => '23')
          )
    );

However, I do not think Router::connect is meant to work this way. No query string data was passed to the uploads controller. Given what I've read in the documentation, I did not expect this to work.

http://book.cakephp.org/2.0/en/development/routing.html "Routing is a feature that maps URLs to controller actions" - I'm guessing this means that query string params are not intended in this situation.

So is there any way I can get routes to act the way I was trying to use .htaccess? I'm surprised there isn't a way to do this, as shortening query strings with .htaccess is such a common task.

Like this tutorial shows: http://www.elated.com/articles/mod-rewrite-tutorial-for-absolute-beginners/ or the apcahe docs: http://httpd.apache.org/docs/2.0/misc/rewriteguide.html

NB: I am well aware that URL mapping I want (especially the upload:27 syntax with the colon) is against cake conventions. My app is not configured to take things like mysite.com/uploads/upload/27, as the docs suggest I should do. I would much rather figure out how to do this the way I imagined it in the firs place.

MrSynAckSter
  • 1,681
  • 1
  • 18
  • 34
  • Are you trying to map this internally only, ie the URL should actually not change, or would a redirect be fine too? – ndm Jun 27 '13 at 09:46
  • A redirect would be ok. I just want the user to be able to type the desired link in to get their model. – MrSynAckSter Jun 27 '13 at 14:00

1 Answers1

0

If a redirect is ok, then this should do it:

RewriteRule ^upload:(\d+)$ /uploads/upload?upload=$1 [R=302,L]

Use the .htaccess file located in app/webroot/ and you should be good. See this example:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} -d [OR]
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteRule .* - [S=2]
    RewriteRule ^upload:(\d+)$ /uploads/upload?upload=$1 [R=302,L]
    RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>

It's the original .htaccess file, modified to make the rewrite conditions (that check whether the requested target is an actually existing file or folder) apply for the last two rewrite rules. This works by skipping the last two rules ([S=2]) in case the conditions are true.

See also Multiple RewriteRules for single RewriteCond in .htaccess

Community
  • 1
  • 1
ndm
  • 59,784
  • 9
  • 71
  • 110